Viewing Text Files

Related to my other thread, I now need to do something with the files I’ve created. I’ve stuck the list of file names in a datset, and populated a table (instead of a dropdown list, but the principle remains the same). As the operator arrows down through the table, the files should appear in a window. The files are text files, but have odd extensions, so I couldn’t get them to work with doc viewer, but your “Text Area” input box works great for what I want. Here’s what I’m doing:

I highlight a row in the table. Based on a propertyChange event, I go grab the file the row is pointing to, and rip through the file line by line like this:

if event.propertyName == 'selectedRow':

	
	import os 
	tFile = event.source.SelectedValue

	a_dir = 'C:\\Import\\Files' 
	tFile = a_dir + "\\" + tFile 
	
	event.source.parent.getComponent('Text Area').text = ''
	t_readFile = open(tFile, 'r')
	for line in t_readFile.readlines():
		event.source.parent.getComponent('Text Area').text = event.source.parent.getComponent('Text Area').text + line

Questions:

  1. Is there a better way of writing to the text area than (quasi code) “TextArea.txt = TextArea.txt + line” ? I tried a few variations of readlines(), but I don’t quite understand what a text area actually is I guess.

  2. As I rip through each line, I’d like to affect certain characters based on operator input. For instance, if they are looking for the word “START”, I would like to use HTML coding to bolden and highlight each occurance. Does your text area box support this?

  3. Is there a better way besides a text area box to do what I’m trying to do? Perhaps a java swing component? I’d like to have ultimate control over how the text is displayed if possible.

  1. Yes, what you’re doing is hugely inefficient. Ignoring the need to alter the text line by line (for now), the script should look like this:

[code]if event.propertyName == ‘selectedRow’:
tFile = event.source.SelectedValue

a_dir = ‘C:\Import\Files’
tFile = a_dir + “\” + tFile

event.source.parent.getComponent(‘Text Area’).text = fpmi.file.readFileAsString(tFile)
[/code]

Your code is doing a huge amount of temporary string allocation with all of that progressive appending - very poor for performance.

  1. As for altering the string, don’t do it line by line, do the entire string at once using regular expressions. Python strings have a replace function, and look at the re library.

  2. You can use HTML in the document viewer. Just be sure to set the text, and then set the content type to “text/html”.

Awesome! Much better performance. I can flip through the files as fast as I can arrow down through them.

As for your last point, can I use HTML in the text area box? You mention the doc viewer, but I’m not using that.

No, the text area is only for plain text (like notepad)

Ok, I’m using the doc viewer now, but don’t see a property to turn off word wrap like the text area box has. I see that it has a horizontal scroll bar, but some lines will still word wrap. Can I change this?

No, you can’t turn off word wrap on text/plain content, but I advise that you use text/html content, and then you can have more control over the formatting. For example, if you want your content to be very wide, put it all in a wide paragraph element, like so:

[code]

PUT YOUR WIDE CONTENT HERE

[/code]

Ok, after a short hiatus, I’m back hacking away at this problem.

First of all, your suggestion of using html worked perfectly. It’s exactly what I wanted, and the resulting files are extremely readable.

But, I’m having a problem doing it without creating a temporary file. What I am doing right now is reading the orginal file line by line, adding the html formatting tags as required, and then writing to a temp file. At the end, I read the temp file with “readFileAsString” just as I did with the orginal files to populate the text box, but there must be another way to do it.

Also, I wanted to use re:compile(…) and do the entire string at once, but there are some inconsistencies within the files that I don’t quite know how to handle yet. But the line by line method seems very fast for the time being. I’ll revisit re: in a while.

Yeah, if regular expressions aren’t suitable, don’t force it, you’ll drive yourself crazy.

If the line by line method is getting you the speed results you need, then there is no need to change the approach. If you need to, you can avoid the temp file by simply store the results in memory rather than write them to a temp file, assuming these files aren’t too huge.

Here is some pseudo-code

[code]finalString = “”
file = loadFile(…)
for line in file.readLines():
htmlLine = transform(line)
finalString += htmlLine

textBox.setText(finalString)[/code]

Thanks Carl. That did the trick. The files are from anywhere between 10 and 100 lines, so iterating line by line and building the string in memory is no big deal.

I looked up string concatenation for a few more tips, and found this site that showed a few comparisons between different approaches. Just thought I’d pass it along for others.

http://www.skymind.com/~ocrow/python_string/

Carl, I see the new version contains the feature we discussed on the phone the other day. I’m ready to run with this, and was wondering if you could post a couple of simple examples on how the hyperlinkupdate is actually used.

If I understand this correctly, I will need to set the doc viewer link action to “fire event”. Then, when I click on a link, would I use the “description” or “url” to pass something to the script? I just need a jump start on this.

And, thanks for the quick response on this. Once I have this working, it’s going to merge nicely with the java2d stuff you recently added.

Yes, you set the Link Action to “Fire Event”. In your case, you’re going to use the event object’s description property. (If you expand the help area in the event script editor and mouseover the properties of the hyperlinkupdate event, you’ll get some useful documentation.)

The url property will be null unless the href of the hyperlink is a valid URL (which, in your case, it isn’t)

Your script will look something like this:

[code]if str(event.eventType) == “ACTIVATED”:
href = event.description

do something here with whatever link they clicked on[/code]

Hope this helps,