/// <summary> /// An event handler called when the site selection has changed. /// </summary> /// <param name="sender">The sender object.</param> /// <param name="e">The event arguments.</param> private void OnSiteSelectionChanged(object sender, EventArgs e) { // If there exists an emphasized marker, de-emphasize it. if (this.marker != null) { this.marker.Emphasized = false; this.marker = null; } // If there is a selected site. if (this.listViewSites.SelectedItems.Count > 0) { // Get the site-marker for this item. Pair<PlSite, MapMarker> tag = (Pair<PlSite, MapMarker>)this.listViewSites.SelectedItems[0].Tag; // If the marker is not null, emphasize the marker. if (tag.Second != null) { this.marker = tag.Second; this.marker.Emphasized = true; } } // Update the next button. this.wizardPageSite.NextEnabled = this.listViewSites.SelectedItems.Count > 0; // Reset the nodes controls. this.listViewNodes.Items.Clear(); this.textBoxFilterNode.Clear(); // Clear the lists. this.nodes.Clear(); this.selectedNodes.Clear(); }
/// <summary> /// Updates the list of PlanetLab sites. /// </summary> private void OnUpdateSites() { // Clear the list view. this.listViewSites.Items.Clear(); this.listViewNodes.Items.Clear(); // Clear the map markers. this.mapControl.Markers.Clear(); // Disable the button. this.wizardPageSite.NextEnabled = false; // Update the filter. this.filterSite = this.textBoxFilterSite.Text.Trim(); // Lock the list. this.sites.Lock(); try { // Update the sites list. foreach (PlSite site in this.sites) { // If the filter is not null or empty. if (!string.IsNullOrEmpty(this.filterSite)) { // If the site name does not match the filter, continue. if (!string.IsNullOrEmpty(site.Name)) { if (!site.Name.ToLower().Contains(this.filterSite.ToLower())) continue; } } // Create a new geo marker for this site. MapMarker marker = null; // If the site has coordinates. if (site.Latitude.HasValue && site.Longitude.HasValue) { // Create a circular marker. marker = new MapBulletMarker(new MapPoint(site.Longitude.Value, site.Latitude.Value)); marker.Name = site.Name; // Add the marker to the map. this.mapControl.Markers.Add(marker); } // Create the list view item. ListViewItem item = new ListViewItem(new string[] { site.SiteId.HasValue ? site.SiteId.Value.ToString() : string.Empty, site.Name, site.Url, site.DateCreated.ToString(), site.LastUpdated.ToString(), site.Latitude.HasValue ? site.Latitude.Value.LatitudeToString() : string.Empty, site.Longitude.HasValue ? site.Longitude.Value.LongitudeToString() : string.Empty }); item.Tag = new Pair<PlSite, MapMarker>(site, marker); item.ImageKey = "Site"; this.listViewSites.Items.Add(item); if (null != marker) { marker.Tag = item; } } } finally { this.sites.Unlock(); } // Update the status. this.wizardPageSite.Status = "Showing {0} of {1} PlanetLab sites.".FormatWith(this.listViewSites.Items.Count, this.sites.Count); }
/// <summary> /// Adds a site to the site list. /// </summary> /// <param name="site">The site.</param> private void OnAddSite(PlSite site) { // Create a new geo marker for this site. MapMarker marker = null; // If the site has coordinates. if (site.Latitude.HasValue && site.Longitude.HasValue) { // Create a circular marker. marker = new MapBulletMarker(new MapPoint(site.Longitude.Value, site.Latitude.Value)); marker.Name = site.Name; // Add the marker to the map. this.mapControl.Markers.Add(marker); } // Create the list view item. ListViewItem item = new ListViewItem(new string[] { site.SiteId.ToString(), site.Name, site.Url, site.NodeIds.Length.ToString(), site.DateCreated.ToString(), site.LastUpdated.ToString(), site.Latitude.HasValue ? site.Latitude.Value.LatitudeToString() : string.Empty, site.Longitude.HasValue ? site.Longitude.Value.LongitudeToString() : string.Empty }, 0); item.Tag = new Pair<PlSite, MapMarker>(site, marker); this.listViewSites.Items.Add(item); // Add the site event handler. site.Changed += this.OnSiteChanged; // Add the item to the marker. if (null != marker) { marker.Tag = item; } }
/// <summary> /// An event handler called when the site selection has changed. /// </summary> /// <param name="sender">The sender object.</param> /// <param name="e">The event arguments.</param> private void OnSelectionChanged(object sender, EventArgs e) { // If there exists an emphasized marker, de-emphasize it. if (this.marker != null) { this.marker.Emphasized = false; this.marker = null; } // If no site is selected. if (this.listViewSites.SelectedItems.Count == 0) { // Change the properties button enabled state. this.buttonProperties.Enabled = false; this.menuItemProperties.Enabled = false; } else { // Change the properties button enabled state. this.buttonProperties.Enabled = true; this.menuItemProperties.Enabled = true; // Get the site-marker for this item. Pair<PlSite, MapMarker> tag = (Pair<PlSite, MapMarker>)this.listViewSites.SelectedItems[0].Tag; // If the marker is not null, emphasize the marker. if (tag.Second != null) { this.marker = tag.Second; this.marker.Emphasized = true; } } }
/// <summary> /// Creates a new node info instance for the specified node. /// </summary> /// <param name="nodeId">The node identifier.</param> /// <param name="siteId">The site identifier.</param> /// <param name="node">The PlanetLab node.</param> /// <param name="site">The PlanetLab site.</param> /// <param name="marker">The map marker.</param> public NodeInfo(int nodeId, int? siteId, PlNode node, PlSite site, MapMarker marker) { this.NodeId = nodeId; this.SiteId = siteId; this.Node = node; this.Site = site; this.Marker = marker; }
/// <summary> /// Creates a new event arguments instance. /// </summary> /// <param name="marker">The marker.</param> public MapMarkerChangedEventArgs(MapMarker marker) { this.Marker = marker; }
/// <summary> /// A method called when receiving the response to a sites refresh request. /// </summary> /// <param name="response">The response.</param> /// <param name="state">The request state.</param> private void OnRefreshSitesRequestResult(XmlRpcResponse response, RequestState state) { // Convert the request state. IdsRequestState requestState = state as IdsRequestState; // If the request has not failed. if ((null == response.Fault) && (null != response.Value)) { // Get the response array. XmlRpcArray array = response.Value as XmlRpcArray; // Check the array is not null. if (null == array) { // Update the status. this.status.Send( ApplicationStatus.StatusType.Normal, @"Slice '{0}' has {1} node{2}.".FormatWith(this.slice.Name, this.slice.NodeIds.Length, this.slice.NodeIds.Length.PluralSuffix()), "Refreshing the sites information failed.", Resources.GlobeLab_16, Resources.GlobeError_16); // Log this.controlLogList.Add(this.config.Log.Add( LogEventLevel.Important, LogEventType.Error, ControlSlice.logSource.FormatWith(this.slice.Id), "Refreshing the sites information failed. The received response was empty.")); // Return. return; } // For each value in the response array. foreach (XmlRpcValue value in array.Values) { // The PlanetLab site. PlSite site = null; // Try parse the structure to a PlanetLab node and add it to the sites list. try { site = this.crawler.PlanetLab.Sites.Add(value.Value as XmlRpcStruct); } catch { } // If the object is null, continue. if (null == site) continue; // Find the list items corresponding to the site. foreach (ListViewItem item in this.listViewNodes.Items.Where((ListViewItem it) => { // Get the node info. NodeInfo info = it.Tag as NodeInfo; // Check the site ID. return info.SiteId == site.Id; })) { // Get the node info. NodeInfo info = item.Tag as NodeInfo; // If the site has not been set. if (info.Site == null) { // Add a node event handler. site.Changed += this.OnSiteChanged; // Set the site. info.Site = site; // If the item does not have a marker and if the site has coordinates. if ((null == info.Marker) && (null != info.Node) && site.Latitude.HasValue && site.Longitude.HasValue) { // Create a circular marker. marker = new MapBulletMarker(new MapPoint(site.Longitude.Value, site.Latitude.Value)); marker.Name = "{0}{1}{2}".FormatWith(info.Node.Hostname, Environment.NewLine, site.Name); // Add the marker to the map. this.mapControl.Markers.Add(marker); // Set the marker. info.Marker = marker; } } } } // Update the status. this.status.Send( ApplicationStatus.StatusType.Normal, @"Slice '{0}' has {1} node{2}.".FormatWith(this.slice.Name, this.slice.NodeIds.Length, this.slice.NodeIds.Length.PluralSuffix()), "Refreshing the sites information completed successfully.", Resources.GlobeLab_16, Resources.GlobeSuccess_16); // Log this.controlLogList.Add(this.config.Log.Add( LogEventLevel.Verbose, LogEventType.Success, ControlSlice.logSource.FormatWith(this.slice.Id), "Refreshing the sites information completed successfully.")); } else { // Update the status. this.status.Send( ApplicationStatus.StatusType.Normal, @"Slice '{0}' has {1} node{2}.".FormatWith(this.slice.Name, this.slice.NodeIds.Length, this.slice.NodeIds.Length.PluralSuffix()), "Refreshing the sites information failed.", Resources.GlobeLab_16, Resources.GlobeError_16); if (null == response.Fault) { // Log this.controlLogList.Add(this.config.Log.Add( LogEventLevel.Important, LogEventType.Error, ControlSlice.logSource.FormatWith(this.slice.Id), "Refreshing the sites information failed.")); } else { // Log this.controlLogList.Add(this.config.Log.Add( LogEventLevel.Important, LogEventType.Error, ControlSlice.logSource.FormatWith(this.slice.Id), "Refreshing the sites information failed with code {0} ({1}).", new object[] { response.Fault.FaultCode, response.Fault.FaultString })); } } }
/// <summary> /// Updates the list of slice nodes. /// </summary> private void OnUpdateNodes() { // Clear the current nodes. this.OnClearNodes(); // Synchronize access to the pending lists. lock (this.pendingSync) { // Clear the list of pending nodes. this.pendingNodes.Clear(); this.pendingSites.Clear(); // Add the list of nodes. foreach (int nodeId in this.slice.NodeIds) { // The node. PlNode node = this.crawler.PlanetLab.DbNodes.Find(nodeId); // The site identifier. int? siteId = null; // The site. PlSite site = null; // If the node is not null. if (null != node) { // Get the site identifier. siteId = node.SiteId; // Add a node event handler. node.Changed += this.OnNodeChanged; // If the node has a site identifier. if (node.SiteId.HasValue) { // Get the site from the database. site = this.crawler.PlanetLab.DbSites.Find(node.SiteId.Value); // If the site is not null. if (null != site) { // Add a site event handler. site.Changed += this.OnSiteChanged; } else { // Add the site to the pending sites. this.pendingSites.Add(node.SiteId.Value); } } } else { // Add the node ID to the pending list. this.pendingNodes.Add(nodeId); } // Create a new geo marker for this site. MapMarker marker = null; if (null != site) { // If the site has coordinates. if (site.Latitude.HasValue && site.Longitude.HasValue) { // Create a circular marker. marker = new MapBulletMarker(new MapPoint(site.Longitude.Value, site.Latitude.Value)); marker.Name = "{0}{1}{2}".FormatWith(node.Hostname, Environment.NewLine, site.Name); // Add the marker to the map. this.mapControl.Markers.Add(marker); } } // Create the node information. NodeInfo info = new NodeInfo(nodeId, siteId, node, site, marker); // Create a list item. ListViewItem item = new ListViewItem(new string[] { nodeId.ToString(), node != null ? node.Hostname : string.Empty, ControlSsh.ClientState.Disconnected.ToString() }); item.ImageKey = node != null ? ControlSlice.nodeImageKeys[(int)node.GetBootState()] : ControlSlice.nodeImageKeys[0]; item.Tag = info; // Add the list item. this.listViewNodes.Items.Add(item); // If the marker is not null, set the marker tag. if (null != marker) { marker.Tag = item; } } // Refresh the pending nodes and sites. if (this.pendingNodes.Count > 0) { this.OnRefreshNodes(); } else if (this.pendingSites.Count > 0) { this.OnRefreshSites(); } } }
/// <summary> /// An event handler called when the mouse leaves the control. /// </summary> /// <param name="e">The event arguments.</param> protected override void OnMouseLeave(EventArgs e) { // Call the base class methods. base.OnMouseLeave(e); // Clear the mouse over flag. this.mouseOverFlag = false; // If there exists a highlighted marker. if (null != this.highlightMarker) { // Invalidate the bounds of that region. this.Invalidate(this.highlightMarker.Bounds.Add(this.bitmapLocation)); // Set the highlighted marker to null. this.highlightMarker = null; } // If there exists a highlighted region. if (null != this.highlightRegion) { // Invalidate the bounds of that region. this.Invalidate(this.highlightRegion.Bounds.Add(this.bitmapLocation)); // Set the highlighted region to null. this.highlightRegion = null; } // If there exists an emphasized marker. if ((null != this.emphasizedMarker) && this.showMarkers) { // Show the info annotation. this.OnShowAnnotation(this.annotationInfo, this.emphasizedMarker.Name, this.emphasizedMarker); } else { // Hide the info annotation. this.OnHideAnnotation(this.annotationInfo); } }
/// <summary> /// An event handler called when the site selection has changed. /// </summary> /// <param name="sender">The sender object.</param> /// <param name="e">The event arguments.</param> private void OnNodeSelectionChanged(object sender, EventArgs e) { // If there exists an emphasized marker, de-emphasize it. if (this.marker != null) { this.marker.Emphasized = false; this.marker = null; } // If no site is selected. if (this.listViewNodes.SelectedItems.Count == 0) { // Change the buttons enabled state. this.buttonRemoveFromNodes.Enabled = false; this.buttonConnect.Enabled = false; this.buttonDisconnect.Enabled = false; this.buttonProperties.Enabled = false; this.menuItemConnect.Enabled = false; this.menuItemDisconnect.Enabled = false; this.menuItemNodeProperties.Enabled = false; this.menuItemSiteProperties.Enabled = false; } else { // Get the node info for this item. NodeInfo info = this.listViewNodes.SelectedItems[0].Tag as NodeInfo; // If the node has a control. if (null != info.ConsoleControl) { // Change the button enabled state. this.buttonConnect.Enabled = info.ConsoleControl.State == ControlSsh.ClientState.Disconnected; this.buttonDisconnect.Enabled = info.ConsoleControl.State == ControlSsh.ClientState.Connected; this.menuItemConnect.Enabled = info.ConsoleControl.State == ControlSsh.ClientState.Disconnected; this.menuItemDisconnect.Enabled = info.ConsoleControl.State == ControlSsh.ClientState.Connected; } else { // Change the button enabled state. this.buttonConnect.Enabled = true; this.buttonDisconnect.Enabled = false; this.menuItemConnect.Enabled = true; this.menuItemDisconnect.Enabled = false; } this.buttonRemoveFromNodes.Enabled = true; this.buttonProperties.Enabled = true; this.buttonNodeProperties.Enabled = true; this.buttonSiteProperties.Enabled = info.Node != null; this.menuItemNodeProperties.Enabled = true; this.menuItemSiteProperties.Enabled = info.Node != null; // If the marker is not null, emphasize the marker. if (null != info.Marker) { this.marker = info.Marker; this.marker.Emphasized = true; } } }
/// <summary> /// Removes the event handlers for the specified marker. /// </summary> /// <param name="marker">The marker.</param> private void OnRemoveMarkerEventHandlers(MapMarker marker) { marker.ColorChanged -= this.OnMarkerColorChanged; marker.EmphasisChanged -= this.OnMarkerEmphasisChanged; marker.LocationChanged -= this.OnMarkerLocationChanged; marker.SizeChanged -= this.OnMarkerSizeChanged; }
/// <summary> /// An event handler called when starting executing the mouse move lazy code. /// </summary> /// <param name="e">The event arguments.</param> private void OnMouseMoveLazyStart(MouseEventArgs e) { // Compute the mouse location. Point location = e.Location.Subtract(this.bitmapLocation); // Execute the lazy code on the thread pool. ThreadPool.QueueUserWorkItem((object state) => { // If the object has been disposed, do nothing. if (this.IsDisposed) return; // Try lock the mouse move mutex. if (Monitor.TryEnter(this.syncMouseMove)) { try { // The current highlighted marker. MapMarker highlightMarker = null; // The current highlighted region. MapRegion highlightRegion = null; // Get an exclusive lock to the markers collection. this.markers.Lock(); try { // Compute the new highlight marker. foreach (MapMarker marker in this.markers) { // If the marker contains the mouse location. if (marker.IsVisible(location)) { // Set the current highlighted marker. highlightMarker = marker; // Stop the iteration. break; } } } finally { this.markers.Unlock(); } // Get an exclusive reader lock to the regions list. this.regions.Lock(); try { // Compute the new highlight region. foreach (MapRegion region in this.regions) { // If the region contains the mouse location. if (region.IsVisible(location)) { // Set the current highlighted region. highlightRegion = region; // Stop the iteration. break; } } } finally { this.regions.Unlock(); } // Call the mouse move lazy finish. this.OnMouseMoveLazyFinish(highlightMarker, highlightRegion); } finally { Monitor.Exit(this.syncMouseMove); } } }); }
/// <summary> /// An event handler called when finishing executing the mouse move lazy code. /// </summary> /// <param name="highlightMarker">The highlighted marker.</param> /// <param name="highlightRegion">The highlighted code.</param> private void OnMouseMoveLazyFinish(MapMarker highlightMarker, MapRegion highlightRegion) { // Execute the code on the UI thread. this.Invoke(() => { // If the mouse over flag is not set, do nothing. if (!this.mouseOverFlag) return; // If the highlighted marker has changed. if (this.highlightMarker != highlightMarker) { // If there exists a previous highlighted marker. if (null != this.highlightMarker) { // Invalidate the bounds of that marker. this.Invalidate(this.highlightMarker.Bounds.Add(this.bitmapLocation)); } // If there exists a current highlighted marker. if ((null != highlightMarker) && this.showMarkers) { // Invalidate the bounds of that marker. this.Invalidate(highlightMarker.Bounds.Add(this.bitmapLocation)); // Show the info annotation. this.OnShowAnnotation(this.annotationInfo, highlightMarker.Name, highlightMarker); } else { // If there is an emphasized marker. if ((null != this.emphasizedMarker) && this.showMarkers) { // Show the info annotation. this.OnShowAnnotation(this.annotationInfo, this.emphasizedMarker.Name, this.emphasizedMarker); } // Else, if there is a highlighted region. else if (null != highlightRegion) { // Show the info annotation. this.OnShowAnnotation(this.annotationInfo, highlightRegion.Name, highlightRegion); } // Else. else { // Hide the info annotation. this.OnHideAnnotation(this.annotationInfo); } } // Set the new highlighted marker. this.highlightMarker = highlightMarker; } // If the highlighted region has changed. if (this.highlightRegion != highlightRegion) { // If there exists a previous highlighted region. if (null != this.highlightRegion) { // Invalidate the bounds of that region. this.Invalidate(this.highlightRegion.Bounds.Add(this.bitmapLocation)); } // If there exists a current highlighted region. if (null != highlightRegion) { // Invalidate the bounds of that region. this.Invalidate(highlightRegion.Bounds.Add(this.bitmapLocation)); // If there is no highlighted marker and no emphasized marker or if the markers are hidden. if (((null == this.highlightMarker) && (null == this.emphasizedMarker)) || !this.showMarkers) { // Show the info annotation. this.OnShowAnnotation(this.annotationInfo, highlightRegion.Name, highlightRegion); } } else { // If there is no highlighted marker and no emphasized marker. if (((null == this.highlightMarker) && (null == this.emphasizedMarker)) || !this.showMarkers) { // Hide the info annotation. this.OnHideAnnotation(this.annotationInfo); } } // Set the new highlighted region. this.highlightRegion = highlightRegion; } }); }
/// <summary> /// An event handler called when a marker emphasis has changed. /// </summary> /// <param name="sender">The sender object.</param> /// <param name="e">The event arguments.</param> private void OnMarkerEmphasisChanged(object sender, MapMarkerChangedEventArgs e) { // If the marker is emphasized. if (e.Marker.Emphasized) { // If the markers are shown. if (this.showMarkers) { // Show the info annotation. this.OnShowAnnotation(this.annotationInfo, e.Marker.Name, e.Marker); } // Set the emphasized marker. this.emphasizedMarker = e.Marker; } else { // If there is a highlighted marker. if ((null != this.highlightMarker) && this.showMarkers) { // Show the info annotation. this.OnShowAnnotation(this.annotationInfo, this.highlightMarker.Name, this.highlightMarker); } // If there is a highlighted region. else if (null != this.highlightRegion) { // Show the info annotation. this.OnShowAnnotation(this.annotationInfo, this.highlightRegion.Name, this.highlightRegion); } else { // Hide the info annotation. this.OnHideAnnotation(this.annotationInfo); } // Set the emphasized marker. this.emphasizedMarker = null; } // Refresh the marker. this.Invalidate(e.Marker.Bounds.Add(this.bitmapLocation)); }
/// <summary> /// An event handler called before the markers are cleared. /// </summary> /// <param name="sender">The sender object.</param> /// <param name="e">The event arguments.</param> private void OnBeforeMarkersCleared(object sender, EventArgs e) { // Lock the markers collection. this.markers.Lock(); try { // For all the markers. foreach (MapMarker marker in this.markers) { // Refresh the marker. this.Invalidate(marker.Bounds.Add(this.bitmapLocation)); // Remove the event handlers all markers in the markers collection. this.OnRemoveMarkerEventHandlers(marker); // Dispose the marker. if (this.markerAutoDispose) { marker.Dispose(); } } } finally { this.markers.Unlock(); } // If any of the highlighted or emphasized markers are not null. if ((null != this.highlightRegion) || (null != this.emphasizedMarker)) { // Set the highlighted marker to null. this.highlightMarker = null; // Set the emphasized marker to null. this.emphasizedMarker = null; // If there exists a highlighted region. if (null != this.highlightRegion) { // Update the annotation. this.OnShowAnnotation(this.annotationInfo, this.highlightRegion.Name, this.highlightRegion); } else { // Hide the annotation. this.OnHideAnnotation(this.annotationInfo); } } }