• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. Select cell view from lib manager

Stats

  • Locked Locked
  • Replies 19
  • Subscribers 143
  • Views 22121
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Select cell view from lib manager

netbug
netbug over 8 years ago

Dear all,

I have a script which allows the user to select a cell view from the library manager, without opening prompting the user. The user selects, in first place, the cell view from the library manager and only then the user should press the button for the script to run. As this is counter-intuitive for some, I would like to have the opposite. When user clicks the "select" button it will open the lib manager, so the user can choose the cell view.

This is described in Cadence documentation, and an example is given for the "ddsUpdateSyncWithForm" command. However this method uses three text boxes (string fields) which get the values for lib, cell and view. But in my case, I would like to use a single text box instead of three, and I can't do it. I've tried to pass the values (lib,cell,view) with variables but it didn't work.

Second question. In the code, you can see that I have to identical "procedures". The only difference is that one is executed when button 1 is pressed and the second when button 2 is pressed. How can I detect which button has been pressed, so I can do a generic function for both.

 

Thanks in advance.

Best regards,

José

 

My code


;==============================================================================
;============================== main function ================================
;==============================================================================

procedure(main()
let((retValue)

; Create the form
retValue=CreateMainForm()
putprop( 'settingsForm 'myHelpCB 'hiHelpAction) ; Customize the information displayed by the Help button

declare(selectedViewArray[2])
selectedViewArray[0]=""
selectedViewArray[1]=""
);end let
) ; end procedure

;==============================================================================
;=============== Display main Form - Create Main form" =======================
;==============================================================================

procedure(CreateMainForm()
let((label1 doneButton settingsForm cellView1 cellView2 selectButton1 selectButton2 selectButton3 sep1)
; template loading and saving

label1=hiCreateLabel(
?name 'label1
?labelText "SUMMARY FILE'S COMPARISON"
?justification 'center
)

sep1=hiCreateSeparatorField(?name 'sep1)

cellView1 = hiCreateStringField(
?name 'cellView1
?prompt "Summary file 1 :"
?value "Please select a summary file"
?editable nil

)

cellView2 = hiCreateStringField(
?name 'cellView2
?prompt "Summary file 2 :"
?value "Please select a summary file"
?editable nil
)

selectButton1=hiCreateButton(
?name 'selectButton1
?buttonText "Select"
?callback "cb_button1_pressed()"
)

selectButton2=hiCreateButton(
?name 'selectButton2
?buttonText "Select"
?callback "cb_button2_pressed()"
)

selectButton3=hiCreateButton(
?name 'selectButton3
?buttonText "Compare !"
?callback "cb_button3_pressed()"
)


hiCreateAppForm(
?name 'settingsForm
?formTitle "Compare summary files"
;?callback list("testOK()" "testCancel()")
?buttonLayout 'Close
?fields list(
list(label1 10:10 600:0 40)
list(sep1 0:35 600:0)
list(cellView1 15:50 500:30 100)
list(cellView2 15:85 500:30 100)
;list(cellView2 300:8 55:30)
;list(selectLabel 15:70 45:20 200)
list(selectButton1 520:50 50:30)
list(selectButton2 520:85 50:30)
list(selectButton3 120:120 90:30)
) ; end list
) ; create form

hiDisplayForm(settingsForm) ; Display form
); end let
); end procedure


;==============================================================================
;=============== Select button1 pressed "cb_button1_pressed" ====================
;==============================================================================
procedure(cb_button1_pressed()
let((selectedView libName cellName viewName pathToSelectedView)
;printf("Test!")
selectedView=ddsGetLibManLCV() ; list containing the the "lib", "cell" and "view", when clicked in lib manager

; separate the list into different variables
libName=nth(0 selectedView)
cellName=nth(1 selectedView)
viewName=nth(2 selectedView)

if(rexMatchp("small_sum" viewName)==t then ; checks if "small_sum" exist in the name of the cell view
; outputs the path to the cell view in the list
pathToSelectedView=ddGetObjReadPath(ddGetObj(libName cellName viewName "*"))

; creates a string in the format "cellname -> viewName" and copies it to the textbox
sprintf(cellViewStr "\n%s -> %s" cellName viewName)
get(settingsForm settingsForm->cellView1->value=cellViewStr)
;printf("Button 1 pressed\n")
;printf(pathToSelectedView)

selectedViewArray[0]=pathToSelectedView

else
dispMessage("Cellview must be text !")

) ;end if
) ;end let

) ;end procedure


;==============================================================================
;=============== Select button2 pressed "cb_button2_pressed" ====================
;==============================================================================
procedure(cb_button2_pressed()
let((selectedView libName cellName viewName pathToSelectedView)
;printf("Test!")
selectedView=ddsGetLibManLCV() ; list containing the the "lib", "cell" and "view", when clicked in lib manager

; separate the list into different variables
libName=nth(0 selectedView)
cellName=nth(1 selectedView)
viewName=nth(2 selectedView)

if(rexMatchp("small_sum" viewName)==t then

; outputs the path to the cell view in the list
pathToSelectedView=ddGetObjReadPath(ddGetObj(libName cellName viewName "*"))

; creates a string in the format "cellname -> viewName" and copies it to the textbox
sprintf(cellViewStr "\n%s -> %s" cellName viewName)
get(settingsForm settingsForm->cellView2->value=cellViewStr)

;printf("Button 2 pressed\n")
;printf(pathToSelectedView)
selectedViewArray[1]=pathToSelectedView

else
dispMessage("Cellview must be text !")
) ;end if


) ;end let
) ;end procedure

;==============================================================================
;=============== Compare Button "cb_button3_pressed" ====================
;==============================================================================
procedure(cb_button3_pressed()
let((str)

; checks if both textboxes aren't empty
if(cellView1->value!="Please select a summary file" && cellView2->value!="Please select a summary file" then
str=sprintf(test "tkdiff %s %s" selectedViewArray[0] selectedViewArray[1]) ; string having the full command to be executed in the shell

csh(str) ; executes the command on linux shell

; Re-initialise text boxes after closing tkdiff editor
get(settingsForm settingsForm->cellView1->value="Please select a summary file")
get(settingsForm settingsForm->cellView2->value="Please select a summary file")
else
dispMessage("Please select two views to be compared !!" )
) ;end if

) ;end let
) ;end procedure

;==============================================================================
;===================== Display Message "dispMessage" =========================
;==============================================================================
procedure(dispMessage( message )
hiDisplayAppDBox(
?name gensym('mybox)
?dboxBanner "Message"
?dboxText message
?dialogStyle 'modeless
?dialogType hicMessageDialog
?buttonLayout 'Close
) ; hiDisplayAppDBox
); End procedure


;==============================================================================
;===================== Building myHelpCB funtion =============================
;==============================================================================

procedure(myHelpCB(arg1 arg2 arg3 arg4)
let((helpStrMsg)

; Help Message
helpStrMsg="\n\
DESCRIPTION\n\
\tSummary file 1 - first summary view selected from the lib manager\n\
\tSummary file 2 - second summary view selected from the lib manager\n\
\t\"Select\" buttons- retrieve the name of the selected views from the lib manager\n\
\t\"Compare\" button - triggers \"tkdiff\" from linux in order to compare both views\n\n\
SUMMARY: \n\
\t1 - Click on the desired cell view from the \"Library manager\"\n\
\t2 - Click the correspondent \"Select\" button.\n\
\t3 - Hit the \"Compare\" button.\n"


hiDisplayAppDBox(
?name gensym("dbox")
?dboxBanner "compViews script HELP"
?dboxText helpStrMsg
?dialogType hicInformationDialog
?dialogStyle 'modeless
?buttonLayout 'Close
)
)
)



  • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Unknown said:
    In the same way, for eg, C allows it, is it possible to have functions stored into a file, and call them from there, pointing to that file (including the file) ?

    Pedro,

    I'm not sure quite what you mean. Do you just mean using load() in SKILL?

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago
    Hi Andrew,
    Imagine that I have a file with generic functions (for eg, read from files, write to files, etc) and I would like to not have them in my main code, but being able to call them whenever I need them. Is that possible ? Or, as you are suggesting, that is only a matter of using a load() command in my main code ?

    Best regards,
    Jose
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • skillUser
    skillUser over 8 years ago
    Hi Jose,

    Yes, you only need to load the functions one time and it shouldn't matter where from. You can set up functions to be autoloaded so that the file(s) that contain the function is loaded automatically when the function is called. You could also gather the core functions into a single context file (which could also be autoloaded, if you like) - loading the context file could be more efficient than loading one or more textual SKILL files.

    Best regards,
    Lawrence.
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago
    Hi Lawrence,
    Thank you for your answer.
    I don't want to bother all of you with my questions, but I have another problem.

    I have a text field which allows the user to enter "letters, numbers and the characters . _-" . I've done this using, as suggested by Andrew, the ?modifyCallback option.
    The default value for that text box is "File Name", but if you try to delete that in order to enter your own text, it will delete all the characters and leave one in the textbox, which cannot be deleted. For eg., if you try to delete all characters either "F" or "e" will remain there.
    Can you figure out what's wrong please ?

    Best regards,
    Jose


    fileName = hiCreateStringField(
    ?name 'fileName
    ?prompt "Summary file :"
    ?value "File name"
    ?editable t
    ?defValue "test.txt"
    ;?default "test.txt"
    ;?callback "ddsUpdateSyncWithForm( )"
    ?modifyCallback "cb_filterUserInput"
    ?invisible t ; this parameter will be set back to nil later in the code
    )


    ;==============================================================================
    ;===========cb_filterUserInput-"filter characters entered by the user" ========
    ;==============================================================================
    procedure(cb_filterUserInput(a b c)
    let((retValue regexOut)

    unless(getchar(b strlen(b))==nil
    regexOut=rexMatchp("^[A-Za-z0-9_.-]" getchar(b strlen(b))) ; don't allow any character besides alphabet _ . and -
    ) ; end unless

    if(regexOut==nil then
    retValue=substring(b 1 strlen(b)-1)
    else
    retValue=b
    ); end if

    ); end let
    );end procedure
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    The problem is because if the string is empty, you end up never setting regexOut so it has its default value of nil. Because of that, you end up in the substring branch of the final if, which will return nil - and because it returns nil, the original string is left unchanged.

    The solution is to change the let in the modify callback to:

    let((retValue (regexOut t))

    However, I'm not sure I'd do it this way, because if you click part way through the string and type one of these illegal characters, it will get accepted - your code only deals with characters at the end.

    I would probably do it this way:

    cb_filterUserInput.badChars=pcreCompile("[^\\w.-]")
    procedure(cb_filterUserInput(a b c)
      pcreReplace(cb_filterUserInput.badChars b "" 0)
    )

    For details on the regular expression, see "man perlre". All it means is any character that is not alphanumeric+_ (that's the \\w) or dot or hyphen.

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago
    Hi Andrew,
    I have one more problem.

    I have a selectorField in my code declared as follows:

    ; Directory Select allows user to select the directory where to save the files
    dataPath = hiCreateFileSelectorField(
    ?name 'dataPath
    ?mode 'directoryOnly
    ?prompt "Save the file to: "
    ?value "Please enter the path"
    ?defValue "~/Desktop/scripts/scriptOutputs"
    ?callback "validateDataPath()"
    ?editable nil
    ?invisible t
    )

    If I select any directory except root, the directory displayed in the textbox is correct, however if I choose the root or a directory that is directly under the root (eg. etc, dev, etc) I will get as output the value "./../../../../../" for root and "./../../../../../etc" for"etc" . However if I choose a directory that is another level below (eg. "/etc/fonts"), it will be displayed correctly.

    Can you help me please ?
    Best regards,
    Jose
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Hi Jose,

    If you want to resolve the path (i.e. not use relative components like this), just add:

    dataPath->hiSimplifyFilename=t

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago

    Hi Andrew,

    That didn't work for me. You see, when I hit the button "..." from the file selector, the box is filled incorrectly even if I remove the callback.  Moreover the previous version didn't have this problem.

    As I couldn't find a way to attach files to this message, I've pasted the code below (I am sorry for that) .

    Thanks in advance.

    Best regards,

    Jose

    Version 0v5 (old one)

    ;==============================================================================

    ;===============  Display main Form - Create Main form" ===================

    ;==============================================================================

    procedure(createMainForm()

       let((label1 doneButton cellView1 cellView2 selectButton1 selectButton2 selectButton3 sep1 myToggle temp)

       ; template loading and saving

       ; Directory Select allows user to select the directory where to save the files

       dataPath = hiCreateFileSelectorField(

         ?name 'dataPath

         ?mode 'directoryOnly

         ?prompt "Save the file to: "

         ?value "Please enter the path"

         ?defValue "~/Desktop/scripts/scriptOutputs"

         ?callback "validateDataPath()"

         ?editable nil

         ?invisible t

       )

       hiCreateAppForm(

    ?name 'settingsForm

    ?formTitle "Compare summary files"

    ?fields list(

       list(label1 10:10 600:0 40)

       list(sep1 0:35 600:0)

       list(cellView1 15:50 500:30 100)

       list(cellView2 15:85 500:30 100)

       list(selectButton1 520:50 50:30 30)

       list(selectButton2 520:85 50:30 30)

         list(selectButton3 120:120 90:30)

       list(myToggle 250:122 -1:-1) ; -1 indicates fields that aren't used, so they can take any value

       list(myToggle2 350:122 -1:-1) ; -1 indicates fields that aren't used, so they can take any value    

       list(dataPath 15:120 500:30 100)

       list(fileName 15:155 250:30 100)

    ) ; end list

       ) ; create form

       hiDisplayForm(settingsForm) ; Display form

    ); end let

    ); end procedure

    ;==============================================================================

    ;==============  validate data path "validateDataPath" ====================

    ;==============================================================================

    procedure(validateDataPath()

     let((myRadio1 myRadio2 txtStr parsedStr retValue)

         myDirStr=settingsForm->dataPath->value

         if((myDirStr!="Please enter path") && (myDirStr!="") then

    myDirStr=simplifyFilename(myDirStr) ; Expands myDirStr path

     ; if the path entered by the user doesn't end with "/" add it to the path      

     unless(substring(myDirStr strlen(myDirStr))=="/"

       myDirStr=strcat(myDirStr "/")

     )

     printf("\n myDirStr -> %s \n" myDirStr)

     if(isDir(myDirStr)==t then

         printf("Valid dir!\n")

         settingsForm->dataPath->value=myDirStr

         retValue="t"

     else

         printf("That's not a Valid dir !\n")

         settingsForm->dataPath->value=""

         retValue="nil"

     ) ; End if

     else

      myDirStr=""

    ) ; end if

     retValDataPath=retValue

     ) ; End let

    ) ; End Procedure

    Version 0v6 (new one)

    procedure(createMainForm()

       let((label1 doneButton cellView1 cellView2 selectButton1 selectButton2 selectButton3 sep1 myToggle temp)

       ; Directory Select allows user to select the directory where to save the files

       dataPath = hiCreateFileSelectorField(

         ?name 'dataPath

         ?mode 'directoryOnly

         ?prompt "Save the file to: "

         ?value "Please enter the path"

         ?defValue "~/Desktop/scripts/scriptOutputs"

         ?callback "validateDataPath()"

         ?editable nil

         ?invisible t

       )

       hiCreateAppForm(

    ?name 'settingsForm

    ?formTitle "Compare summary files"

    ?fields list(

       list(label1 10:10 600:0 40)

       list(sep1 0:35 600:0)

       list(cellView1 15:50 500:30 100)

       list(cellView2 15:85 500:30 100)

       list(selectButton1 520:50 50:30 30)

       list(selectButton2 520:85 50:30 30)

         list(selectButton3 120:120 90:30)

       list(myToggle 250:122 -1:-1) ; -1 indicates fields that aren't used, so they can take any value

       list(myToggle2 350:122 -1:-1) ; -1 indicates fields that aren't used, so they can take any value    

       list(dataPath 15:120 500:30 100)

       list(fileName 15:155 250:30 100)

    ) ; end list

       ) ; create form

       hiDisplayForm(settingsForm) ; Display form

    ); end let

    ); end procedure

    ;==============================================================================

    ;==============  validate data path "validateDataPath" ====================

    ;==============================================================================

    procedure(validateDataPath()

     let((myRadio1 myRadio2 txtStr parsedStr retValue myDirStr)

         myDirStr=settingsForm->dataPath->value

         if((myDirStr!="Please enter the path") && (myDirStr!="") then

    myDirStr=simplifyFilename(myDirStr) ; Expands myDirStr path

     ; if the path entered by the user doesn't end with "/" add it to the path      

     unless(substring(myDirStr strlen(myDirStr))=="/"

       myDirStr=strcat(myDirStr "/")

     )

     printf("\n myDirStr -> %s \n" myDirStr)

    ;if(isDir(myDirStr)==t then

     if((isDir(myDirStr)==t) && (isWritable(myDirStr)==t) then

         printf("Valid dir!\n")

         settingsForm->dataPath->value=myDirStr

         retValue="t"

     else

         printf("That's not a Valid dir or you don't have write permissions!\n")

     dispMessage("That's not a Valid dir or you don't have write permissions!\n")      

         ;settingsForm->dataPath->value=""

         retValue="nil"

     ) ; End if

     else

      myDirStr=""

    ) ; end if

      retValDataPath=retValue

     ) ; End let

    ) ; End Procedure

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Jose,

    You should be able to attach files via the rich text formatting interface (there's a little Insert/Edit Media icon). However, I have seen this break sometimes... (I've not checked today).

    I just checked your code. The reason why the new code breaks and the old code works is that your validateDataPath() function uses simplifyFilename() to resolve the relative path to a full path (in both cases). However, in the new version, it checks:

    if((isDir(myDirStr)==t) && (isWritable(myDirStr)==t) then
      printf("Valid dir!\n")
      settingsForm->dataPath->value=myDirStr
    ...

    In other words, it only updates the dataPath on the form if the path is a directory and it's writable. In the old version it didn't check whether it was writable. The settingsForm->dataPath->value=myDirStr is setting it to the simplified filename, and hence resolving the ../../../ etc.

    If in the new code I add:

    dataPath->hiSimplifyFilename=t

    immediately before the hiCreateAppForm() call - i.e. after you've created the field and stored it in the dataPath variable (which doesn't appear to be local, by the way; I assume that's an oversight), then it also solves the problem because the simplifyFilename is done at source regardless of what you do in your callback.

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
<

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information