Jump to content
Paolo

Problem when naming symbols folder programmatically

Recommended Posts

In my Mouldings plugins package I use a file of symbols and symbol folders as a database to be used in the plugin.

The database is browsable using a tree control like this.

1703803555_Schermata2020-09-03alle14_47_38.thumb.png.f8f0d885b80687e5e04e1a31e7ebcd07.png


The symbol folders are created starting from an actual folder on the disk and, recursively, for each folder inside it.

I use the following commands (inside the recursion cycle):

{paths is the name of the actual folder as read from the disk}
nameObject(paths);
BeginFolderN(16);

Unfortunately folders on the disk and symbol folders in Vectorworks do not behave the same.

Vectorworks doesn't allow two entities with the same name.
For example, two folders can have the same name on the disk as soon as they are in different locations.

This cannot happen in Vectorworks, so I have a check to assign a progressive number each time a name already exists.

{paths is the name of the actual folder as read from the disk}
k := 1;
while getObject(paths) <> nil do
    begin
        if k = 1 then
            paths := concat(paths, '-', num2Str(0,k))
        else {I have already started the numbering…}
            paths := concat(Copy(paths, 1, len(paths)-len(num2Str(0,k))), num2Str(0,k));
        k := k+1;                
    end;
nameObject(paths);
BeginFolderN(16);

In this way I will have, for example Folder, Folder-1, Folder-2 and so on.

The problem is that I found a name ("Siding") that is probably a reserved word!
In this case

getObject('Siding')

returns nil and

nameObject('Siding')

returns an error message saying that there is already an object with that name.
Also

Name2Index('Siding')

returns 0 (no object associated with that name).

This is a contradiction!

Is there a way to see if a name is used other than to check for the associated object (that may fail!)?


This is the test script if you want to verify the contradiction:

procedure test;
var
h : handle;
begin
h := getObject('Siding');
if h = nil then message('No object with this name! ', Name2Index('Siding'));
nameObject('Siding');
BeginFolderN(16);

end;
run(test);

It shows a script error, here's mine (in Italian)

940706786_Schermata2020-09-03alle14_52_26.thumb.png.65aa8b0bf15fbc420a69cc447200aeb1.png

 

It says that 'Siding' name is already existing, but how can I check in advance if a name exists, avoiding showing the script error?

 

Thank you for the help.

Edited by Paolo

Share this post


Link to post

Use GetObject('Name")

 

It it returns anything other than a Nil handle then an object with that name exists.

Share this post


Link to post

Hi Pat,

the problem is that if you try

GetObject('Siding');

it returns Nil, so you can think that 'Siding' is a name free to use, but…

nameObject('Siding');

Returns a script error (name is already in use!).

So I cannot be sure (AFAIK) if a name I pass to GetObject is really Nil because it either has nothing associated or is a "reserved" word like 'Siding'.

Share this post


Link to post

Hi @Paolo ,

   Your test script needs an EndFolder command to compile correctly and run. Also, Name2Index() will always return "0" for a name that does not exist. 

 

PROCEDURE test;
VAR
	h : handle;
BEGIN
	h := GetObject('Siding');
	if (h = nil) then message('No object with this name! ''Siding'' exists');

	NameObject('Siding');
	BeginFolderN(16);
	EndFolder;
END;
Run(test);

 

Another problem with your script is if the folder "Siding" exists, VW will not delete it and create it again, a new folder named "Folder"  will be created, then after that VW will create "Folder-2", then "Folder-3", etc., each time your test script is rerun.

 

I believe @Pat Stanford 's approach is the right way to go – test for the handle's existence, then test for the handle's type – but you have to do different things based on:

1) if "Siding" does not exist (create your folder)

2) "Siding" exists, and it IS a Folder Type (do nothing; or delete the existing folder and recreate it from scratch)

3) "Siding" exists, but it IS NOT a Folder Type (execute your escape plan)

 

HTH,

Raymond

 

Share this post


Link to post

@MullinRJI think @Paolo is probably right. I think it is possible that something is used in the NameList of the file but attached to an object that will get a handle. Like a component of a wall.

 

I think you will have to write a routine to manually parse the Name list.

 

NameNum will get you the number of items in the NameList.

NameList(X) will return the string value of the name.

 

What I don't know is how fast the NameList commands are. If they are slow it might be better to read the entire NameList into an array of strings and then compare each potential import value to the array. You could sort the array to possibly make it faster.

 

If they are fast you could just step through the NameList each time before importing. But you still have the three cases to consider what you are doing.

 

(Psudocode)

NameFound:=False;

For X := 1 to NameNum do

Begin

  If NameList(X) = NameToTest then NameFound:=True;

End;

If NameFound then

  Begin

    Check type of object with the name

  End

Else

  Create Folder {Since name does not exist}

EndIf;

 

Share this post


Link to post

To verify @Pat Stanford conjecture, I have made this test:

procedure test;

var
i : integer;
h : handle;

begin
for i := 1 to nameNum do
	writeln(NameList(i));
	
h := GetObject('Siding');
if h = nil then {try to create an object and assign it the name 'Siding')}
	begin
		rect(0,0,100,100);
		setName(LNewObj, 'Siding'); {this gives an error!}
	end;
end;

run(test);

Applied to a new empty document, the result (in the output file), the following:


Nessuna
Quote
Irregolare
Tavolozza-1
Script-1

No sign of any "Siding", though the last part of the script…

setName(LNewObj, 'Siding');

Issues a script error (name already used!).

Also manually naming an object (in the OIP) as 'Siding' is not allowed.

 

Until now there is no a 100% chance that creating a symbol folder with a particular name will not lead to an error, despite all checks and control you can do priorly.

"Siding" is a word not allowed, discovered by accident. How many more words like this are there? There is a list of the reserved words?

I think I have to live with it!

Edited by Paolo

Share this post


Link to post

I just named an object Siding in the OIP without a problem.

 

Try your scripts on a new blank file? Could you have a problem with your template file that has a corrupt Siding object?

 

How about creating a worksheet database with a criteria of All Objects & In Symbol & In PIO. Use a column label of =N to display the name.

If that does not show an object named Siding perhaps place an instance of every symbol in the drawing and try again as the worksheet can only see objects that are in the drawing, not resources.

  • Like 1

Share this post


Link to post

Hi @Paolo.

   I know from testing on several versions of VW that "Siding" is not a reserved word. Would you please post a problem file so that we may investigate further? It's possible that your Mouldings Plug-ins package is using the name "Siding" and that is preventing you from using it again.

 

   Also, have you restarted VW to see if the issue goes away? If it does vanish after a restart, does it reappear a little later?

 

Thank you,

Raymond

Share this post


Link to post

Thank you @PatStanford and @MullinRJfor your help.

Siding is actually the name of one plugin in my mouldings package.

Is it not allowed to name an object with a name of a plugin?

Tomorrow I’ll try with the word ‘Corner’ that is another plugin of the package.

We will see...

 

About restarting VW, I had the very same behavior on two different Vectorworks installations, home and office, both with the Mouldings Package installed, VW2020 SP4 Italian version.

 

 

Share this post


Link to post

Hi @Paolo ,

   No, Plug-in names use the same name space as custom objects that you name manually, or by script. The only name space that I know of that is managed separately are the Layer Names. You can have objects, like Symbols, with the same name as a Layer and VW will not raise a conflict. 

 

   I know this is confusing, but you are now on the right track. 

 

Raymond

Share this post


Link to post

@Paolo, No, you can not use the same name for anything in VW. There are only two "name spaces" in Vectorworks. One is for Layers, the other is for everything else. So you can not name an object the same as the name of a PIO, a class, or another object.

 

(I have the above already typed before @MullinRJ beat me to the post so I am posting anyway.).  ;-)

 

  • Like 1

Share this post


Link to post

Ok, now that we found the cause, is there a procedure to get a list of the plugins names currently used so to  check if a name can be used?

 

The nameList() doesn’t show plugins names, just the objects named in the drawing.

 

And what happens if I create a ‘Xyz’ folder, then, later, I install a ‘Xyz’ plugin? Just curious...

Share this post


Link to post

Maybe this should work:

 

FUNCTION HasPlugin( itemUniversalName  :STRING; VAR PaletteName  :STRING) : BOOLEAN;

Share this post


Link to post
25 minutes ago, Pat Stanford said:

(I have the above already typed before @MullinRJ beat me to the post so I am posting anyway.). 😉

 

@Pat Stanford , You must know, as I do, that you have to get up pretty early if you want to beat @Pat Stanford to the post. 😉

 

LOL,

Raymond

Share this post


Link to post
17 minutes ago, Paolo said:

Maybe this should work:

 

FUNCTION HasPlugin( itemUniversalName  :STRING; VAR PaletteName  :STRING) : BOOLEAN;

 

@Paolo ,

   I did a quick test and it looks like the function HasPlugin() only returns TRUE if you have the plug-in installed in your workspace. Loading a plug-in after you have a resource/object of the same name will cause a conflict, but I don't know how VW responds in that scenario. I can only assume it causes more confusion.

 

Raymond

 

 

 

  • Like 1

Share this post


Link to post

PIOs load before drawings, so I would think the PIO would always win, but maybe not.

 

Anecdotal from about 10 years ago. User created classes named Door and Window. The user was then unable to use the Door or Window tool to place Door or Window objects due to the name conflict. Changing the class names to Doors and Windows solved the problem.

  • Like 1

Share this post


Link to post

Thanks very much to Mr. @MullinRJ and Mr. @PatStanford, the case was been brilliantly solved!

 

Here's the check passage to be sure a folder gets its unique name (paths is the string var to be queried):

 

k := 1;
{loop to check if there is already an object named paths or paths is the name of a plugin in the current workspace (conflict!)}
{add '-1', '-2', …-'n' to paths until there is no more conflict match.}
while ((getObject(paths) <> nil) or HasPlugin(paths, paletteName))  do
	begin
		if k = 1 then
			paths := concat(paths, '-', num2Str(0,k))
		else {ho già aggiunto un numero}
			paths := concat(Copy(paths, 1, len(paths)-len(num2Str(0,k))), num2Str(0,k));
		k := k+1;				
	end;

nameObject(paths);
		
BeginFolderN(16);
…
EndFolder;

 

  • Like 2

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


 

7150 Riverwood Drive, Columbia, Maryland 21046, USA   |   Contact Us:   410-290-5114

 

© 2018 Vectorworks, Inc. All Rights Reserved. Vectorworks, Inc. is part of the Nemetschek Group.

×
×
  • Create New...