diff --git a/CHANGELOG.md b/CHANGELOG.md index d0e052bce..1db86491b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,3 +21,4 @@ Lib: Fix issue with failed tile downloads Lib: Use two decimal precision for average speed Android: Fix sensor scanning state handling for internal and Ble sensors. Android: Fix handling of unpaired power meters +GTK: Add support for Nominatim reverse diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt index f55e404bb..33a61ff3e 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt @@ -33,6 +33,7 @@ object Strings { const val ACTION_LOCATION_COPY = "locationCopy" const val ACTION_LOCATION_PASTE = "locationPaste" const val ACTION_LOCATION_REVERSE = "locationReverse" + const val ACTION_LOCATION_REVERSE_CENTER = "locationReverseCenter" const val ACTION_LOCATION_CM = "locationCM" // Custom widgets diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/menu/provider/LocationMenu.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/menu/provider/LocationMenu.kt index 0e6d4cecc..3c3cd22c7 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/menu/provider/LocationMenu.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/menu/provider/LocationMenu.kt @@ -1,29 +1,61 @@ package ch.bailu.aat_gtk.view.menu.provider +import ch.bailu.aat_gtk.app.GtkAppContext import ch.bailu.aat_gtk.config.Strings import ch.bailu.aat_gtk.controller.ClipboardController import ch.bailu.aat_gtk.controller.UiControllerInterface import ch.bailu.aat_gtk.view.map.GtkCustomMapView import ch.bailu.aat_gtk.view.menu.MenuHelper +import ch.bailu.aat_lib.api.cm.CmApi +import ch.bailu.aat_lib.api.nominatim.NominatimReverseApi +import ch.bailu.aat_lib.app.AppContext +import ch.bailu.aat_lib.dispatcher.DispatcherInterface +import ch.bailu.aat_lib.gpx.GpxPointNode +import ch.bailu.aat_lib.gpx.attributes.GpxAttributes +import ch.bailu.aat_lib.gpx.attributes.Keys +import ch.bailu.aat_lib.gpx.information.GpxInformation +import ch.bailu.aat_lib.gpx.information.InfoID import ch.bailu.aat_lib.logger.AppLog import ch.bailu.aat_lib.preferences.StorageInterface import ch.bailu.aat_lib.preferences.map.SolidMapGrid +import ch.bailu.aat_lib.preferences.map.overlay.SolidNominatimReverseOverlay +import ch.bailu.aat_lib.preferences.system.SolidDataDirectory import ch.bailu.aat_lib.resources.Res import ch.bailu.aat_lib.resources.ToDo import ch.bailu.gtk.gdk.Display import ch.bailu.gtk.gio.Menu import ch.bailu.gtk.gtk.Application import ch.bailu.gtk.type.Str +import org.mapsforge.map.view.MapView +import kotlin.text.ifEmpty class LocationMenu : MenuProviderInterface { override fun createMenu(): Menu { return Menu().apply { append(Res.str().clipboard_copy(), MenuHelper.toAppAction(Strings.ACTION_LOCATION_COPY)) - append(Res.str().clipboard_paste(), MenuHelper.toAppAction(Strings.ACTION_LOCATION_PASTE)) - appendSection(Str.NULL, Menu().apply { - append(ToDo.translate("About location"), MenuHelper.toAppAction(Strings.ACTION_LOCATION_REVERSE)) - append(ToDo.translate("CM locations"), MenuHelper.toAppAction(Strings.ACTION_LOCATION_CM)) + append( + Res.str().clipboard_paste(), + MenuHelper.toAppAction(Strings.ACTION_LOCATION_PASTE) + ) + appendSection(ToDo.translate("Reverse Nominatim"), Menu().apply { + append( + ToDo.translate("Query"), + MenuHelper.toAppAction(Strings.ACTION_LOCATION_REVERSE) + ) + append( + ToDo.translate("Center"), + MenuHelper.toAppAction(Strings.ACTION_LOCATION_REVERSE_CENTER) + ) }) + + if (CmApi.ENABLED) { + appendSection(Str.NULL, Menu().apply { + append( + ToDo.translate("CM locations"), + MenuHelper.toAppAction(Strings.ACTION_LOCATION_CM) + ) + }) + } } } @@ -38,9 +70,31 @@ class LocationMenu : MenuProviderInterface { override fun updateActionValues(app: Application) {} companion object { - fun createActions(storageInterface: StorageInterface, app: Application, display: Display, uiController: UiControllerInterface) { - val clipboard = ClipboardController(display) + /** + * Independent closure for handling menu actions + */ + fun createActions( + app: Application, + appContext: AppContext, + display: Display, + mapView: MapView, + dispatcher: DispatcherInterface, + uiController: UiControllerInterface + ) { + + createActionsClipboard(app, appContext.storage, display, uiController) + createActionsNominatimReverse(app, appContext, mapView, uiController, dispatcher) + createActionsCm(app, appContext.dataDirectory) + + } + private fun createActionsClipboard( + app: Application, + storage: StorageInterface, + display: Display, + uiController: UiControllerInterface + ) { + val clipboard = ClipboardController(display) MenuHelper.setAction(app, Strings.ACTION_LOCATION_PASTE) { clipboard.getLatLong { AppLog.i(this, it.toString()) @@ -49,19 +103,69 @@ class LocationMenu : MenuProviderInterface { } MenuHelper.setAction(app, Strings.ACTION_LOCATION_COPY) { - val sgrid = SolidMapGrid(storageInterface, GtkCustomMapView.DEFAULT_KEY) - val text = sgrid.getCode(uiController.getMapBounding().center.toLatLong()).toString() + val sgrid = SolidMapGrid(storage, GtkCustomMapView.DEFAULT_KEY) + val text = + sgrid.getCode(uiController.getMapBounding().center.toLatLong()).toString() AppLog.i(this, text) - clipboard.setText(sgrid.getCode(uiController.getMapBounding().center.toLatLong()).toString()) + clipboard.setText( + sgrid.getCode(uiController.getMapBounding().center.toLatLong()).toString() + ) + } + } + + private fun createActionsCm(app: Application, dataDirectory: SolidDataDirectory) { + val cmApi = CmApi(dataDirectory) + MenuHelper.setAction(app, Strings.ACTION_LOCATION_CM) { + cmApi.startTask(GtkAppContext) } + } + + private fun createActionsNominatimReverse( + app: Application, + appContext: AppContext, + mapView: MapView, + uiController: UiControllerInterface, + dispatcher: DispatcherInterface + ) { + val soverlay = SolidNominatimReverseOverlay(appContext.dataDirectory) + val reverseApi = NominatimReverseApi(soverlay) + var isUpdated = false + MenuHelper.setAction(app, Strings.ACTION_LOCATION_REVERSE) { - AppLog.d(this,uiController.getMapBounding().center.toLatLong().toString() + " -> query/nominatim-reverse.json") + if (!reverseApi.isTaskRunning(GtkAppContext.services)) { + reverseApi.startTask( + GtkAppContext, + uiController.getMapBounding().center, + mapView.model.mapViewPosition.zoomLevel.toInt() + ) + soverlay.setEnabled(true) + isUpdated = true + } } - MenuHelper.setAction(app, Strings.ACTION_LOCATION_CM) { - AppLog.d(this, "https://api-gw.criticalmaps.net/locations -> query/cm.json") + MenuHelper.setAction(app, Strings.ACTION_LOCATION_REVERSE_CENTER) { + uiController.centerInMap(soverlay.getIID()) + } + + + dispatcher.addTarget({ iid: Int, info: GpxInformation -> + if (isUpdated) { + val firstNode = info.getGpxList().pointList.first + if (firstNode is GpxPointNode) { + AppLog.i(this, getMessage(firstNode.getAttributes())) + } + isUpdated = false + } + }, InfoID.NOMINATIM_REVERSE) + } + + private fun getMessage(attributes: GpxAttributes): String { + return attributes[Keys.toIndex("name")].ifEmpty { + attributes[Keys.toIndex("city")].ifEmpty { + attributes[Keys.toIndex("label")] + } } } } diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/MainWindow.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/MainWindow.kt index e4c3f3ae8..1b912605b 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/MainWindow.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/MainWindow.kt @@ -12,7 +12,6 @@ import ch.bailu.aat_gtk.util.GtkTimer import ch.bailu.aat_gtk.view.dialog.FileChangedDialog import ch.bailu.aat_gtk.view.dialog.PreferencesDialog import ch.bailu.aat_gtk.view.map.GtkCustomMapView -import ch.bailu.aat_gtk.view.menu.provider.LocationMenu import ch.bailu.aat_gtk.view.messages.MessageOverlay import ch.bailu.aat_gtk.view.search.PoiPage import ch.bailu.aat_gtk.view.toplevel.navigation.NavigationView @@ -33,8 +32,8 @@ import ch.bailu.aat_lib.dispatcher.usage.UsageTrackers import ch.bailu.aat_lib.gpx.information.GpxInformation import ch.bailu.aat_lib.gpx.information.InfoID import ch.bailu.aat_lib.gpx.information.InformationUtil -import ch.bailu.aat_lib.preferences.map.overlay.SolidOverlayFileEnabled import ch.bailu.aat_lib.preferences.map.SolidPositionLock +import ch.bailu.aat_lib.preferences.map.overlay.SolidOverlayFileEnabled import ch.bailu.aat_lib.resources.Res import ch.bailu.foc.Foc import ch.bailu.gtk.adw.Application @@ -116,8 +115,6 @@ class MainWindow(private val app: Application, private val appContext: AppContex window.onDestroy { exit(dispatcher, 0) } - - LocationMenu.createActions(appContext.storage, app, window.display, this) } private fun clearEditor(onCleared: ()->Unit) { @@ -255,6 +252,8 @@ class MainWindow(private val app: Application, private val appContext: AppContex dispatcher.addOverlaySources(appContext, usageTrackers) dispatcher.addSource(FixedOverlaySource.createDraftSource(appContext, usageTrackers)) dispatcher.addSource(FixedOverlaySource.createPoiSource(appContext, usageTrackers)) + dispatcher.addSource(FixedOverlaySource.createCmSource(appContext, usageTrackers)) + dispatcher.addSource(FixedOverlaySource.createNominatimReverseSource(appContext, usageTrackers)) dispatcher.addSource(editorSource) dispatcher.addTarget(metaInfoCollector, InfoID.ALL) } diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/MapMainView.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/MapMainView.kt index 7afd143d7..0590eeab0 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/MapMainView.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/MapMainView.kt @@ -12,6 +12,7 @@ import ch.bailu.aat_gtk.view.map.control.InfoBar import ch.bailu.aat_gtk.view.map.control.MainBar import ch.bailu.aat_gtk.view.map.control.NavigationBar import ch.bailu.aat_gtk.view.map.control.NodeInfo +import ch.bailu.aat_gtk.view.menu.provider.LocationMenu import ch.bailu.aat_gtk.view.toplevel.navigation.NavigationView import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.dispatcher.DispatcherInterface @@ -147,6 +148,8 @@ class MapMainView( overlay.addOverlay(statusLabel.box) showMainBar() + + LocationMenu.createActions(app, appContext, window.display, map, dispatcher, uiController) } private fun addBar(bar: Bar) { diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/api/Api.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/api/Api.kt index 5d244a2d7..ee2c33012 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/api/Api.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/api/Api.kt @@ -5,6 +5,10 @@ import ch.bailu.aat_lib.service.ServicesInterface import ch.bailu.aat_lib.service.background.FileTask import ch.bailu.foc.Foc +/** + * Abstract base class for all APIs + * startTask uses individual implementations + */ abstract class Api(private val overlay: SolidOverlayInterface) { val apiName: String get() = overlay.getLabel() diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/api/cm/CmApi.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/api/cm/CmApi.kt index b1fbc8609..2325d5de7 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/api/cm/CmApi.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/api/cm/CmApi.kt @@ -16,4 +16,7 @@ class CmApi(baseDirectory: SolidDataDirectory) : Api(SolidCriticalMapOverlay(bas background.process(task) } } + companion object { + const val ENABLED = false // TODO handle as experimental feature and enable via env variable + } } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/source/FixedOverlaySource.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/source/FixedOverlaySource.kt index 650c3894d..647d895a9 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/source/FixedOverlaySource.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/source/FixedOverlaySource.kt @@ -2,12 +2,15 @@ package ch.bailu.aat_lib.dispatcher.source import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.dispatcher.usage.UsageTrackerInterface -import ch.bailu.aat_lib.gpx.information.InfoID import ch.bailu.aat_lib.preferences.StorageInterface -import ch.bailu.aat_lib.util.fs.AppDirectory +import ch.bailu.aat_lib.preferences.map.overlay.SolidCriticalMapOverlay +import ch.bailu.aat_lib.preferences.map.overlay.SolidDraftOverlay +import ch.bailu.aat_lib.preferences.map.overlay.SolidFixedOverlay +import ch.bailu.aat_lib.preferences.map.overlay.SolidNominatimReverseOverlay +import ch.bailu.aat_lib.preferences.map.overlay.SolidPoiOverlay -class FixedOverlaySource(context: AppContext, usageTracker: UsageTrackerInterface, private val directory: String, private val file: String, iid: Int): - FileSource(context, iid, usageTracker) { +class FixedOverlaySource(context: AppContext, usageTracker: UsageTrackerInterface, private val overlay: SolidFixedOverlay): + FileSource(context, overlay.getIID(), usageTracker) { private val dataDirectory = context.dataDirectory @@ -18,7 +21,7 @@ class FixedOverlaySource(context: AppContext, usageTracker: UsageTrackerInterfac } private fun onPreferencesChanged() { - setFile(dataDirectory.getValueAsFile().descendant(directory).child(file)) + setFile(overlay.getValueAsFile()) } override fun onResumeWithService() { @@ -34,11 +37,23 @@ class FixedOverlaySource(context: AppContext, usageTracker: UsageTrackerInterfac companion object { fun createPoiSource(context: AppContext, usageTracker: UsageTrackerInterface): FileSource { - return FixedOverlaySource(context, usageTracker, AppDirectory.DIR_POI, AppDirectory.FILE_POI, InfoID.POI) + val overlay = SolidPoiOverlay(context.dataDirectory) + return FixedOverlaySource(context, usageTracker, overlay) } fun createDraftSource(context: AppContext, usageTracker: UsageTrackerInterface): FileSource { - return FixedOverlaySource(context, usageTracker, AppDirectory.DIR_EDIT, AppDirectory.FILE_DRAFT, InfoID.EDITOR_DRAFT) + val overlay = SolidDraftOverlay(context.dataDirectory) + return FixedOverlaySource(context, usageTracker, overlay) + } + + fun createNominatimReverseSource(context: AppContext, usageTracker: UsageTrackerInterface): FileSource { + val overlay = SolidNominatimReverseOverlay(context.dataDirectory) + return FixedOverlaySource(context, usageTracker, overlay) + } + + fun createCmSource(context: AppContext, usageTracker: UsageTrackerInterface): FileSource { + val overlay = SolidCriticalMapOverlay(context.dataDirectory) + return FixedOverlaySource(context, usageTracker, overlay) } } } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/gpx/information/InformationUtil.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/gpx/information/InformationUtil.kt index 084e56810..c04234c95 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/gpx/information/InformationUtil.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/gpx/information/InformationUtil.kt @@ -1,5 +1,6 @@ package ch.bailu.aat_lib.gpx.information +import ch.bailu.aat_lib.api.cm.CmApi import ch.bailu.aat_lib.preferences.map.overlay.SolidCustomOverlayList import ch.bailu.aat_lib.resources.Res import ch.bailu.aat_lib.resources.ToDo @@ -7,7 +8,6 @@ import ch.bailu.aat_lib.resources.ToDo object InformationUtil { fun defaultName(iid: Int): String { - // TODO: use enum for this when(iid) { InfoID.POI -> return Res.str().p_mapsforge_poi() InfoID.EDITOR_DRAFT -> return ToDo.translate("Draft") @@ -45,6 +45,10 @@ object InformationUtil { add(InfoID.EDITOR_OVERLAY) add(InfoID.TRACKER) add(InfoID.LIST_SUMMARY) + add(InfoID.NOMINATIM_REVERSE) + if (CmApi.ENABLED) { + add(InfoID.CRITICAL_MAP) + } } } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/preferences/map/overlay/SolidBrouterOverlay.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/preferences/map/overlay/SolidBrouterOverlay.kt index 852844213..1687ffedb 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/preferences/map/overlay/SolidBrouterOverlay.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/preferences/map/overlay/SolidBrouterOverlay.kt @@ -8,4 +8,4 @@ class SolidBrouterOverlay(baseDirectory: SolidDataDirectory) : SolidFixedOverlay(baseDirectory, InfoID.BROUTER, AppDirectory.DIR_QUERY, - AppDirectory.FILE_BROUTER) \ No newline at end of file + AppDirectory.FILE_BROUTER) diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/preferences/map/overlay/SolidDraftOverlay.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/preferences/map/overlay/SolidDraftOverlay.kt new file mode 100644 index 000000000..4d1ac2a22 --- /dev/null +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/preferences/map/overlay/SolidDraftOverlay.kt @@ -0,0 +1,11 @@ +package ch.bailu.aat_lib.preferences.map.overlay + +import ch.bailu.aat_lib.gpx.information.InfoID +import ch.bailu.aat_lib.preferences.system.SolidDataDirectory +import ch.bailu.aat_lib.util.fs.AppDirectory + +class SolidDraftOverlay(baseDirectory: SolidDataDirectory) : + SolidFixedOverlay(baseDirectory, + InfoID.EDITOR_DRAFT, + AppDirectory.DIR_EDIT, + AppDirectory.FILE_DRAFT) diff --git a/doc/uml/dispatcher.uxf b/doc/uml/dispatcher.uxf index cac29565a..800d46278 100644 --- a/doc/uml/dispatcher.uxf +++ b/doc/uml/dispatcher.uxf @@ -1,13 +1,13 @@ - 10 + 8 UMLClass - 480 - 280 - 380 - 100 + 440 + 312 + 304 + 80 <<interface>> SourceInterface @@ -20,10 +20,10 @@ SourceInterface UMLClass - 480 - 640 - 380 - 120 + 440 + 600 + 304 + 96 <<interface>> DispatcherInterface @@ -35,10 +35,10 @@ DispatcherInterface UMLClass - 490 - 1180 - 370 - 80 + 448 + 1032 + 296 + 64 <<interface>> TargetInterface @@ -49,10 +49,10 @@ TargetInterface UMLClass - 1090 - 650 - 130 - 30 + 928 + 608 + 104 + 24 Dispatcher @@ -61,10 +61,10 @@ TargetInterface Relation - 850 - 650 - 260 - 30 + 736 + 608 + 208 + 24 lt=<<- 10.0;10.0;240.0;10.0 @@ -72,10 +72,10 @@ TargetInterface UMLClass - 1070 - 1210 - 100 - 30 + 912 + 1056 + 80 + 24 MapOverlay @@ -83,10 +83,10 @@ TargetInterface Relation - 850 - 1210 - 240 - 30 + 736 + 1056 + 192 + 24 lt=<<- 10.0;10.0;220.0;10.0 @@ -94,10 +94,10 @@ TargetInterface Relation - 680 - 750 - 30 - 450 + 600 + 688 + 24 + 360 lt=<<- 10.0;430.0;10.0;10.0 @@ -105,10 +105,10 @@ TargetInterface Relation - 810 - 860 - 70 - 340 + 704 + 776 + 56 + 272 lt=<<- 10.0;320.0;10.0;10.0;50.0;10.0 @@ -116,10 +116,10 @@ TargetInterface UMLClass - 1100 - 340 - 120 - 30 + 936 + 360 + 96 + 24 FileSource @@ -128,10 +128,10 @@ TargetInterface UMLClass - 1360 - 580 - 280 - 110 + 1144 + 552 + 224 + 88 <<interface>> UsageTrackerInterface @@ -143,10 +143,10 @@ UsageTrackerInterface Relation - 1010 - 680 - 420 - 280 + 864 + 632 + 336 + 224 lt=<. 400.0;10.0;400.0;260.0;10.0;260.0 @@ -154,10 +154,10 @@ UsageTrackerInterface Relation - 850 - 340 - 270 - 30 + 736 + 360 + 216 + 24 lt=<<- 10.0;10.0;250.0;10.0 @@ -165,10 +165,10 @@ UsageTrackerInterface UMLClass - 480 - 450 - 380 - 110 + 440 + 448 + 304 + 88 <<interface>> EmiterInterface @@ -180,10 +180,10 @@ EmiterInterface Relation - 680 - 370 - 30 - 100 + 600 + 384 + 24 + 80 lt=<<- 10.0;80.0;10.0;10.0 @@ -191,10 +191,10 @@ EmiterInterface Relation - 680 - 550 - 30 - 110 + 600 + 528 + 24 + 88 lt=<<- 10.0;10.0;10.0;90.0 @@ -202,10 +202,10 @@ EmiterInterface Relation - 310 - 320 - 200 - 930 + 304 + 344 + 160 + 744 lt=<. 180.0;910.0;10.0;910.0;10.0;10.0;170.0;10.0 @@ -213,10 +213,10 @@ EmiterInterface Relation - 640 - 750 - 30 - 450 + 568 + 688 + 24 + 360 lt=<. 10.0;430.0;10.0;10.0 @@ -224,10 +224,10 @@ EmiterInterface UMLClass - 1840 - 880 - 270 - 140 + 1528 + 792 + 216 + 112 OverlayController - @@ -241,10 +241,10 @@ EmiterInterface UMLClass - 1870 - 690 - 250 - 130 + 1552 + 640 + 200 + 104 DetailController - @@ -256,10 +256,10 @@ EmiterInterface UMLClass - 880 - 820 - 100 - 80 + 760 + 744 + 80 + 64 ToggleFilter - @@ -268,10 +268,10 @@ EmiterInterface UMLClass - 1100 - 150 - 130 - 30 + 936 + 208 + 104 + 24 /SolidOverlayFile/ @@ -280,10 +280,10 @@ EmiterInterface Relation - 1150 - 170 - 30 - 80 + 976 + 224 + 24 + 64 lt=<. 10.0;10.0;10.0;60.0 @@ -291,10 +291,10 @@ EmiterInterface UMLClass - 1100 - 400 - 120 - 90 + 936 + 408 + 96 + 72 EditorSource - @@ -304,10 +304,10 @@ EmiterInterface UMLClass - 530 - 80 - 150 - 30 + 480 + 152 + 120 + 24 TrackerTimerSource @@ -315,10 +315,10 @@ EmiterInterface Relation - 820 - 370 - 300 - 60 + 712 + 384 + 240 + 48 lt=<<- 10.0;10.0;10.0;40.0;280.0;40.0 @@ -326,10 +326,10 @@ EmiterInterface UMLClass - 1100 - 550 - 180 - 70 + 936 + 528 + 144 + 56 EditorSourceController - @@ -340,10 +340,10 @@ EmiterInterface Relation - 1140 - 480 - 30 - 90 + 968 + 472 + 24 + 72 lt=<. 10.0;10.0;10.0;70.0 @@ -351,10 +351,10 @@ EmiterInterface UMLClass - 500 - 60 - 350 - 150 + 456 + 136 + 280 + 120 @@ -362,10 +362,10 @@ EmiterInterface Relation - 670 - 200 - 30 - 100 + 592 + 248 + 24 + 80 lt=<<- 10.0;80.0;10.0;10.0 @@ -373,10 +373,10 @@ EmiterInterface UMLClass - 530 - 120 - 150 - 30 + 480 + 184 + 120 + 24 TrackerSource @@ -384,10 +384,10 @@ EmiterInterface UMLClass - 530 - 160 - 180 - 30 + 480 + 216 + 144 + 24 CurrentLocationSource @@ -395,10 +395,10 @@ EmiterInterface UMLClass - 690 - 120 - 150 - 30 + 608 + 184 + 120 + 24 SensorSource @@ -406,10 +406,10 @@ EmiterInterface UMLClass - 690 - 80 - 150 - 30 + 608 + 152 + 120 + 24 IteratorSource @@ -417,10 +417,10 @@ EmiterInterface UMLClass - 1240 - 230 - 130 - 30 + 1048 + 272 + 104 + 24 FileViewSource @@ -428,10 +428,10 @@ EmiterInterface Relation - 1150 - 250 - 30 - 110 + 976 + 288 + 24 + 88 lt=<<- 10.0;90.0;10.0;10.0 @@ -439,10 +439,10 @@ EmiterInterface UMLClass - 1100 - 230 - 130 - 30 + 936 + 272 + 104 + 24 OverlaySource @@ -450,10 +450,10 @@ EmiterInterface Relation - 1190 - 250 - 130 - 110 + 1008 + 288 + 104 + 88 lt=<<- 10.0;90.0;10.0;60.0;110.0;60.0;110.0;10.0 @@ -461,10 +461,10 @@ EmiterInterface UMLClass - 0 - 460 - 240 - 110 + 56 + 456 + 192 + 88 <<interface>> LifeCylceInterface @@ -478,10 +478,10 @@ LifeCylceInterface Relation - 230 - 500 - 270 - 30 + 240 + 488 + 216 + 24 lt=<<- 10.0;10.0;250.0;10.0 @@ -489,10 +489,10 @@ LifeCylceInterface Relation - 830 - 970 - 50 - 230 + 720 + 864 + 40 + 184 lt=<. 10.0;210.0;10.0;10.0;30.0;10.0 @@ -500,10 +500,10 @@ LifeCylceInterface Relation - 1210 - 350 - 220 - 250 + 1024 + 368 + 176 + 200 lt=<. 200.0;230.0;200.0;10.0;10.0;10.0 @@ -511,10 +511,10 @@ LifeCylceInterface Relation - 1460 - 680 - 30 - 320 + 1224 + 632 + 24 + 256 lt=<<- 10.0;10.0;10.0;300.0 @@ -522,10 +522,10 @@ LifeCylceInterface Relation - 1610 - 680 - 30 - 320 + 1344 + 632 + 24 + 256 lt=<<- 10.0;10.0;10.0;300.0 @@ -533,10 +533,10 @@ LifeCylceInterface UMLClass - 1330 - 980 - 190 - 60 + 1120 + 872 + 152 + 48 OverlayUsageTracker @@ -545,10 +545,10 @@ LifeCylceInterface UMLClass - 1540 - 980 - 190 - 60 + 1288 + 872 + 152 + 48 SelectableUsageTracker - @@ -558,10 +558,10 @@ LifeCylceInterface UMLClass - 1330 - 1090 - 190 - 30 + 1120 + 960 + 152 + 24 /SolidOverlayFileEnabled/ @@ -570,10 +570,10 @@ LifeCylceInterface Relation - 1460 - 1030 - 30 - 80 + 1224 + 912 + 24 + 64 lt=<. 10.0;60.0;10.0;10.0 @@ -581,10 +581,10 @@ LifeCylceInterface Relation - 1570 - 400 - 30 - 200 + 1312 + 408 + 24 + 160 lt=<<- 10.0;180.0;10.0;10.0 @@ -592,10 +592,10 @@ LifeCylceInterface UMLClass - 1510 - 360 - 190 - 50 + 1264 + 376 + 152 + 40 UsageTrackers @@ -604,10 +604,10 @@ LifeCylceInterface Relation - 1550 - 680 - 30 - 140 + 1296 + 632 + 24 + 112 lt=<<- 10.0;10.0;10.0;120.0 @@ -615,10 +615,10 @@ LifeCylceInterface UMLClass - 1480 - 800 - 130 - 60 + 1240 + 728 + 104 + 48 UsageTracker @@ -627,10 +627,10 @@ LifeCylceInterface Relation - 1550 - 850 - 30 - 150 + 1296 + 768 + 24 + 120 lt=<. 10.0;10.0;10.0;130.0 @@ -638,10 +638,10 @@ LifeCylceInterface Relation - 1600 - 400 - 30 - 200 + 1336 + 408 + 24 + 160 lt=<<<<<- 10.0;10.0;10.0;180.0 @@ -649,10 +649,10 @@ LifeCylceInterface UMLClass - 880 - 920 - 100 - 80 + 760 + 824 + 80 + 64 SelectFilter - @@ -661,10 +661,10 @@ LifeCylceInterface UMLClass - 860 - 800 - 160 - 210 + 744 + 728 + 128 + 168 @@ -672,10 +672,10 @@ LifeCylceInterface UMLClass - 920 - 230 - 160 - 30 + 792 + 272 + 128 + 24 FixedOverlaySource @@ -683,10 +683,10 @@ LifeCylceInterface Relation - 990 - 250 - 150 - 110 + 848 + 288 + 120 + 88 lt=<<- 130.0;90.0;130.0;60.0;10.0;60.0;10.0;10.0