Can I make a Text Editor object read-only under program control?


My goal is to have an entry box whose data is initially editable, then after clicking a “finished” button, that object now acts like a Text Display object. The contents could be edited again through a different method, or an “unlock” button could re-enable editing in place, but it is safe from unauthorized or accidental modification. Is this currently possible, or is it a feature being considered?


You could set it to “formula”. The formula would be the field or variable you wanted to display. Editing would cause the value that was entered to go into a variable named TextEditingResult. You would write a procedure that would pass that value on to the field or variable you are displaying, or not, depending on the current value of a variable indicating whether it was locked or unlocked.


Thanks, Dave. I’m having trouble wrapping my head around all of this. Let me give some more specific details of what I’m doing, and maybe you can steer me in terms of what you’re talking about.

This involves an Invoice database, with line items holding the individual items ordered on that invoice. Some of these items have serial numbers, which must be recorded at this point. An earlier procedure has preloaded my Text Editor with a ¶-delimited array that provides the item code for each line item that needs a serial number recorded, with an entry space right after each array item for the s/n. Once all the serial numbers have been typed in, pressing a button processes that information into the appropriate data structures in other databases. At this point I want to “freeze” that entry, showing its completed value whenever that record is brought up, but not allow any keystrokes - basically turn it into a TDO.

If there was an “editable/not editable” switch on the TEO that I could control with a procedure, the problem would be solved. I was looking for some setting in the Blueprint that I might be able to manipulate to do this, but I didn’t find anything.

If you could give me a little more detail about the steps you described it would be a big help.


I thought of another angle. Is there a way to control the “arrangement” of an object, that is, “Send to Back”, “Send to Front”, etc, under program control? I could have identical TDO/TEO laid on top of each other, showing the same field contents, and send the TDO to Front to prevent editing, or to Back to let the TEO be the active object.


Scott, even if Panorama had an option to disable a Text Edit object (which might not be a bad idea) it wouldn’t really help your application. In your application, it sounds like you would need to have the enable/disable status change on the fly, as you move from record to record. In other words, simply moving up or down in the database I think you would need it to change from enabled to disabled. That wouldn’t work if enable/disable was an option for the object itself, since the object wouldn’t change as you move from record to record.

You can do send to back/bring to front under program control. Also, why stop there – you can simply create the editor object when you need it on the fly! However, neither one of those techniques will get around the problem I mentioned in the last paragraph – you almost certainly want the status to change without any programming. But if programming is ok, then you can make ANY change you want to a form under program control. Your program can start with an empty form and build the entire thing from scratch if it wants, and change it in any way at any time. I don’t know if you ever purchased the training videos, but there was a 2 part session that covered this in depth.

For example, the Find/Select dialog works that way. That dialog is a Panorama form. When you press the + button to add another row, Panorama actually creates some new objects on the fly. When you press the - button, that row of objects is deleted. So this is a real world technique that actually works. By the way, an easy way to write the code to create a graphic object is to create it manually, then open the blueprint, and copy the code out of that dialog. The code is ready to use as is for creating another exact copy of the selected object.

You might take a closer look at what Dave is suggesting, that could be a good solution for you as well.


That’s exactly right. But I’m thinking in terms of a changeobject command that enables/disables editing (if that was actually a setting) on that object based on a variable in that record, not just setting the object characteristic once and for all.

Can you expand a bit on how to send to back/bring to front programatically? It might be an imperfect way, but I’d like to see it in action and it might help elsewhere.

Creating/destroying objects is not an approach I’ve ever thought of, and I’ll explore that; the possibilities seem endless. A big factor in any of these methods is how long of a delay will these manipulations cause as I scroll from record to record? And I’m quite fine with doing all of this with programming, I don’t know how else to make it sensitive to settings in each individual record. I’m going to try some things, this might work best in the end.

I was looking for a handler to execute code whenever a record changed, a la .CurrentRecord in Pan 6, but I can’t find any documentation on them in Help except ‘info(“runninghandler”)’ which describes the purpose of handler procedures but gives no information about what’s available and how to invoke them.

I’m not completely clear on what Dave is suggesting, and I’m hoping for some elaboration.


None of these methods are going to work scrolling from record to record, that was my point.

Panorama X doesn’t currently have a .CurrentRecord feature, and if it did, it would not be able to perform graphic manipulations of any kind, whether send to back/front, creating objects, whatever (obviously it couldn’t do that in Panorama 6 either).

Using Formula Mode is described in detail in both the Panorama X and Panorama 6 documentation. To make one point clear – using Dave’s suggestion would not prevent you from clicking on and editing the text, but it would make it possible to prevent any change happening to the database when editing was complete.


Here is a scheme to be able to lock a Text Editor Object depending upon a field’s value on a record by record basis. We have a Text Editor Object named “theTextBox” with the options set as below.

The field the TEO is linked to is named TheText along with another text field named textLock which can be hidden if desired. The procedure for the TEO looks like this:

I have a small Text Display Object next to the TEO with a lock image that shows when the textLock field is set to “1”. I used the FontAwesome lock character with this formula:


The TDO has a procedure that will remove the lock if the option key is used when clicking it or if the right mouse key is used. Changing the textLock field then enables editing and opens the TEO. This allows you to override the lock if necessary.

The way it works is that when the TEO is clicked on to edit it checks to see if the textLock field is set for that record. If it is it beeps and makes sure the TEO does not open. If editing is allowed it will set the textLock field to “!” when finished as long as it is not blank. The animation below shows scrolling down the TheText field as the lock kicks in and out depending upon the record. It also shows the TEO being unlocked using a right click to edit the field.

This little test file is available at


I saw a discussion about handlers not being able to do lots of things, like graphic manipulations, but can’t the handler code call other procedures that can do this? In any case, I had already put Next/Previous buttons on my form to do record “scrolling” and running a key procedure, as a stop-gap until I could invoke .CurrentRecord for this, but I’ll just continue to use my buttons and retain full ability to perform whatever tasks I need. I need to explore different ways of storing my blueprint values for the various objects I want to destroy or create on the fly.

But I just saw Gary’s post and it’s a very interesting approach. I’ll try it. Thanks Gary!


No. What “handler” code means is that Panorama is running the code without the normal event run loop. So the code cannot perform any action that requires the event run loop to operate. If the code calls a subroutine, that subroutine will also be executed without the normal event run loop. Just because it is a subroutine doesn’t change anything. It’s not the code itself that makes it a handler – it is how Panorama runs the code.

I realize the previous paragraph problem isn’t going to make much sense to most of you. Sorry about that, you’ll have to stick with the first word – No.


I realize the previous paragraph problem isn’t going to make much sense to most of you

It’s only a problem if you don’t understand it! : ) You meant probably, right?


Yes, that’s what I meant.


Huh? I’ve been using .CurrentRecord in my Pan X databases all along and it runs as intended every time I move to another record. Or am I dillusional?


Jim, you are not dillusional or delusional! I guess I forgot that I have added support for .CurrentRecord to Panorama X. I just check the source code, and it is in there. Also, it is not executed as a handler, so you can do anything you want in this routine. Still, I would recommend that whatever you do, it should be speedy.

Now that we have established the .CurrentRecord is available, I still probably wouldn’t recommend manipulating graphic objects in this code. First, it will probably be too slow, this code should be super fast. Also, it won’t work unless the form in question is the topmost window. If your database has more than one window open this isn’t going to work at all, even slowly.


Gary, this works great, it doe everything I need. Thank you! The real key is the Procedure Trigger settings, with the procedure closing the object before it can do anything. I can’t imagine having come up with this myself.

How can I find out more about the FontAwesome character set?


Open the Help and search for awesome. Or font. Or icon.


Also under the Help menu you will find Font Awesome Icons.


Since the font is invoked by calling it “FontAwesome” with no spaces, it would be useful for Help to recognize this way of expressing it. That’s why I couldn’t find it.


The regular Help search searches the topic titles. Since there is no topic called FontAwesome, it didn’t find it. If you check the Full Text Search option, it searches ALL the text. In that case, a search for FontAwesome with no spaces will work.

There are two reasons why the Full Text Search option is not always turned on:

  • It’s considerable slower
  • In some cases the full text search will turn up way too many results. For example, a regular search for call will turn up 12 results, probably including what you are looking for. But a full text search for call will return 395 results, probably making the actual information you are trying to find much harder to find.