ArcObjects Library Reference  

DigitTool

About the Implementing a schematic digitizing tool Sample

[C#]

DigitTool.cs

using System;

using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Schematic;
using ESRI.ArcGIS.SchematicControls;
using ESRI.ArcGIS.esriSystem;
using System.Windows.Forms;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Display;

namespace CurrentDigitTool
{
	internal static class CurrentTool
	{
		public static DigitTool.DigitTool currentDigit;
		public static ESRI.ArcGIS.Framework.IDockableWindow currentDockableWindow;
		public static DigitTool.DigitDockableWindow digitDockableWindow;
	}
}


namespace DigitTool
{
	public class DigitTool : ESRI.ArcGIS.Desktop.AddIns.Tool
	{
		ESRI.ArcGIS.Framework.IApplication m_app;
		ESRI.ArcGIS.esriSystem.IExtension m_schematicExtension;
		ISchematicLayer m_schematicLayer;
		ISchematicLayer m_schematicLayerForLink;
		ISchematicFeature m_schematicFeature1;
		ISchematicFeature m_schematicFeature2;
		INewLineFeedback m_linkFbk;
		private string m_messageFromOK = "\n" + "Complete missing data and click on button ok";

		private int m_x;
		private int m_y;

		public DigitDockableWindow m_dockableDigit;
		private ESRI.ArcGIS.Framework.IDockableWindow m_dockableWindow;
		private bool m_fromDeactivate = false;

		public DigitTool()
		{
			m_app = ArcMap.Application;
		}

		protected override void OnUpdate()
		{
			// the tool is enable only if the diagram is in memory
			try
			{
				if (ArcMap.Application == null)
				{
					Enabled = false;
					return;
				}

				SetTargetLayer();

				if (m_schematicLayer == null)
				{
					Enabled = false;
					return;
				}

				if (m_schematicLayer.IsEditingSchematicDiagram() == false)
				{
					Enabled = false;
					return;
				}

				ISchematicInMemoryDiagram inMemoryDiagram = m_schematicLayer.SchematicInMemoryDiagram;

				if (inMemoryDiagram == null)
					Enabled = false;
				else
					Enabled = true;
			}
			catch (System.Exception e)
			{
				System.Windows.Forms.MessageBox.Show(e.Message);
			}
			return;
		}

		protected override void OnMouseMove(ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs arg)
		{
			try
			{
				if (m_schematicFeature1 != null)
				{
					ESRI.ArcGIS.ArcMapUI.IMxApplication mxApp = (ESRI.ArcGIS.ArcMapUI.IMxApplication)m_app;

					if (mxApp == null)
						return;

					ESRI.ArcGIS.Display.IAppDisplay appDisplay = mxApp.Display;

					if (appDisplay == null)
						return;

					IScreenDisplay screenDisplay = appDisplay.FocusScreen;

					if (screenDisplay == null)
						return;

					//Move the Feedback to the current mouse location
					IPoint pnt = screenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y);

					if (pnt != null && m_linkFbk != null)
						m_linkFbk.MoveTo(pnt);
				}
			}	
			catch (System.Exception e)
			{
				System.Windows.Forms.MessageBox.Show(e.Message);
			}
			return;
		}

		protected override void OnMouseUp(ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs arg)
		{
			bool abortOperation = false;
			ESRI.ArcGIS.Schematic.ISchematicOperation schematicOperation = null;

			try
			{
				if (m_dockableDigit == null)
					return;

				if (arg != null)
				{
					m_x = arg.X;
					m_y = arg.Y;
				}

				if (m_dockableWindow == null)
					return;

				if (m_dockableWindow.IsVisible() == false)
				{
					m_dockableWindow.Show(true);
				}

				ESRI.ArcGIS.SchematicControls.ISchematicTarget target = (ESRI.ArcGIS.SchematicControls.ISchematicTarget)m_schematicExtension;

				if (target != null)
					m_schematicLayer = target.SchematicTarget;

				if (m_schematicLayer == null)
				{
					System.Windows.Forms.MessageBox.Show("No target Layer");
					return;
				}

				ISchematicInMemoryDiagram inMemoryDiagram;
				ISchematicInMemoryFeatureClass schematicInMemoryFeatureClass;
				ISchematicInMemoryFeatureClassContainer schematicInMemoryFeatureClassContainer;

				//Get the point
				ESRI.ArcGIS.Geometry.Point point = new ESRI.ArcGIS.Geometry.Point();

				ESRI.ArcGIS.ArcMapUI.IMxApplication mxApp;
				ESRI.ArcGIS.Display.IAppDisplay appDisplay;
				IScreenDisplay screenDisplay;
				IDisplay display;
				IDisplayTransformation transform;
				ISpatialReference spatialReference;

				inMemoryDiagram = m_schematicLayer.SchematicInMemoryDiagram;
				schematicInMemoryFeatureClassContainer = (ISchematicInMemoryFeatureClassContainer)inMemoryDiagram;

				if (schematicInMemoryFeatureClassContainer == null)
					return;

				mxApp = (ESRI.ArcGIS.ArcMapUI.IMxApplication)m_app;

				if (mxApp == null)
					return;

				appDisplay = mxApp.Display;

				if (appDisplay == null)
					return;

				screenDisplay = appDisplay.FocusScreen;
				display = screenDisplay;

				if (display == null)
					return;

				transform = display.DisplayTransformation;

				if (transform == null)
					return;

				spatialReference = transform.SpatialReference;

				WKSPoint mapPt = new WKSPoint();
				ESRI.ArcGIS.Display.tagPOINT devPoint;
				devPoint.x = m_x;
				devPoint.y = m_y;
				transform.TransformCoords(ref mapPt, ref devPoint, 1, 1); //'esriTransformToMap

				point.SpatialReference = spatialReference;
				point.Project(spatialReference);
				point.X = mapPt.X;
				point.Y = mapPt.Y;

				schematicInMemoryFeatureClass = schematicInMemoryFeatureClassContainer.GetSchematicInMemoryFeatureClass(m_dockableDigit.FeatureClass());

				if (schematicInMemoryFeatureClass == null)
				{
					System.Windows.Forms.MessageBox.Show("Invalid Type.");
					return;
				}

				if (m_dockableDigit.CreateNode())
				{
					//TestMandatoryField
					m_dockableDigit.btnOKPanel1.Visible = false;

					if (m_dockableDigit.ValidateFields() == false)
					{
						m_dockableDigit.x(m_x);
						m_dockableDigit.y(m_y);

						System.Windows.Forms.MessageBox.Show(m_dockableDigit.ErrorProvider1.GetError(m_dockableDigit.btnOKPanel1) + m_messageFromOK);
						return;
					}

					ESRI.ArcGIS.Geometry.IGeometry geometry;

					ISchematicInMemoryFeature schematicInMemoryFeatureNode;

					geometry = point;

					schematicOperation = (ESRI.ArcGIS.Schematic.ISchematicOperation) new ESRI.ArcGIS.SchematicControls.SchematicOperation();

					//digit operation is undo(redo)able we add it in the stack
					IMxDocument doc  = (IMxDocument)m_app.Document;
					ESRI.ArcGIS.SystemUI.IOperationStack operationStack; 
					operationStack = doc.OperationStack;
					operationStack.Do(schematicOperation);
					schematicOperation.StartOperation("Digit", m_app, m_schematicLayer, true);

					//do abort operation
					abortOperation = true;

					schematicInMemoryFeatureNode = schematicInMemoryFeatureClass.CreateSchematicInMemoryFeatureNode(geometry, "");
					//schematicInMemoryFeatureNode.UpdateStatus = esriSchematicUpdateStatus.esriSchematicUpdateStatusNew; if we want the node deleted after update
					schematicInMemoryFeatureNode.UpdateStatus = esriSchematicUpdateStatus.esriSchematicUpdateStatusLocked;

					abortOperation = false;
					schematicOperation.StopOperation();

					ISchematicFeature schematicFeature = schematicInMemoryFeatureNode;
					m_dockableDigit.FillValue(ref schematicFeature);

					if (m_dockableDigit.AutoClear())
						m_dockableDigit.SelectionChanged();
				}
				else
				{
					m_dockableDigit.btnOKPanel2.Visible = false;

					//Get the Tolerance of ArcMap
					Double tolerance;
					IMxDocument mxDocument = (ESRI.ArcGIS.ArcMapUI.IMxDocument)m_app.Document;
					ESRI.ArcGIS.esriSystem.WKSPoint point2 = new WKSPoint();
					ESRI.ArcGIS.Display.tagPOINT devPt;

					tolerance = mxDocument.SearchTolerancePixels;
					devPt.x = (int)tolerance;
					devPt.y = (int)tolerance;

					transform.TransformCoords(ref point2, ref devPt, 1, 2);//2 <-> esriTransformSize 4 <-> esriTransformToMap

					tolerance = point2.X * 5;//increase the tolerance value

					IEnumSchematicFeature schematicFeatures = m_schematicLayer.GetSchematicFeaturesAtPoint(point, tolerance, false, true);

					ISchematicFeature schematicFeatureSelected = null;
					double distancetmp;
					double distance = 0;
					schematicFeatures.Reset();

					if (schematicFeatures.Count <= 0)
						return;

					//pSchematicFeatures may contain several features, we are choosing the closest node.
					ISchematicFeature schematicFeature2 = schematicFeatures.Next();

					double dX;
					double dY;
					ISchematicInMemoryFeatureNode schematicInMemoryFeatureNode =  null;
					if (schematicFeature2 != null)
					{
						if (schematicFeature2.SchematicElementClass.SchematicElementType == ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeType)
							schematicInMemoryFeatureNode = (ISchematicInMemoryFeatureNode)schematicFeature2;
					}
										
					ISchematicInMemoryFeatureNodeGeometry schematicInMemoryFeatureNodeGeometry = (ISchematicInMemoryFeatureNodeGeometry)schematicInMemoryFeatureNode;
					dX = schematicInMemoryFeatureNodeGeometry.Position.X;
					dY = schematicInMemoryFeatureNodeGeometry.Position.Y;
					schematicFeatureSelected = schematicFeature2;
					distance = SquareDistance(dX - point.X, dY - point.Y);

					while (schematicFeature2 != null)
					{
						//find the closest featureNode...
						if (schematicInMemoryFeatureNode != null)
						{
							schematicInMemoryFeatureNodeGeometry = (ISchematicInMemoryFeatureNodeGeometry) schematicInMemoryFeatureNode;

							if (schematicInMemoryFeatureNodeGeometry == null)
								continue;

							dX = schematicInMemoryFeatureNodeGeometry.Position.X;
							dY = schematicInMemoryFeatureNodeGeometry.Position.Y;
							distancetmp = SquareDistance(dX - point.X, dY - point.Y);
							
							if (distancetmp < distance)
							{
								distance = distancetmp;
								schematicFeatureSelected = schematicFeature2;
							}
						}

						schematicFeature2 = schematicFeatures.Next();
						
						if (schematicFeature2 != null)
						{
							if (schematicFeature2.SchematicElementClass.SchematicElementType == ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeType)
								schematicInMemoryFeatureNode = (ISchematicInMemoryFeatureNode)schematicFeature2;
						}
					}
					
					if (schematicFeatureSelected == null)
						return;

					if (schematicFeatureSelected.SchematicElementClass.SchematicElementType != esriSchematicElementType.esriSchematicNodeType)
						return;

					if (m_schematicFeature1 == null)
					{
						m_schematicFeature1 = schematicFeatureSelected;
						m_dockableDigit.SchematicFeature1(m_schematicFeature1);

						if (!m_dockableDigit.CheckValidFeature(true))
						{
							m_schematicFeature1 = null;
							m_dockableDigit.SchematicFeature1(m_schematicFeature1);
							throw new Exception("Invalid starting node for this link type");
						}

						//Begin Feedback 
						m_linkFbk = new NewLineFeedback();
						m_linkFbk.Display = screenDisplay;

						//symbol
						ISimpleLineSymbol sLnSym;
						IRgbColor rGB = new RgbColor();

						sLnSym = (ESRI.ArcGIS.Display.ISimpleLineSymbol)m_linkFbk.Symbol;

						//Make a color
						rGB.Red = 255;
						rGB.Green = 0;
						rGB.Blue = 0;

						// Setup the symbol with color and style
						sLnSym.Color = rGB;

						m_linkFbk.Start(point);
						//End Feedback

						//To know if we are in the same diagram.
						m_schematicLayerForLink = m_schematicLayer;
					}
					else
					{
						if (m_schematicLayerForLink != m_schematicLayer)
						{
							System.Windows.Forms.MessageBox.Show("wrong Target layer");
							m_schematicLayerForLink = null;
							EndFeedBack();
							return;
						}
						m_schematicFeature2 = schematicFeatureSelected;
						m_dockableDigit.SchematicFeature2(m_schematicFeature2);

						//TestMandatoryField
						if (m_dockableDigit.ValidateFields() == false)
						{
							m_dockableDigit.x(m_x);
							m_dockableDigit.y(m_y);

							System.Windows.Forms.MessageBox.Show(m_dockableDigit.ErrorProvider1.GetError(m_dockableDigit.btnOKPanel2) + m_messageFromOK);
							return;
						}

						if (!m_dockableDigit.CheckValidFeature(false))
						{
							m_schematicFeature2 = null;
							m_dockableDigit.SchematicFeature2(m_schematicFeature2);
							throw new Exception("Invalid End node for this link type");
						}

						//CreateLink
						ISchematicInMemoryFeature schematicInMemoryFeatureLink;

						schematicOperation = (ESRI.ArcGIS.Schematic.ISchematicOperation) new ESRI.ArcGIS.SchematicControls.SchematicOperation();

						//digit operation is undo(redo)able we add it in the stack
						IMxDocument doc  = (IMxDocument)m_app.Document;
						ESRI.ArcGIS.SystemUI.IOperationStack operationStack; 
						operationStack = doc.OperationStack;
						operationStack.Do(schematicOperation);
						schematicOperation.StartOperation("Digit", m_app, m_schematicLayer, true);

						//do abort operation
						abortOperation = true;

						schematicInMemoryFeatureLink = schematicInMemoryFeatureClass.CreateSchematicInMemoryFeatureLink((ESRI.ArcGIS.Schematic.ISchematicInMemoryFeatureNode)m_schematicFeature1, (ESRI.ArcGIS.Schematic.ISchematicInMemoryFeatureNode)m_schematicFeature2, "");
						//schematicInMemoryFeatureLink.UpdateStatus = esriSchematicUpdateStatus.esriSchematicUpdateStatusNew; if we want the node deleted after update
						schematicInMemoryFeatureLink.UpdateStatus = esriSchematicUpdateStatus.esriSchematicUpdateStatusLocked;

						abortOperation = false;
						schematicOperation.StopOperation();

						ISchematicFeature schematicFeature = schematicInMemoryFeatureLink;
						m_dockableDigit.FillValue(ref schematicFeature);

						//End Feedback
						EndFeedBack();

						m_schematicLayerForLink = null;

						if (m_dockableDigit.AutoClear())
							m_dockableDigit.SelectionChanged();

					}
				}

				//Refresh the view and viewer windows
				RefreshView();
			}
			catch (System.Exception e)
			{
				if (abortOperation && (schematicOperation != null))
					schematicOperation.AbortOperation();

				EndFeedBack();
				System.Windows.Forms.MessageBox.Show(e.Message);
			}

			return;
		}

		protected override bool OnDeactivate()
		{
			try
			{
				CurrentDigitTool.CurrentTool.currentDigit = null;

				if (m_dockableWindow != null)
				{
					m_fromDeactivate = true;
					m_dockableWindow.Dock(ESRI.ArcGIS.Framework.esriDockFlags.esriDockUnPinned);
					m_dockableWindow.Show(false);
				}
			}
			catch (System.Exception e)
			{
				System.Windows.Forms.MessageBox.Show(e.Message);
			}

			return true;
		}

		protected override void OnActivate()
		{
			try
			{
				this.Cursor = Cursors.Cross;

				CurrentDigitTool.CurrentTool.currentDigit = this;

				SetTargetLayer();

				ESRI.ArcGIS.Framework.IDockableWindowManager dockWinMgr = ArcMap.DockableWindowManager;
				UID u = new UID();
				u.Value = "DigitTool_DockableWindowCS";

				if (dockWinMgr == null)
					return;

				m_dockableWindow = dockWinMgr.GetDockableWindow(u);

				if (m_dockableDigit == null)
					m_dockableDigit = CurrentDigitTool.CurrentTool.digitDockableWindow;

				if (m_dockableDigit != null)
					m_dockableDigit.Init(m_schematicLayer);

				m_dockableWindow.Show(true);

				CurrentDigitTool.CurrentTool.currentDockableWindow = m_dockableWindow;
			}
			catch (System.Exception e)
			{
				System.Windows.Forms.MessageBox.Show(e.Message);
			}
		}

		private void RefreshView()
		{
			IMxDocument mxDocument2 = (IMxDocument)m_app.Document;

			if (mxDocument2 == null)
				return;

			IMap map = mxDocument2.FocusMap;
			IActiveView activeView = (IActiveView)map;

			if (activeView != null)
				activeView.Refresh();

			//refresh viewer window
			IApplicationWindows applicationWindows = m_app as IApplicationWindows;

			ISet mySet = applicationWindows.DataWindows;
			if (mySet != null)
			{
				mySet.Reset();
				IMapInsetWindow dataWindow = (IMapInsetWindow)mySet.Next();
				while (dataWindow != null)
				{
					dataWindow.Refresh();
					dataWindow = (IMapInsetWindow)mySet.Next();
				}
			}
		}

		public void EndFeedBack()
		{
			m_schematicFeature1 = null;
			m_schematicFeature2 = null;
			
			if (m_dockableDigit != null)
			{
				m_dockableDigit.SchematicFeature1(m_schematicFeature1);
				m_dockableDigit.SchematicFeature2(m_schematicFeature2);
			}

			if (m_linkFbk != null)
			{
				m_linkFbk.Stop();
				m_linkFbk = null;
			}
		}

		public void SchematicFeature1(ISchematicFeature value)
		{
			m_schematicFeature1 = value;
			return;
		}

		public void SchematicFeature2(ISchematicFeature value)
		{
			m_schematicFeature2 = value;
			return;
		}

		public void FromDeactivate(bool value)
		{
			m_fromDeactivate = value;
		}

		public bool FromDeactivate()
		{
			return m_fromDeactivate;
		}

		public void MyMouseUp(int x, int y)
		{
			m_x = x;
			m_y = y;

			m_messageFromOK = "";
			OnMouseUp(null);
			m_messageFromOK = "\n" + "Complete missing data and click on button ok";
		}

		private double SquareDistance(double dx, double dy)
		{
			return (dx * dx + dy * dy);
		}


		private void SetTargetLayer()
		{
			try
			{
				if (m_schematicLayer == null)
				{
					IExtension extention = null;
					IExtensionManager extensionManager;

					extensionManager = (IExtensionManager)m_app;
					extention = extensionManager.FindExtension("SchematicUI.SchematicExtension");
					
					if (extention == null)
						Enabled = false;
					else
					{
						m_schematicExtension = extention;
						ISchematicTarget target = m_schematicExtension as ISchematicTarget;
						if (target != null)
							m_schematicLayer = target.SchematicTarget;
					}
				}
			}
			catch (System.Exception e)
			{
				System.Windows.Forms.MessageBox.Show(e.Message);
			}
		}
	}

}

[Visual Basic .NET]

DigitTool.vb

Option Strict Off
Option Explicit On

Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Schematic
Imports ESRI.ArcGIS.SchematicControls
Imports ESRI.ArcGIS.esriSystem
Imports System.Windows.Forms
Imports ESRI.ArcGIS.ArcMapUI
Imports ESRI.ArcGIS.Display

Namespace CurrentDigitTool
	Friend Module CurrentTool
		Public currentDigit As DigitTool
		Public currentDockableWindow As ESRI.ArcGIS.Framework.IDockableWindow
		Public digitDockableWindow As DigitDockableWindow
	End Module
End Namespace

Public Class DigitTool
	Inherits ESRI.ArcGIS.Desktop.AddIns.Tool

	Private m_app As ESRI.ArcGIS.Framework.IApplication
	Public m_dockableDigit As DigitDockableWindow
	Private m_schematicExtension As ESRI.ArcGIS.esriSystem.IExtension
	Private m_schematicLayer As ISchematicLayer
	Private m_schematicLayerForLink As ISchematicLayer
	Private m_schematicFeature1 As ISchematicFeature
	Private m_schematicFeature2 As ISchematicFeature
	Private m_linkFbk As INewLineFeedback
	Private m_messageFromOK As String = vbCrLf & "Complete missing data and click on button ok"

	Private m_x As Integer
	Private m_y As Integer

	Private m_dockableWindow As ESRI.ArcGIS.Framework.IDockableWindow
	Private m_fromDeactivate = False


	Public Sub New()
		m_app = My.ArcMap.Application
	End Sub

	Protected Overrides Sub OnUpdate()
		'the tool is enable only if the diagram is in memory
		SetTargetLayer()

		If (m_schematicLayer Is Nothing) Then
			Enabled = False
			Return
		End If

		If (m_schematicLayer.IsEditingSchematicDiagram() = False) Then
			Enabled = False
			Return
		End If

		Dim inMemoryDiagram As ISchematicInMemoryDiagram = m_schematicLayer.SchematicInMemoryDiagram

		If (inMemoryDiagram Is Nothing) Then
			Enabled = False
		Else
			Enabled = True
		End If
	End Sub

	Protected Overrides Function OnDeactivate() As Boolean
		CurrentDigitTool.CurrentTool.currentDigit = Nothing

		If Not m_dockableWindow Is Nothing Then
			m_fromDeactivate = True
			m_dockableWindow.Dock(ESRI.ArcGIS.Framework.esriDockFlags.esriDockUnPinned)
			m_dockableWindow.Show(False)
		End If

		Return True

	End Function

	Protected Overrides Sub OnActivate()
		Me.Cursor = Cursors.Cross

		CurrentDigitTool.CurrentTool.currentDigit = Me

		SetTargetLayer()

		Dim windowID As UID = New UIDClass
		windowID.Value = "DigitTool_DockableWindowVB"
		m_dockableWindow = My.ArcMap.DockableWindowManager.GetDockableWindow(windowID)

		If (m_dockableDigit Is Nothing) Then
			m_dockableDigit = CurrentDigitTool.digitDockableWindow
		End If

		If m_dockableDigit IsNot Nothing Then
			m_dockableDigit.Init(m_schematicLayer)
		End If

		m_dockableWindow.Show(True)

		CurrentDigitTool.CurrentTool.currentDockableWindow = m_dockableWindow

	End Sub

	Protected Overrides Sub OnMouseMove(ByVal arg As ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs)
		Try
			If Not m_schematicFeature1 Is Nothing Then

				Dim mxApp As ESRI.ArcGIS.ArcMapUI.IMxApplication = m_app

				If mxApp Is Nothing Then
					Return
				End If

				Dim appDisplay As ESRI.ArcGIS.Display.IAppDisplay = mxApp.Display

				If appDisplay Is Nothing Then
					Return
				End If

				Dim screenDisplay As IScreenDisplay = appDisplay.FocusScreen

				If screenDisplay Is Nothing Then
					Return
				End If


				'Move the Feedback to the current mouse location
				Dim pnt As IPoint = screenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y)

				If (m_linkFbk IsNot Nothing And pnt IsNot Nothing) Then
					m_linkFbk.MoveTo(pnt)
				End If
			End If

		Catch ex As Exception
			MsgBox(ex.Message)
		End Try
	End Sub

	Protected Overrides Sub OnMouseUp(ByVal arg As ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs)
		Dim abortOperation As Boolean = False
		Dim schematicOperation As ESRI.ArcGIS.Schematic.ISchematicOperation = Nothing

		Try

			If m_dockableDigit Is Nothing Then
				Return
			End If

			If Not arg Is Nothing Then
				m_x = arg.X
				m_y = arg.Y
			End If

			If m_dockableWindow Is Nothing Then
				Return
			End If

			If Not m_dockableWindow.IsVisible() Then
				m_dockableWindow.Show(True)
			End If

			Dim target As ESRI.ArcGIS.SchematicControls.ISchematicTarget

			target = m_schematicExtension

			If Not target Is Nothing Then
				m_schematicLayer = target.SchematicTarget
			End If

			If m_schematicLayer Is Nothing Then
				MsgBox("No target Layer")
				Return
			End If

			Dim inMemoryDiagram As ISchematicInMemoryDiagram
			Dim schematicInMemoryFeatureClass As ISchematicInMemoryFeatureClass
			Dim schematicInMemoryFeatureClassContainer As ISchematicInMemoryFeatureClassContainer

			'Get the point
			Dim point As New ESRI.ArcGIS.Geometry.Point

			Dim mxApp As ESRI.ArcGIS.ArcMapUI.IMxApplication
			Dim appDisplay As ESRI.ArcGIS.Display.IAppDisplay
			Dim screenDisplay As IScreenDisplay
			Dim display As IDisplay
			Dim transform As IDisplayTransformation
			Dim spatialReference As ISpatialReference

			inMemoryDiagram = m_schematicLayer.SchematicInMemoryDiagram
			schematicInMemoryFeatureClassContainer = inMemoryDiagram

			If (schematicInMemoryFeatureClassContainer Is Nothing) Then
				Return
			End If

			mxApp = m_app

			If mxApp Is Nothing Then
				Return
			End If

			appDisplay = mxApp.Display

			If appDisplay Is Nothing Then
				Return
			End If

			screenDisplay = appDisplay.FocusScreen
			display = screenDisplay

			If display Is Nothing Then
				Return
			End If

			transform = display.DisplayTransformation

			If transform Is Nothing Then
				Return
			End If

			spatialReference = transform.SpatialReference

			Dim mapPt As ESRI.ArcGIS.esriSystem.WKSPoint
			Dim devPoint As ESRI.ArcGIS.Display.tagPOINT
			devPoint.x = m_x
			devPoint.y = m_y
			transform.TransformCoords(mapPt, devPoint, 1, 1) 'esriTransformToMap

			point.SpatialReference = spatialReference
			point.Project(spatialReference)
			point.X = mapPt.X
			point.Y = mapPt.Y

			schematicInMemoryFeatureClass = schematicInMemoryFeatureClassContainer.GetSchematicInMemoryFeatureClass(m_dockableDigit.FeatureClass)

			If schematicInMemoryFeatureClass Is Nothing Then
				System.Windows.Forms.MessageBox.Show("Invalid Type.")
				Return
			End If

			If (m_dockableDigit.CreateNode = True) Then
				'TestMandatoryField
				m_dockableDigit.btnOKPanel1.Visible = False

				If m_dockableDigit.ValidateFields() = False Then
					m_dockableDigit.x() = m_x
					m_dockableDigit.y() = m_y
					MsgBox(m_dockableDigit.ErrorProvider1.GetError(m_dockableDigit.btnOKPanel1) & m_messageFromOK)
					Exit Sub
				End If

				Dim geometry As ESRI.ArcGIS.Geometry.IGeometry

				Dim schematicInMemoryFeatureNode As ISchematicInMemoryFeature

				geometry = point

				SchematicOperation = New ESRI.ArcGIS.SchematicControls.SchematicOperation

				'digit operation is undo(redo)able we add it in the stack
				Dim doc As IMxDocument = m_app.Document
				Dim operationStack As ESRI.ArcGIS.SystemUI.IOperationStack
				operationStack = doc.OperationStack()
				operationStack.Do(schematicOperation)
				schematicOperation.StartOperation("Digit", m_app, m_schematicLayer, True)

				'do abort operation
				abortOperation = True

				schematicInMemoryFeatureNode = schematicInMemoryFeatureClass.CreateSchematicInMemoryFeatureNode(geometry, "")
				'schematicInMemoryFeatureNode.UpdateStatus = esriSchematicUpdateStatus.esriSchematicUpdateStatusNew if we want the node deleted after update
				schematicInMemoryFeatureNode.UpdateStatus = esriSchematicUpdateStatus.esriSchematicUpdateStatusLocked

				abortOperation = False
				schematicOperation.StopOperation()

				m_dockableDigit.FillValue(schematicInMemoryFeatureNode)

				If (m_dockableDigit.AutoClear()) Then
					m_dockableDigit.SelectionChanged()
				End If

			Else
				m_dockableDigit.btnOKPanel2.Visible = False

                'Get the Tolerance of ArcMap
				Dim tolerance As Double
				Dim mxDocument As IMxDocument = m_app.Document
				Dim point2 As ESRI.ArcGIS.esriSystem.WKSPoint
				Dim devPt As ESRI.ArcGIS.Display.tagPOINT

				tolerance = mxDocument.SearchTolerancePixels
				devPt.x = tolerance
				devPt.y = tolerance

				transform.TransformCoords(point2, devPt, 1, 2) '2 <-> esriTransformSize 4 <-> esriTransformToMap

				tolerance = point2.X * 5 'increase the tolerance value

				Dim schematicFeatures As IEnumSchematicFeature
				schematicFeatures = m_schematicLayer.GetSchematicFeaturesAtPoint(point, tolerance, False, True)

				If Not schematicFeatures.Count > 0 Then
					Return
				End If

				Dim schematicFeatureSelected As ISchematicFeature
				Dim distancetmp As Double
				Dim distance As Double = 0
				schematicFeatures.Reset()


				''schematicFeatureSelected = schematicFeatures.Next

                ''pSchematicFeatures may contain several features , we are choosing the closest node.
				Dim schematicFeature2 As ISchematicFeature = schematicFeatures.Next()

				Dim dX As Double
				Dim dY As Double
				Dim schematicInMemoryFeatureNode As ISchematicInMemoryFeatureNode = Nothing

				If schematicFeature2 IsNot Nothing Then
					If schematicFeature2.SchematicElementClass.SchematicElementType = esriSchematicElementType.esriSchematicNodeType Then
						schematicInMemoryFeatureNode = schematicFeature2
					End If

				End If

				Dim schematicInMemoryFeatureNodeGeometry As ISchematicInMemoryFeatureNodeGeometry = schematicInMemoryFeatureNode
				dX = schematicInMemoryFeatureNodeGeometry.Position.X
				dY = schematicInMemoryFeatureNodeGeometry.Position.Y
				schematicFeatureSelected = schematicFeature2
				distance = SquareDistance(dX - point.X, dY - point.Y)

				While (schematicFeature2 IsNot Nothing)

					''find the closest featureNode...
					If schematicInMemoryFeatureNode IsNot Nothing Then

						schematicInMemoryFeatureNodeGeometry = schematicInMemoryFeatureNode

						If schematicInMemoryFeatureNodeGeometry Is Nothing Then
							Continue While
						End If

						dX = schematicInMemoryFeatureNodeGeometry.Position.X
						dY = schematicInMemoryFeatureNodeGeometry.Position.Y
						distancetmp = SquareDistance(dX - point.X, dY - point.Y)

						If (distancetmp < distance) Then
							distance = distancetmp
							schematicFeatureSelected = schematicFeature2
						End If
					End If

					schematicFeature2 = schematicFeatures.Next()

					If schematicFeature2 IsNot Nothing Then
						If schematicFeature2.SchematicElementClass.SchematicElementType = ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeType Then
							schematicInMemoryFeatureNode = schematicFeature2
						End If
					End If

				End While

				If (schematicFeatureSelected Is Nothing) Then
					Exit Sub
				End If

				If (schematicFeatureSelected.SchematicElementClass.SchematicElementType <> esriSchematicElementType.esriSchematicNodeType) Then
					Exit Sub
				End If

				If m_schematicFeature1 Is Nothing Then
					m_schematicFeature1 = schematicFeatureSelected
					m_dockableDigit.SchematicFeature1() = m_schematicFeature1

					If m_dockableDigit.CheckValidFeature(True) <> True Then
						m_schematicFeature1 = Nothing
						m_dockableDigit.SchematicFeature1() = m_schematicFeature1
						Err.Raise(513, "CheckValidFeature", "Invalid starting node for this link type")
					End If

					''Begin Feedback 
					m_linkFbk = New NewLineFeedback
					m_linkFbk.Display() = screenDisplay

					''symbol
					Dim sLnSym As ISimpleLineSymbol
					Dim rGB As IRgbColor

					sLnSym = m_linkFbk.Symbol

					rGB = New RgbColor
					' Make a color
					With rGB
						.Red = 255
						.Green = 0
						.Blue = 0
					End With

					' Setup the symbol with color and style
					sLnSym.Color = rGB

					m_linkFbk.Start(point)
					''End Feedback

					'To know if we are in the same diagram.
					m_schematicLayerForLink = m_schematicLayer

				Else
					If (Not m_schematicLayerForLink Is m_schematicLayer) Then
						MsgBox("wrong Target layer")
						m_schematicLayerForLink = Nothing
						EndFeedBack()
						Exit Sub
					End If
					m_schematicFeature2 = schematicFeatureSelected
					m_dockableDigit.SchematicFeature2() = m_schematicFeature2

					'TestMandatoryField
					If m_dockableDigit.ValidateFields() = False Then
						m_dockableDigit.x() = m_x
						m_dockableDigit.y() = m_y
						MsgBox(m_dockableDigit.ErrorProvider1.GetError(m_dockableDigit.btnOKPanel2) & m_messageFromOK)
						Exit Sub
					End If

					If m_dockableDigit.CheckValidFeature(False) <> True Then
						m_schematicFeature2 = Nothing
						m_dockableDigit.SchematicFeature2() = m_schematicFeature2
						Err.Raise(513, "CheckValidFeature", "Invalid End node for this link type")
					End If

					'CreateLink
					Dim schematicInMemoryFeatureLink As ISchematicInMemoryFeature

					schematicOperation = New ESRI.ArcGIS.SchematicControls.SchematicOperation
					
					'digit operation is undo(redo)able we add it in the stack
					Dim doc As IMxDocument = m_app.Document
					Dim operationStack As ESRI.ArcGIS.SystemUI.IOperationStack
					operationStack = doc.OperationStack()
					operationStack.Do(schematicOperation)
					schematicOperation.StartOperation("Digit", m_app, m_schematicLayer, True)

					abortOperation = True

					schematicInMemoryFeatureLink = schematicInMemoryFeatureClass.CreateSchematicInMemoryFeatureLink(m_schematicFeature1, m_schematicFeature2, "")
					'schematicInMemoryFeatureLink.UpdateStatus = esriSchematicUpdateStatus.esriSchematicUpdateStatusNew if we want the link deleted after update
					schematicInMemoryFeatureLink.UpdateStatus = esriSchematicUpdateStatus.esriSchematicUpdateStatusLocked

					abortOperation = False
					schematicOperation.StopOperation()

					m_dockableDigit.FillValue(schematicInMemoryFeatureLink)

					'End Feedback
					EndFeedBack()

					m_schematicLayerForLink = Nothing

					If (m_dockableDigit.AutoClear()) Then
						m_dockableDigit.SelectionChanged()
					End If

				End If

			End If

            'Refresh the view and viewer windows
			RefreshView()

			Return

		Catch ex As Exception
			If abortOperation = True And schematicOperation IsNot Nothing Then
				schematicOperation.AbortOperation()
			End If
			EndFeedBack()
			MsgBox(ex.Message)
		End Try

	End Sub

	Private Sub RefreshView()
		Dim map As IMap
		Dim mxDocument2 As IMxDocument = m_app.Document
		map = mxDocument2.FocusMap
		Dim activeView As IActiveView
		activeView = map
		activeView.Refresh()

		'refresh viewer window
		Dim applicationWindows As IApplicationWindows = m_app

		Dim mySet As ISet = applicationWindows.DataWindows

		If mySet IsNot Nothing Then
			mySet.Reset()
			Dim dataWindow As IMapInsetWindow = mySet.Next()
			While dataWindow IsNot Nothing
				dataWindow.Refresh()
				dataWindow = mySet.Next()
			End While		
		End If
			
	End Sub

	Public Sub MyMouseUp(ByVal x As Integer, ByVal y As Integer)
		m_x = x
		m_y = y
		m_messageFromOK = ""
		OnMouseUp(Nothing)
		m_messageFromOK = vbCrLf & "Complete missing data and click on button ok"
	End Sub

	Public Sub EndFeedBack()

		m_schematicFeature1 = Nothing
		m_schematicFeature2 = Nothing

		If m_dockableDigit IsNot Nothing Then
			m_dockableDigit.SchematicFeature1() = m_schematicFeature1
			m_dockableDigit.SchematicFeature2() = m_schematicFeature2
		End If

		If Not m_linkFbk Is Nothing Then
			m_linkFbk.Stop()
			m_linkFbk = Nothing
		End If

	End Sub

	Public WriteOnly Property SchematicFeature1() As ISchematicFeature
		Set(ByVal Value As ISchematicFeature)
			m_schematicFeature1 = Value
		End Set
	End Property

	Public WriteOnly Property SchematicFeature2() As ISchematicFeature
		Set(ByVal Value As ISchematicFeature)
			m_schematicFeature2 = Value
		End Set
	End Property

	Public Property FromDeactivate() As Boolean
		Get
			Return m_fromDeactivate
		End Get
		Set(ByVal value As Boolean)
			m_fromDeactivate = value
		End Set
	End Property

	Protected Overrides Sub Finalize()
		m_linkFbk = Nothing
		'If (m_dockableWindow IsNot Nothing) Then
		'	m_dockableWindow.Show(False)
		'End If

		MyBase.Finalize()
	End Sub

	Private Function SquareDistance(ByVal dx As Double, ByVal dy As Double) As Double
		Return (dx * dx + dy * dy)
	End Function
			

	Private Sub SetTargetLayer()
		If m_schematicLayer Is Nothing Then
			Dim extention As ESRI.ArcGIS.esriSystem.IExtension = Nothing
			Dim extensionManager As ESRI.ArcGIS.esriSystem.IExtensionManager

			extensionManager = m_app
			extention = extensionManager.FindExtension("esriSchematicUI.SchematicExtension")
			
			If extention IsNot Nothing Then

				m_schematicExtension = extention

				Dim target As ISchematicTarget = TryCast(extention, ISchematicTarget)

				If Not target Is Nothing Then
					m_schematicLayer = target.SchematicTarget
				End If
			End If
		End If
	End Sub

End Class