home products news downloads documentation support gallery online maps resellers search
TNTmips Downloads Menu

HOME

CONTACT US

CURRENT RELEASE
  TNT 2013

DEVELOPMENT VERSION
  TNT 2014

TNTmips Pro
PRIOR RELEASES
  TNT 2012

FREE SOFTWARE
  TNTmips Free
  TNTatlas
  TNTsdk

MORE DOWNLOADS
  HASP Key Driver
  Screen Recorder
  TNT Language Kits
  Sample Geodata
  TNT Scripts

DOCUMENTATION
  TNTmips Tutorials
  Tutorial Datasets
  Technical Guides
  Scripts
  Quick Guides

MORE INFO
  Download FAQs
  FTP
  Download Managers
  Find Reseller

SITE MAP


URLS.SML

See other examples of Tool and Macro scripts ...


# URLS.SML - Pops up a dialog that opens the external browser to the url selected.
# Which URLs get displayed is based on where the user clicked.
# The URLs are stored in the reference file url.txt in the same directory as this script.
# Requires TNTmips version 6.4

# Format for reference file:
# [filename : description]
# {element} 					# element is either "raster value" or a vector element
# ...								# of the form "(element type) (table name) (field name) (field value)"
# {element}						# (See sample reference file)
# url
# ...
# url

# The following symbols are predefined 
#    class GROUP Group          {use to access the group being viewed if the script is run from a group view}
#    class VIEW View            {use to access the view the tool script is attached to}

# Variable declarations
class Widget listParent;
class XmForm form, buttonRow;
class XmRowColumn vectorModes, actions;
class XmSeparator line1, line2;
class XmList list;
class XmLabel vectorLabel, actionLabel;
class XmToggleButton pointButton, nodeButton, lineButton, polyButton;
class XmToggleButton scanButton, addButton;
class PushButtonItem urlButton, openButton, closeButton;
class XmDrawingArea da;
class GC gc;
class PointTool pointTool;
class MdispRegionTool polyTool;
string filepath$, mode$, action$;
VECTOR vv;
RASTER rv;
array numeric arr[1000];
numeric elemNum;
numeric setDefaultWhenClose;

# Callback for drawing area expose.  Draws text.
proc cbRedraw() {
	if (gc == 0) return;
	ActivateGC(gc);
	SetColorName("gray75");
	FillRect(0, 0, da.width, da.height);
	SetColorName("black");
	DrawInterfaceText("Layer: " + Group.ActiveLayer.Name + "\nURL File: " + filepath$, 0, 10);
	}

# Callback for when the active layer changes.
proc cbLayer() {
	if (Group.ActiveLayer.Type == "Raster") {
		vectorLabel.Sensitive = 0;
		pointButton.Sensitive = 0;
		nodeButton.Sensitive = 0;
		lineButton.Sensitive = 0;
		polyButton.Sensitive = 0;
		}
	else {
		vectorLabel.Sensitive = 1;
		polyButton.Sensitive = 1;
		lineButton.Sensitive = 1;
		nodeButton.Sensitive = 1;
		pointButton.Sensitive = 1;
		}
	cbRedraw();
	}

# Callback for when the open button is pressed.
proc cbOpen() {
	filepath$ = GetInputFileName(filepath$, "Open URL file", "txt");
	cbRedraw();
	}

# Callback for when the go button is pressed.
proc cbGo() {
	local string url$;
	url$ = list.GetItemAtPos(list.GetFirstSelectedPos());
	if (list.SelectedItemCount > 0 and url$ != "No URLs found!" and url$ != "Type not supported!"
		and url$ != "No element found!"  and url$ != "File not found!")
		RunAssociatedApplication(url$);
	}

# Callback for when the close button is pressed.
proc cbClose() {
	pointTool.Managed = 0;
	DialogClose(form);
	if (setDefaultWhenClose) {
		setDefaultWhenClose = false;
		View.SetDefaultTool();
		}
	}

# Callback for when user selects a different vector selection mode.
proc cbModeChanged() {
	if (pointButton.Set == 1) {
		mode$ = "point";
		}
	else if (nodeButton.Set == 1) {
		mode$ = "node";
		}
	else if (lineButton.Set == 1) {
		mode$ = "line";
		}
	else mode$ = "poly";
	}

# Callback for when user selects a different action.
proc cbActionChanged() {
	if (scanButton.Set == 1) {
		action$ = "scan";
		}
	else action$ = "add";
	}

# Callback for when user clicks the right mouse button on the polygon tool
# (or clicks apply).
proc cbToolApply(class PointTool pointTool) {
	# Clear the list
	list.DeleteAllItems();

	# Set up local variables.
	local string url$, layerName$, temp$, temp2$, item$, element$, table$, field$, value$;
	local class FILE reffile;
	local class GRE_LAYER layer;
	local numeric numTok, i, j, num, start;
	local class POINT2D point;
	local class StatusHandle status;
	local class StatusContext context;
	layer = Group.ActiveLayer;

	# If the layer is a raster or vector, proceed with the script.
	if (layer.Type == "Raster" or layer.Type == "Vector") {
		# Check point.
		point.x = pointTool.Point.x;
		point.y = pointTool.Point.y;

		# Set up layer, object, layer name, and point transformations.
		if (layer.Type == "Raster") {
			point = TransPoint2D(point, ViewGetTransLayerToScreen(View, layer, 1));
			DispGetRasterFromLayer(rv, layer);
			layerName$ = "[" + rv.$Info.Name + " : " + rv.$Info.Desc + "]";
			}
		else if (layer.Type == "Vector") {
			point = TransPoint2D(point, ViewGetTransViewToScreen(View, 1));
			point = TransPoint2D(point, ViewGetTransMapToView(View, layer.Projection, 1));
			local class GRE_LAYER_VECTOR vl;
			vl = layer;
			DispGetVectorFromLayer(vv, layer);
			layerName$ = "[" + vv.$Info.Name + " : " + vv.$Info.Desc + "]";
			}

		reffile = fopen(filepath$);

		# Find file entry.
		start = 0;
		while(!feof(reffile)) {
			url$ = fgetline$(reffile);
			start += 1;
			if (url$ == layerName$)
				break;
			}
		if (url$ != layerName$)
			list.AddItem("File not found!");

		# Read lines for this file.
		url$ = "";
		while(!feof(reffile)) {
			temp$ = fgetline$(reffile);
			url$ = url$ + temp$ + "\n";
			if (temp$ == "")
				break;
			}

		# Close file.
		fclose(reffile);

		# Add non-specific URLs to the list.
		numTok = NumberTokens(url$, "\n\r");
		for i = 1 to numTok {
			item$ = GetToken(url$, "\n\r", i);
			if (left$(item$, 1) == "{")
				break;
			if (!list.ItemExists(item$))
				list.AddItem(item$);
			start += 1;
			}

		# Remove non-specific URLs from string.
		temp$ = "";
		for j = i to numTok
			temp$ = temp$ + GetToken(url$, "\n\r", j) + "\n";
		url$ = temp$;

		# If the string is empty, break out of the if statement.
		if (url$ == "")
			break;

		# Set loop variables.
		numeric add = false;
		numTok = NumberTokens(url$, "\n\r");

		# If the layer is vector and an appropriate element exists or the layer is a raster
		# and the cell value is not null, search the rest of the string.
		if ((layer.Type == "Vector" and ((mode$ == "point" and vv.$Info.NumPoints > 0) or
			 										(mode$ == "node" and vv.$Info.NumNodes > 0) or
			 										(mode$ == "line" and vv.$Info.NumLines > 0) or
			 										(mode$ == "poly" and vv.$Info.NumPolys > 0))) or
			 (layer.Type == "Raster" and !IsNull(rv[point.y, point.x]))) {

			# If the layer is a vector, find and highlight the closest element.
			numeric elementNum;
			if (layer.Type == "Vector") {
				if (mode$ == "point") {
					elementNum = FindClosestPoint(vv, point.x, point.y, GetLastUsedGeorefObject(vv));
					vl.Point.HighlightSingle(elementNum);
					}
				else if (mode$ == "node") {
					elementNum = FindClosestNode(vv, point.x, point.y, GetLastUsedGeorefObject(vv));
					vl.Node.HighlightSingle(elementNum);
					}
				else if (mode$ == "line") {
					elementNum = FindClosestLine(vv, point.x, point.y, GetLastUsedGeorefObject(vv));
					vl.Line.HighlightSingle(elementNum);
					}
				else {
					elementNum = FindClosestPoly(vv, point.x, point.y, GetLastUsedGeorefObject(vv));
					vl.Poly.HighlightSingle(elementNum);
					}
				}

			# Create a status bar so user knows the script is doing something.
			status = StatusDialogCreate(form);
			context = StatusContextCreate(status);
			StatusSetMessage(context, "Scanning File...");

			for i = 1 to numTok {
				temp$ = GetToken(url$, "\n\r", i);

				# If the token ends in a } it is a raster value or vector element.
				if (right$(temp$, 1) == "}") {
					arr[i - 1] = 1;


					# If the last element was a URL, set add to false.
					if (i != 1)
						if (arr[i - 2] == 0)
							add = false;

					# If add is false, check if this point has the current raster value or is close 
					# to the current vector element.
					if (!add) {
						if (layer.Type == "Raster") {
							if (rv[point.y, point.x] == StrToNum(GetToken(temp$, "{}", 1))) {
								arr[i - 1] = 2;
								add = true;
								}
							}
						else {
							element$ = GetToken(temp$, "{ }", 1);
							table$ = GetToken(temp$, "{ }", 2);
							field$ = GetToken(temp$, "{ }", 3);
							value$ = "";
							num =  NumberTokens(temp$, "{ }");
							for j = 4 to num
								value$ = value$ + " " + GetToken(temp$, "{ }", j);
							value$ = right$(value$, strlen(value$) - 1);
							if (element$ == mode$) {
								if (mode$ == "point") {
									if (vv.point[elementNum].(table$).(field$)$ == value$) {
										add = true;
										arr[i - 1] = 2;
										}
									}
								else if (mode$ == "node") {
									if (vv.node[elementNum].(table$).(field$)$ == value$) {
										add = true;
										arr[i - 1] = 2;
										}
									}
								else if (mode$ == "line") {
									if (vv.line[elementNum].(table$).(field$)$ == value$) {
										add = true;
										arr[i - 1] = 2;
										}
									}
								else {
									if (vv.poly[elementNum].(table$).(field$)$ == value$) {
										add = true;
										arr[i - 1] = 2;
										}
									}
								}
							}
						}
					}

				#  Add the url to the list if add is true and it is not on the list.
				else {
					arr[i - 1] = 0;
					if (add)
						if (!list.ItemExists(temp$))
							list.AddItem(temp$);
					}
				}

			if (list.ItemCount == 0)
				list.AddItem("No URLs found!");

			cbRedraw();

			# Destroy the status bar.
			StatusContextDestroy(context);
			StatusDialogDestroy(status);


			# If the action is add, get URL from user.
			if (action$ == "add") {
				local class DATABASE db;
				if (layer.Type == "Raster") {
					item$ = PopupString(sprintf("Enter a URL to add for raster value %.2f:", rv[point.y, point.x]));
					j = 1;
					}
				else {
					if (mode$ == "point") {
						db = OpenVectorPointDatabase(vv);
						j = PopupSelectTableField(db, table$, field$);
						value$ = vv.point[elementNum].(table$).(field$)$;
						}
					else if (mode$ == "node") {
						db = OpenVectorPointDatabase(vv);
						j = PopupSelectTableField(db, table$, field$);
						value$ = vv.node[elementNum].(table$).(field$)$;
						}
					else if (mode$ == "line") {
						db = OpenVectorLineDatabase(vv);
						j = PopupSelectTableField(db, table$, field$);
						value$ = vv.line[elementNum].(table$).(field$)$;
						}
					else {
						db = OpenVectorPolyDatabase(vv);
						j = PopupSelectTableField(db, table$, field$);
						value$ = vv.poly[elementNum].(table$).(field$)$;
						}
					if (j > 0)
						item$ = PopupString(sprintf("Enter a URL to add for:\n   Table: %s\n   Field: %s\n   Value: %s",
															  table$, field$, value$));
					}

				# If there was no error getting table and field information, continue.
				if (j > 0) {
					# Read file into string.
					url$ = "";
					reffile = fopen(filepath$);
					while(!feof(reffile)) {
						temp$ = fgetline$(reffile);
						if (temp$ == "")
							temp$ = " ";
						url$ = url$ + temp$ + "\n";
						}
					url$ = left$(url$, strlen(url$) - 1);
					fclose(reffile);

					# Add the URL to the appropriate location in the reference file.
					if (list.GetItemAtPos(1) != "File not found!") {
						temp$ = "";
						for j = 1 to start {
							temp2$ = GetToken(url$, "\n\r", j);
							if (temp2$ == " ")
								temp2$ = "";
							temp$ = temp$ + temp2$ + "\n";
							}

						for j = 1 to numTok {
							temp$ = temp$ + GetToken(url$, "\n\r", j + start) + "\n";
							if (j > 1) {
								if (arr[j - 1] == 2 and arr[j] == 0 and arr[j - 2] == 0)
									break;
								}
							else if (arr[j - 1] == 2 and arr[j] == 0)
								break;
							}
						if (j > numTok) {
							j -= 1;
							if (layer.Type == "Raster") {
								temp$ = temp$ + "{" + NumToStr(rv[point.y, point.x]) + "}" + "\n";
								}
							else temp$ = temp$ + "{" + mode$ + " " + table$ + " " + field$ + " " + value$ + "}" + "\n";
							}
						temp$ = temp$ + item$ + "\n";
						num = NumberTokens(url$, "\n\r");
						for j = j + start + 1 to num {
						temp2$ = GetToken(url$, "\n\r", j);
							if (temp2$ == " ")
								temp2$ = "";
							temp$ = temp$ + temp2$ + "\n";
							}

						url$ = left$(temp$, strlen(temp$) - 1);
						}
					else {
						if (layer.Type == "Raster") {
							temp$ = "{" + NumToStr(rv[point.y, point.x]) + "}";
							}
						else temp$ = "{" + mode$ + " " + table$ + " " + field$ + " " + value$ + "}";
						url$ = url$ + "\n\n" + layerName$ + "\n" + temp$ + "\n" + item$;
						}

					# This is currently the only way to to file modification other than overwriting data.
					# Create a new file, write to it, and delete the old one.
					RenameFile(filepath$, FileNameGetPath(filepath$) + FileNameGetName(filepath$) + ".old");

					# Recreate file.
					reffile = fopen(filepath$);

					# Write to the new file.
					fwritestring(reffile, url$);

					# Close file.
					fclose(reffile);

					# Delete old file.
					DeleteFile(FileNameGetPath(filepath$) + FileNameGetName(filepath$) + ".old");
					}
				}
			}
		else if (list.ItemCount == 0)
			list.AddItem("No element found!");
		list.VisibleItemCount = list.ItemCount;
		if (list.VisibleItemCount > 10)
			list.VisibleItemCount = 10;
		}
	else
		list.AddItem("Type not supported!");
	url$ = list.GetItemAtPos(1);
	if (url$ != "No URLs found!" and url$ != "Type not supported!"
		and url$ != "No element found!"  and url$ != "File not found!")
		list.SelectPos(1);
	}

# Called the first time the tool is activated. 
# If the tool implements a dialog it should be created (but not displayed) here. 
func OnInitialize () {
	WidgetAddCallback(Group.LayerSelectedCallback, cbLayer);

	# Set up dialog
	form = CreateFormDialog("Select a URL");
	form.marginHeight = 2;
	form.marginWidth = 2;
	form.ResizePolicy = "RESIZE_ANY";
	WidgetAddCallback(form.Shell.PopdownCallback, cbClose);

	# Drawing area for displaying raster name.
	da = CreateDrawingArea(form, 30, 350);
	da.leftWidget = form;
	da.topWidget = form;
	da.rightWidget = form;
	WidgetAddCallback(da.ExposeCallback, cbRedraw);

	# List for displaying urls.
	list = CreateScrolledList(form);
	listParent = list.parent;
	listParent.topWidget = da;
	listParent.leftWidget = form;
	listParent.rightWidget = form;

	# Label for vector modes.
	vectorLabel = CreateLabel(form, "Vector Mode:");
	vectorLabel.topWidget = list;
	vectorLabel.leftWidget = form;
	vectorLabel.topOffset = 4;

	# Form for toggle buttons for vector mode.
	vectorModes = CreateRowColumn(form, 4);
	vectorModes.topWidget = list;
	vectorModes.leftWidget = vectorLabel;
	vectorModes.rightWidget = form;
	vectorModes.RadioBehavior = 1;

	# Button to select points.
	pointButton = CreateToggleButton(vectorModes, "Points");
	WidgetAddCallback(pointButton.ValueChangedCallback, cbModeChanged);

	# Button to select points.
	nodeButton = CreateToggleButton(vectorModes, "Nodes");
	WidgetAddCallback(nodeButton.ValueChangedCallback, cbModeChanged);

	# Button to select points.
	lineButton = CreateToggleButton(vectorModes, "Lines");
	WidgetAddCallback(lineButton.ValueChangedCallback, cbModeChanged);

	# Button to select points.
	polyButton = CreateToggleButton(vectorModes, "Polygons");
	WidgetAddCallback(polyButton.ValueChangedCallback, cbModeChanged);

	# Separator between vector modes and actions.
	line1 = CreateHorizontalSeparator(form);
	line1.topWidget = vectorModes;
	line1.leftWidget = form;
	line1.rightWidget = form;

	# Label for actions.
	actionLabel = CreateLabel(form, "Action:");
	actionLabel.topWidget = line1;
	actionLabel.leftWidget = form;
	actionLabel.topOffset = 4;

	# Form for toggle buttons for options.
	actions = CreateRowColumn(form, 3);
	actions.topWidget = line1;
	actions.leftWidget = actionLabel;
	actions.rightWidget = form;
	actions.RadioBehavior = 1;

	# Button to select scan.
	scanButton = CreateToggleButton(actions, "Scan");
	WidgetAddCallback(scanButton.ValueChangedCallback, cbActionChanged);

	# Button to select add.
	addButton = CreateToggleButton(actions, "Add");
	WidgetAddCallback(addButton.ValueChangedCallback, cbActionChanged);

	# Separator between actions and command buttons.
	line2 = CreateHorizontalSeparator(form);
	line2.topWidget = actions;
	line2.leftWidget = form;
	line2.rightWidget = form;

	# Button to open reference file.
	openButton = CreatePushButtonItem("Open File...", cbOpen);

	# Button to launch browser.
	urlButton = CreatePushButtonItem("Launch Browser", cbGo);

	# Button to close polyTool.
	closeButton = CreatePushButtonItem("Close", cbClose);

	# Row of buttons.
	buttonRow = CreateButtonRow(form, openButton, urlButton, closeButton);
	buttonRow.topWidget = line2;
	buttonRow.leftWidget = form;
	buttonRow.rightWidget = form;

	# Add point tool.
	pointTool = ViewCreatePointTool(View);
	ToolAddCallback(pointTool.ActivateCallback, cbToolApply);

	# Default file path.
	filepath$ = _context.ScriptDir + "url.txt";
	}  # end of OnInitialize

# Called when tool is to be destroyed, will not be called if tool was never activated. 
# If the tool implements a dialog it should be destroyed here. 
func OnDestroy () {
	cbClose();
	DestroyGC(gc);
	DestroyWidget(form);
	}  # end of OnDestroy 
 
# Called when tool is activated. 
# If the polyTool implements a dialog it should be "managed" (displayed) here. 
func OnActivate () {
	# Reset everything to default.
	list.DeleteAllItems();
	list.VisibleItemCount = 1;
	pointButton.Set = 0;
	nodeButton.Set = 0;
	lineButton.Set = 0;
	polyButton.Set = 1;
	mode$ = "poly";
	scanButton.Set = 1;
	addButton.Set = 0;
	action$ = "scan";

	if (Group.ActiveLayer.Type == "Vector")
		Group.ActiveLayer.UnhighlightAllElements();
	DialogOpen(form);
	pointTool.Managed = 1;
	pointTool.HasPosition = 0;

	# Find reference file
	if (!fexists(filepath$))
		cbOpen();

	if (gc == 0)
		gc = CreateGCForDrawingArea(da);
	cbLayer();
	setDefaultWhenClose = true;
	}  # end of OnActivate
 
# Called when tool is deactivated (usually when switching to another tool). 
# If the tool implements a dialog it should be "unmanaged" (hidden) here. 
func OnDeactivate () {
	setDefaultWhenClose = false;
	cbClose();
	}  # end of OnDeactivate


Back Home ©MicroImages, Inc. 2013 Published in the United States of America
11th Floor - Sharp Tower, 206 South 13th Street, Lincoln NE 68508-2010   USA
Business & Sales: (402)477-9554  Support: (402)477-9562  Fax: (402)477-9559
Business info@microimages.com  Support support@microimages.com  Web webmaster@microimages.com

25 March 2009

page update: 16 Jun 11