#!/usr/bin/env python3
#
#--------------------------------------------------------
# Efabless Open Galaxy Project Manager GUI ported to
# open_pdks.
#
# This is a Python tkinter script that handles local
# project management.
#
#--------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# September 9, 2016
# Modifications 2017, 2018
# Updates 2021 by Max Chen
# Version 1.1
#--------------------------------------------------------

import sys
import io
import os
import re
import glob
import json
import signal
import shutil
import tarfile
import datetime
import tempfile
import subprocess
import contextlib
import faulthandler

import tkinter
from tkinter import ttk, StringVar, Listbox, END
from tkinter import filedialog

# Local imports

import tksimpledialog
import tooltip

from rename_project import rename_project_all
from consoletext import ConsoleText
from helpwindow import HelpWindow
from treeviewchoice import TreeViewChoice
from symbolbuilder import SymbolBuilder
from make_icon_from_soft import create_symbol
from profile import Profile

# Global variables

theProg = sys.argv[0]

deferLoad = True         # True: display GUI before (slow) loading of projects

# There must be exactly one instance of Tk; don't call again elsewhere.
root = tkinter.Tk()

# Name for design directory
designdir = 'design'

# Name for import directory
importdir = 'import'

# Name for cloudv directory
cloudvdir = 'cloudv'

# Name for archived imports project sub-directory
archiveimportdir = 'imported'

# Name for current design file
currdesign = '~/.open_pdks/currdesign'

# Name for personal preferences file
prefsfile = '~/.open_pdks/prefs.json'

# Application directory.
try:
    pdk_root = os.environ('PDK_ROOT')
except:
    pdk_root = 'PREFIX/pdk'

apps_path = pdk_root + '/scripts'

#---------------------------------------------------------------
# Watch a directory for modified time change.  Repeat every two
# seconds.  Call routine callback() if a change occurs
#---------------------------------------------------------------

class WatchClock(object):
    def __init__(self, parent, path, callback, interval=2000, interval0=None):
        self.parent = parent
        self.callback = callback
        self.path = path
        self.interval = interval
        if interval0 != None:
            self.interval0 = interval0
            self.restart(first=True)
        else:
            self.interval0 = interval
            self.restart()

    def query(self):
        for entry in self.path:
            statbuf = os.stat(entry)
            if statbuf.st_mtime > self.reftime:
                self.callback()
                self.restart()
                return
        self.timer = self.parent.after(self.interval, self.query)

    def stop(self):
        self.parent.after_cancel(self.timer)

    # if first: optionally use different (typically shorter) interval, AND DON'T
    # pre-record watched-dir mtime-s (which forces the callback on first timer fire)
    def restart(self, first=False):
        self.reftime = 0
        if not first:
            for entry in self.path:
                statbuf = os.stat(entry)
                if statbuf.st_mtime > self.reftime:
                    self.reftime = statbuf.st_mtime
        self.timer = self.parent.after(self.interval0 if first and self.interval0 != None else self.interval, self.query)

#------------------------------------------------------
# Dialog for generating a new layout
#------------------------------------------------------

class NewLayoutDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed=''):
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')

        self.l1prefs = tkinter.IntVar(master)
        self.l1prefs.set(1)
        ttk.Checkbutton(master, text='Populate new layout from netlist',
			variable = self.l1prefs).grid(row = 2, columnspan = 2, sticky = 'enws')

        return self

    def apply(self):
        return self.l1prefs.get

#------------------------------------------------------
# Simple dialog for entering project names
#------------------------------------------------------

class ProjectNameDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed=''):
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        ttk.Label(master, text='Enter new project name:').grid(row = 1, column = 0, sticky = 'wns')
        self.nentry = ttk.Entry(master)
        self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
        self.nentry.insert(0, seed)
        return self.nentry # initial focus

    def apply(self):
        return self.nentry.get()

class PadFrameCellNameDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed=''):
        description = 'PadFrame'       # TODO: make this an extra optional parameter of a generic CellNameDialog?
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        if description:
            description = description + " "
        else:
            description = ""
        ttk.Label(master, text=("Enter %scell name:" %(description))).grid(row = 1, column = 0, sticky = 'wns')
        self.nentry = ttk.Entry(master)
        self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
        self.nentry.insert(0, seed)
        return self.nentry # initial focus

    def apply(self):
        return self.nentry.get()

#------------------------------------------------------
# Dialog for copying projects.  Includes checkbox
# entries for preferences.
#------------------------------------------------------

class CopyProjectDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed=''):
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        ttk.Label(master, text="Enter new project name:").grid(row = 1, column = 0, sticky = 'wns')
        self.nentry = ttk.Entry(master)
        self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
        self.nentry.insert(0, seed)
        self.elprefs = tkinter.IntVar(master)
        self.elprefs.set(0)
        ttk.Checkbutton(master, text='Copy electric preferences (not recommended)',
			variable = self.elprefs).grid(row = 2, columnspan = 2, sticky = 'enws')
        self.spprefs = tkinter.IntVar(master)
        self.spprefs.set(0)
        ttk.Checkbutton(master, text='Copy ngspice folder (not recommended)',
			variable = self.spprefs).grid(row = 3, columnspan = 2, sticky = 'enws')
        return self.nentry # initial focus

    def apply(self):
        # Return a list containing the entry text and the checkbox states.
        elprefs = True if self.elprefs.get() == 1 else False
        spprefs = True if self.spprefs.get() == 1 else False
        return [self.nentry.get(), elprefs, spprefs]

#-------------------------------------------------------
# Not-Quite-So-Simple dialog for entering a new project.
# Select a project name and a PDK from a drop-down list.
#-------------------------------------------------------

class NewProjectDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed='', importnode=None, development=False, parent_pdk=''):
        global pdk_root
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        ttk.Label(master, text="Enter new project name:").grid(row = 1, column = 0)
        self.nentry = ttk.Entry(master)
        self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
        self.nentry.insert(0, seed or '')      # may be None
        self.pvar = tkinter.StringVar(master)
        if not importnode:
            # Add PDKs as found by searching /ef/tech for 'libs.tech' directories
            ttk.Label(master, text="Select foundry/node:").grid(row = 2, column = 0)
        else:
            ttk.Label(master, text="Foundry/node:").grid(row = 2, column = 0)
        self.infolabel = ttk.Label(master, text="", style = 'brown.TLabel', wraplength=250)
        self.infolabel.grid(row = 3, column = 0, columnspan = 2, sticky = 'news')
        self.pdkmap = {}
        self.pdkdesc = {}
        self.pdkstat = {}
        pdk_def = None

        node_def = importnode
        if not node_def:
            node_def = "EFXH035B"

        # use glob instead of os.walk. Don't need to recurse large PDK hier.
        # TODO: stop hardwired default EFXH035B: get from an overall flow /ef/tech/.ef-config/plist.json
        # (or get it from the currently selected project)
        #EFABLESS PLATFORM
        for pdkdir_lr in glob.glob(pdk_root + '/*/libs.tech/'):
            pdkdir = os.path.split( os.path.split( pdkdir_lr )[0])[0]    # discard final .../libs.tech/
            (foundry, foundry_name, node, desc, status) = ProjectManager.pdkdir2fnd( pdkdir )
            if not foundry or not node:
                continue
            key = foundry + '/' + node
            self.pdkmap[key] = pdkdir
            self.pdkdesc[key] = desc
            self.pdkstat[key] = status
            if node == node_def and not pdk_def:
                pdk_def = key
            
        # Quick hack:  sorting puts EFXH035A before EFXH035LEGACY.  However, some
        # ranking is needed.
        pdklist = sorted( self.pdkmap.keys())
        if not pdklist:
            raise ValueError( "assertion failed, no available PDKs found")
        pdk_def = (pdk_def or pdklist[0])

        if parent_pdk != '':
            pdk_def = parent_pdk
            
        self.pvar.set(pdk_def)

        # Restrict list to single entry if importnode was non-NULL and
        # is in the PDK list (OptionMenu is replaced by a simple label)
        # Otherwise, restrict the list to entries having an "status"
        # entry equal to "active".  This allows some legacy PDKs to be
	# disabled for creating new projects (but available for projects
        # that already have them).
        
        if importnode or parent_pdk != '':
            self.pdkselect = ttk.Label(master, text = pdk_def, style='blue.TLabel')
        else:
            pdkactive = list(item for item in pdklist if self.pdkstat[item] == 'active')
            if development:
                pdkactive.extend(list(item for item in pdklist if self.pdkstat[item] == 'development'))
            self.pdkselect = ttk.OptionMenu(master, self.pvar, pdk_def, *pdkactive,
    			style='blue.TMenubutton', command=self.show_info)
        self.pdkselect.grid(row = 2, column = 1)
        self.show_info(0)

        return self.nentry # initial focus

    def show_info(self, args):
        key = str(self.pvar.get())
        desc = self.pdkdesc[key]
        if desc == '':
            self.infolabel.config(text='(no description available)')
        else:
            self.infolabel.config(text=desc)

    def apply(self):
        return self.nentry.get(), self.pdkmap[ str(self.pvar.get()) ]  # Note converts StringVar to string

#----------------------------------------------------------------
# Not-Quite-So-Simple dialog for selecting an existing project.
# Select a project name from a drop-down list.  This could be
# replaced by simply using the selected (current) project.
#----------------------------------------------------------------

class ExistingProjectDialog(tksimpledialog.Dialog):
    def body(self, master, plist, seed, warning='Enter name of existing project to import into:'):
        ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')

        # Alphebetize list
        plist.sort()
        # Add projects
        self.pvar = tkinter.StringVar(master)
        self.pvar.set(plist[0])

        ttk.Label(master, text='Select project:').grid(row = 1, column = 0)

        self.projectselect = ttk.OptionMenu(master, self.pvar, plist[0], *plist, style='blue.TMenubutton')
        self.projectselect.grid(row = 1, column = 1, sticky = 'ewns')
        # pack version (below) hangs. Don't know why, changed to grid (like ProjectNameDialog)
        # self.projectselect.pack(side = 'top', fill = 'both', expand = 'true')
        return self.projectselect # initial focus

    def apply(self):
        return self.pvar.get()  # Note converts StringVar to string

#----------------------------------------------------------------
# Not-Quite-So-Simple dialog for selecting an existing ElecLib of existing project.
# Select an elecLib name from a drop-down list.
#----------------------------------------------------------------

class ExistingElecLibDialog(tksimpledialog.Dialog):
    def body(self, master, plist, seed):
        warning = "Enter name of existing Electric library to import into:"
        ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')

        # Alphebetize list
        plist.sort()
        # Add electric libraries
        self.pvar = tkinter.StringVar(master)
        self.pvar.set(plist[0])

        ttk.Label(master, text="Select library:").grid(row = 1, column = 0)

        self.libselect = ttk.OptionMenu(master, self.pvar, plist[0], *plist, style='blue.TMenubutton')
        self.libselect.grid(row = 1, column = 1)
        return self.libselect # initial focus

    def apply(self):
        return self.pvar.get()  # Note converts StringVar to string

#----------------------------------------------------------------
# Dialog for layout, in case of multiple layout names, none of
# which matches the project name (ip-name).  Method: Select a
# layout name from a drop-down list.  If there is no project.json
# file, add a checkbox for creating one and seeding the ip-name
# with the name of the selected layout.  Include entry for
# new layout, and for new layouts add a checkbox to import the
# layout from schematic or verilog, if a valid candidate exists.
#----------------------------------------------------------------

class EditLayoutDialog(tksimpledialog.Dialog):
    def body(self, master, plist, seed='', ppath='', pname='', warning='', hasnet=False):
        ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        self.ppath = ppath
        self.pname = pname

        # Checkbox variable
        self.confirm = tkinter.IntVar(master)
        self.confirm.set(0)

        # To-Do:  Add checkbox for netlist import

        # Alphebetize list
        plist.sort()
        # Add additional item for new layout
        plist.append('(New layout)')

        # Add layouts to list
        self.pvar = tkinter.StringVar(master)
        self.pvar.set(plist[0])

        ttk.Label(master, text='Selected layout to edit:').grid(row = 1, column = 0)

        if pname in plist:
            pseed = plist.index(pname)
        else:
            pseed = 0

        self.layoutselect = ttk.OptionMenu(master, self.pvar, plist[pseed], *plist,
				style='blue.TMenubutton', command=self.handle_choice)
        self.layoutselect.grid(row = 1, column = 1, sticky = 'ewns')

        # Create an entry form and checkbox for entering a new layout name, but
        # keep them unpacked unless the "(New layout)" selection is chosen.

        self.layoutbox = ttk.Frame(master)
        self.layoutlabel = ttk.Label(self.layoutbox, text='New layout name:')
        self.layoutlabel.grid(row = 0, column = 0, sticky = 'ewns')
        self.layoutentry = ttk.Entry(self.layoutbox)
        self.layoutentry.grid(row = 0, column = 1, sticky = 'ewns')
        self.layoutentry.insert(0, pname)

        # Only allow 'makeproject' checkbox if there is no project.json file
        jname = ppath + '/project.json'
        if not os.path.exists(jname):
            self.makeproject = ttk.Checkbutton(self.layoutbox,
			text='Make default project name',
			variable = self.confirm)
            self.makeproject.grid(row = 2, column = 0, columnspan = 2, sticky = 'ewns')
        return self.layoutselect # initial focus

    def handle_choice(self, event):
        if self.pvar.get() == '(New layout)':
            # Add entry and checkbox for creating ad-hoc project.json file
            self.layoutbox.grid(row = 1, column = 0, columnspan = 2, sticky = 'ewns')
        else:
            # Remove entry and checkbox
            self.layoutbox.grid_forget()
        return

    def apply(self):
        if self.pvar.get() == '(New layout)':
            if self.confirm.get() == 1:
                pname = self.pname
                master.create_ad_hoc_json(self.layoutentry.get(), pname)
            return self.layoutentry.get()
        else:
            return self.pvar.get()  # Note converts StringVar to string

#----------------------------------------------------------------
# Dialog for padframe: select existing ElecLib of existing project, type in a cellName.
#   Select an elecLib name from a drop-down list.
#   Text field for entry of a cellName.
#----------------------------------------------------------------

class ExistingElecLibCellDialog(tksimpledialog.Dialog):
    def body(self, master, descPre, seed='', descPost='', plist=None, seedLibNm=None, seedCellNm=''):
        warning = 'Pick existing Electric library; enter cell name'
        warning = (descPre or '') + ((descPre and ': ') or '') + warning + ((descPost and ' ') or '') + (descPost or '')
        ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')

        # Alphebetize list
        plist.sort()
        # Add electric libraries
        self.pvar = tkinter.StringVar(master)
        pNdx = 0
        if seedLibNm and seedLibNm in plist:
            pNdx = plist.index(seedLibNm)
        self.pvar.set(plist[pNdx])

        ttk.Label(master, text='Electric library:').grid(row = 1, column = 0, sticky = 'ens')
        self.libselect = ttk.OptionMenu(master, self.pvar, plist[pNdx], *plist, style='blue.TMenubutton')
        self.libselect.grid(row = 1, column = 1, sticky = 'wns')

        ttk.Label(master, text=('cell name:')).grid(row = 2, column = 0, sticky = 'ens')
        self.nentry = ttk.Entry(master)
        self.nentry.grid(row = 2, column = 1, sticky = 'ewns')
        self.nentry.insert(0, seedCellNm)

        return self.libselect # initial focus

    def apply(self):
        # return list of 2 strings: selected ElecLibName, typed-in cellName.
        return [self.pvar.get(), self.nentry.get()]  # Note converts StringVar to string

#------------------------------------------------------
# Simple dialog for confirming anything.
#------------------------------------------------------

class ConfirmDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed):
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        return self

    def apply(self):
        return 'okay'

#------------------------------------------------------
# More proactive dialog for confirming an invasive
# procedure like "delete project".  Requires user to
# click a checkbox to ensure this is not a mistake.
# confirmPrompt can be overridden, default='I am sure I want to do this.'
#------------------------------------------------------

class ProtectedConfirmDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed='', confirmPrompt=None):
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        self.confirm = tkinter.IntVar(master)
        self.confirm.set(0)
        if not confirmPrompt:
            confirmPrompt='I am sure I want to do this.'
        ttk.Checkbutton(master, text=confirmPrompt,
			variable = self.confirm).grid(row = 1, columnspan = 2, sticky = 'enws')
        return self

    def apply(self):
        return 'okay' if self.confirm.get() == 1 else ''

#------------------------------------------------------
# Simple dialog to say "blah is not implemented yet."
#------------------------------------------------------

class NotImplementedDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed):
        if not warning:
            warning = "Sorry, that feature is not implemented yet"
        if warning:
            warning = "Sorry, " + warning + ", is not implemented yet"
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        return self

    def apply(self):
        return 'okay'

#------------------------------------------------------
# (This is actually a generic confirm dialogue, no install/overwrite intelligence)
# But so far dedicated to confirming the installation of one or more files,
# with notification of which (if any) will overwrite existing files.
#
# The warning parameter is fully constructed by caller, as multiple lines as either:
#   For the import of module 'blah',
#   CONFIRM installation of (*: OVERWRITE existing):
#    * path1
#      path2
#      ....
# or:
#   For the import of module 'blah',
#   CONFIRM installation of:
#      path1
#      path2
#      ....
# TODO: bastardizes warning parameter as multiple lines. Implement some other way?
#------------------------------------------------------

class ConfirmInstallDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed):
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        return self

    def apply(self):
        return 'okay'

#------------------------------------------------------
# Dialog to import a project into the project manager
#------------------------------------------------------

class ImportDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed, parent_pdk, parent_path, project_dir):
        self.badrex1 = re.compile("^\.")
        self.badrex2 = re.compile(".*[/ \t\n\\\><\*\?].*")
        
        self.projectpath = ""
        self.project_pdkdir = ""
        self.foundry = ""
        self.node = ""
        self.parentpdk = parent_pdk
        self.parentpath = parent_path
        self.projectdir = project_dir #folder that contains all projects
        
        if warning:
            ttk.Label(master, text=warning, wraplength=250).grid(row = 0, columnspan = 2, sticky = 'wns')
        ttk.Label(master, text="Enter new project name:").grid(row = 1, column = 0)
        
        self.entry_v = tkinter.StringVar()
        
        self.nentry = ttk.Entry(master, textvariable = self.entry_v)
        self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
        
        self.entry_v.trace('w', self.text_validate)
        

        ttk.Button(master,
                        text = "Choose Project...",
                        command = self.browseFiles).grid(row = 3, column = 0)
                        
        self.pathlabel = ttk.Label(master, text = ("No project selected" if self.projectpath =="" else self.projectpath), style = 'red.TLabel', wraplength=300)
        
        self.pathlabel.grid(row = 3, column = 1)
        
        ttk.Label(master, text="Foundry/node:").grid(row = 4, column = 0)
        
        self.pdklabel = ttk.Label(master, text="N/A", style = 'red.TLabel')
        self.pdklabel.grid(row = 4, column = 1)
        
        self.importoption = tkinter.StringVar()
        
        self.importoption.set(("copy" if parent_pdk!='' else "link"))
        
        self.linkbutton = ttk.Radiobutton(master, text="Make symbolic link", variable=self.importoption, value="link")
        self.linkbutton.grid(row = 5, column = 0)
        ttk.Radiobutton(master, text="Copy project", variable=self.importoption, value="copy").grid(row = 5, column = 1)
        
        self.error_label = ttk.Label(master, text="", style = 'red.TLabel', wraplength=300)
        self.error_label.grid(row = 6, column = 0, columnspan = 2)
        
        self.entry_error = ttk.Label(master, text="", style = 'red.TLabel', wraplength=300)
        self.entry_error.grid(row = 2, column = 0, columnspan = 2)
        
        return self.nentry
    
    def text_validate(self, *args):
        newname = self.entry_v.get()
        projectpath = ''
        if self.parentpath!='':
            projectpath = self.parentpath + '/subcells/' + newname
        else:
            projectpath = self.projectdir + '/' + newname
             
        if ProjectManager.blacklisted( newname):
            self.entry_error.configure(text = newname + ' is not allowed for a project name.')
        elif newname == "":
            self.entry_error.configure(text = "")
        elif self.badrex1.match(newname):
            self.entry_error.configure(text =  'project name may not start with "."')
        elif self.badrex2.match(newname):
            self.entry_error.configure(text = 'project name contains illegal characters or whitespace.')
        elif os.path.exists(projectpath):
            self.entry_error.configure(text = newname + ' is already a project name.')
        else:
            self.entry_error.configure(text = '')
            return True
        return False
        
    def validate(self, *args):
        return self.text_validate(self) and self.pdk_validate(self)
        
    def browseFiles(self):
        initialdir = "~/"
        if os.path.isdir(self.projectpath):
            initialdir = os.path.split(self.projectpath)[0]
            
        selected_dir = filedialog.askdirectory(initialdir = initialdir, title = "Select a Project to Import",)
                                          
        if os.path.isdir(str(selected_dir)):
            self.error_label.configure(text = '')
            self.linkbutton.configure(state="normal")
            
            self.projectpath = selected_dir
            self.pathlabel.configure(text=self.projectpath, style = 'blue.TLabel')
            # Change label contents
            if (self.nentry.get() == ''):
                self.nentry.insert(0, os.path.split(self.projectpath)[1])
                
            self.pdk_validate(self)
    
    def pdk_validate(self, *args):
        if not os.path.exists(self.projectpath):
            self.error_label.configure(text = 'Invalid directory')
            return False
        
        if self.parentpath != "" and self.projectpath in self.parentpath:
            self.error_label.configure(text = 'Cannot import a parent directory into itself.')
            return False
        #Find project pdk
        if os.path.exists(self.projectpath + '/.config/techdir') or os.path.exists(self.projectpath + '/.ef-config/techdir'):
            self.project_pdkdir = os.path.realpath(self.projectpath + ProjectManager.config_path( self.projectpath) + '/techdir')
            self.foundry, foundry_name, self.node, desc, status = ProjectManager.pdkdir2fnd( self.project_pdkdir )
        else:
            if not os.path.exists(self.projectpath + '/info.yaml'):
                self.error_label.configure(text = self.projectpath + ' does not contain an info.yaml file.')
                self.project_pdkdir = ""
                self.foundry = ""
                self.node = ""
            else:                    
                self.project_pdkdir, self.foundry, self.node = ProjectManager.get_import_pdk( self.projectpath)
            
        if self.project_pdkdir == "":
            self.pdklabel.configure(text="Not found", style='red.TLabel')
            return False
        else:
            if (self.parentpdk!="" and self.parentpdk != self.foundry + '/' + self.node):
                self.importoption.set("copy")
                self.linkbutton.configure(state="disabled")
                self.error_label.configure(text = 'Warning: Parent project uses '+self.parentpdk+' instead of '+self.foundry + '/' + self.node+'. The imported project will be copied and cleaned.')
            self.pdklabel.configure(text=self.foundry + '/' + self.node, style='blue.TLabel')     
            return True
        
    
    def apply(self):
        return self.nentry.get(), self.project_pdkdir, self.projectpath, self.importoption.get()
    
#------------------------------------------------------
# Dialog to allow users to select a flow
#------------------------------------------------------
    
class SelectFlowDialog(tksimpledialog.Dialog):
    def body(self, master, warning, seed='', is_subproject = False):
        self.wait_visibility()
        if warning:
            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
        
        ttk.Label(master, text="Flow:").grid(row = 1, column = 0)
        
        project_flows = {
            'Analog':'Schematic, Simulation, Layout, DRC, LVS',
            'Digital':'Preparation, Synthesis, Placement, Static Timing Analysis, Routing, Post-Route STA, Migration, DRC, LVS, GDS, Cleanup',
            'Mixed-Signal':'',
            'Assembly':'',
        }
        
        subproject_flows = {
            'Analog':'Schematic, Simulation, Layout, DRC, LVS',
            'Digital':'Preparation, Synthesis, Placement, Static Timing Analysis, Routing, Post-Route STA, Migration, DRC, LVS, GDS, Cleanup',
            'Mixed-Signal': '',
        }
        self.flows = subproject_flows if is_subproject else project_flows
        self.flowvar = tkinter.StringVar(master, value = 'Analog')
        
        self.infolabel = ttk.Label(master, text=self.flows[self.flowvar.get()], style = 'brown.TLabel', wraplength=250)
        self.infolabel.grid(row = 2, column = 0, columnspan = 2, sticky = 'news')
        
        self.option_menu = ttk.OptionMenu(
            master,
            self.flowvar,
            self.flowvar.get(),
            *self.flows.keys(),
            command=self.show_info
        )
        
        self.option_menu.grid(row = 1, column = 1)

        return self.option_menu# initial focus
    
    def show_info(self, args):
        key = self.flowvar.get()
        print(key)
        desc = self.flows[key]
        if desc == '':
            self.infolabel.config(text='(no description available)')
        else:
            self.infolabel.config(text=desc)
    

    def apply(self):
        return str(self.flowvar.get())  # Note converts StringVar to string
        
#------------------------------------------------------
# Project Manager class
#------------------------------------------------------

class ProjectManager(ttk.Frame):
    """Project Management GUI."""

    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.root = parent
        parent.withdraw()
        self.update_idletasks()     # erase small initial frame asap
        self.init_gui()
        parent.protocol("WM_DELETE_WINDOW", self.on_quit)
        parent.deiconify()

    def on_quit(self):
        """Exits program."""
        quit()

    def init_gui(self):
        """Builds GUI."""
        global designdir
        global importdir
        global archiveimportdir
        global currdesign
        global theProg
        global deferLoad
        global apps_path

        message = []
        allPaneOpen = False
        prjPaneMinh = 10
        iplPaneMinh = 4
        impPaneMinh = 4

        # Read user preferences
        self.prefs = {}
        self.read_prefs()

        # Get default font size from user preferences
        fontsize = self.prefs['fontsize']

        s = ttk.Style()
        available_themes = s.theme_names()
        # print("themes: " + str(available_themes))
        s.theme_use(available_themes[0])

        s.configure('gray.TFrame', background='gray40')
        s.configure('blue_white.TFrame', bordercolor = 'blue', borderwidth = 3)
        s.configure('italic.TLabel', font=('Helvetica', fontsize, 'italic'))
        s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold italic'),
                        foreground = 'brown', anchor = 'center')
        s.configure('title2.TLabel', font=('Helvetica', fontsize, 'bold italic'),
                        foreground = 'blue')
        s.configure('normal.TLabel', font=('Helvetica', fontsize))
        s.configure('red.TLabel', font=('Helvetica', fontsize), foreground = 'red')
        s.configure('brown.TLabel', font=('Helvetica', fontsize), foreground = 'brown3', background = 'gray95')
        s.configure('green.TLabel', font=('Helvetica', fontsize), foreground = 'green3')
        s.configure('blue.TLabel', font=('Helvetica', fontsize), foreground = 'blue')
        s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
        s.configure('red.TButton', font=('Helvetica', fontsize), foreground = 'red', border = 3,
                        relief = 'raised')
        s.configure('green.TButton', font=('Helvetica', fontsize), foreground = 'green3', border = 3,
                        relief = 'raised')
        s.configure('blue.TMenubutton', font=('Helvetica', fontsize), foreground = 'blue', border = 3,
			relief = 'raised')

        # Create the help window
        self.help = HelpWindow(self, fontsize=fontsize)
        
        with io.StringIO() as buf, contextlib.redirect_stdout(buf):
            self.help.add_pages_from_file(apps_path + '/manager_help.txt')
            message = buf.getvalue()
        

        # Set the help display to the first page
        self.help.page(0)

        # Create the profile settings window
        self.profile = Profile(self, fontsize=fontsize)

        # Variables used by option menus
        self.seltype = tkinter.StringVar(self)
        self.cur_project = tkinter.StringVar(self)
        self.cur_import = "(nothing selected)"
        self.project_name = ""

        # Root window title
        self.root.title('Project Manager')
        self.root.option_add('*tearOff', 'FALSE')
        self.pack(side = 'top', fill = 'both', expand = 'true')

        pane = tkinter.PanedWindow(self, orient = 'vertical', sashrelief='groove', sashwidth=6)
        pane.pack(side = 'top', fill = 'both', expand = 'true')
        self.toppane = ttk.Frame(pane)
        self.botpane = ttk.Frame(pane)

        # All interior windows size to toppane
        self.toppane.columnconfigure(0, weight = 1)
        # Projects window resizes preferably to others
        self.toppane.rowconfigure(3, weight = 1)

        # Get username, and from it determine the project directory.
        # Save this path, because it gets used often.
        username = self.prefs['username']
        self.projectdir = os.path.expanduser('~/' + designdir)
        self.cloudvdir = os.path.expanduser('~/' + cloudvdir)

        # Check that the project directory exists, and create it if not
        if not os.path.isdir(self.projectdir):
            os.makedirs(self.projectdir)

        # Label with the user
        self.toppane.user_frame = ttk.Frame(self.toppane)
        self.toppane.user_frame.grid(row = 0, sticky = 'news')

        self.toppane.user_frame.title = ttk.Label(self.toppane.user_frame, text='User:', style='red.TLabel')
        self.toppane.user_frame.user = ttk.Label(self.toppane.user_frame, text=username, style='blue.TLabel')

        self.toppane.user_frame.title.pack(side = 'left', padx = 5)
        self.toppane.user_frame.user.pack(side = 'left', padx = 5)

        #---------------------------------------------
        ttk.Separator(self.toppane, orient='horizontal').grid(row = 1, sticky = 'news')
        #---------------------------------------------

        # List of projects:
        self.toppane.design_frame = ttk.Frame(self.toppane)
        self.toppane.design_frame.grid(row = 2, sticky = 'news')

        self.toppane.design_frame.design_header = ttk.Label(self.toppane.design_frame, text='Projects',
			style='title.TLabel')
        self.toppane.design_frame.design_header.pack(side = 'left', padx = 5)

        self.toppane.design_frame.design_header2 = ttk.Label(self.toppane.design_frame,
			text='(' + self.projectdir + '/)', style='normal.TLabel')
        self.toppane.design_frame.design_header2.pack(side = 'left', padx = 5)

        # Get current project from ~/.open_pdks/currdesign and set the selection.
        try:
            with open(os.path.expanduser(currdesign), 'r') as f:
                pdirCur = f.read().rstrip()
        except:
            pdirCur = None

        
        # Create listbox of projects
        projectlist = self.get_project_list() if not deferLoad else []
        height = min(10, max(prjPaneMinh, 2 + len(projectlist)))
        self.projectselect = TreeViewChoice(self.toppane, fontsize = fontsize,
		    deferLoad = deferLoad, selectVal = pdirCur, natSort = True)
        self.projectselect.populate("Available Projects:", projectlist,
			[["New", True, self.createproject],
			 ["Import", True, self.importproject],
			 ["Flow", False, self.startflow],
			 ["Copy", False, self.copyproject],
			 ["Rename", False, self.renameproject],
			 ["Delete", False, self.deleteproject]],
			height = height, columns = [0, 1])
        self.projectselect.grid(row = 3, sticky = 'news')
        self.projectselect.bindselect(self.setcurrent)

        tooltip.ToolTip(self.projectselect.get_button(0), text="Create a new project/subproject")
        tooltip.ToolTip(self.projectselect.get_button(1), text="Import a project/subproject")
        tooltip.ToolTip(self.projectselect.get_button(2), text="Start design flow")
        tooltip.ToolTip(self.projectselect.get_button(3), text="Make a copy of an entire project")
        tooltip.ToolTip(self.projectselect.get_button(4), text="Rename a project folder")
        tooltip.ToolTip(self.projectselect.get_button(5), text="Delete an entire project")

        pdklist = self.get_pdk_list(projectlist)
        self.projectselect.populate2("PDK", projectlist, pdklist)

        if pdirCur:
            try:
                curitem = next(item for item in projectlist if pdirCur == item)
            except StopIteration:
                pass
            else:
                if curitem:
                    self.projectselect.setselect(pdirCur)

        # Check that the import directory exists, and create it if not
        if not os.path.isdir(self.projectdir + '/' + importdir):
            os.makedirs(self.projectdir + '/' + importdir)

        # Create a watchdog on the project and import directories
        watchlist = [self.projectdir, self.projectdir + '/' + importdir]
        if os.path.isdir(self.projectdir + '/upload'):
            watchlist.append(self.projectdir + '/upload')
        
        # Check the creation time of the project manager app itself.  Because the project
        # manager tends to be left running indefinitely, it is important to know when it
        # has been updated.  This is checked once every hour since it is really expected
        # only to happen occasionally.

        thisapp = [theProg]
        self.watchself = WatchClock(self, thisapp, self.update_alert, 3600000)

        #---------------------------------------------

        # Add second button bar for major project applications
        self.toppane.apptitle = ttk.Label(self.toppane, text='Tools:', style='title2.TLabel')
        self.toppane.apptitle.grid(row = 4, sticky = 'news')
        self.toppane.appbar = ttk.Frame(self.toppane)
        self.toppane.appbar.grid(row = 5, sticky = 'news')

        # Define the application buttons and actions
        self.toppane.appbar.schem_button = ttk.Button(self.toppane.appbar, text='Edit Schematic',
		command=self.edit_schematic, style = 'normal.TButton')
        self.toppane.appbar.schem_button.pack(side = 'left', padx = 5)
        self.toppane.appbar.layout_button = ttk.Button(self.toppane.appbar, text='Edit Layout',
		command=self.edit_layout, style = 'normal.TButton')
        self.toppane.appbar.layout_button.pack(side = 'left', padx = 5)
        self.toppane.appbar.lvs_button = ttk.Button(self.toppane.appbar, text='Run LVS',
		command=self.run_lvs, style = 'normal.TButton')
        self.toppane.appbar.lvs_button.pack(side = 'left', padx = 5)
        self.toppane.appbar.char_button = ttk.Button(self.toppane.appbar, text='Characterize',
		command=self.characterize, style = 'normal.TButton')
        self.toppane.appbar.char_button.pack(side = 'left', padx = 5)
        self.toppane.appbar.synth_button = ttk.Button(self.toppane.appbar, text='Synthesis Flow',
		command=self.synthesize, style = 'normal.TButton')
        self.toppane.appbar.synth_button.pack(side = 'left', padx = 5)

        self.toppane.appbar.padframeCalc_button = ttk.Button(self.toppane.appbar, text='Pad Frame',
        	command=self.padframe_calc, style = 'normal.TButton')
        self.toppane.appbar.padframeCalc_button.pack(side = 'left', padx = 5)
        '''
        if self.prefs['schemeditor'] == 'xcircuit':
            tooltip.ToolTip(self.toppane.appbar.schem_button, text="Start 'XCircuit' schematic editor")
        elif self.prefs['schemeditor'] == 'xschem':
            tooltip.ToolTip(self.toppane.appbar.schem_button, text="Start 'XSchem' schematic editor")
        else:
            tooltip.ToolTip(self.toppane.appbar.schem_button, text="Start 'Electric' schematic editor")

        if self.prefs['layouteditor'] == 'klayout':
            tooltip.ToolTip(self.toppane.appbar.layout_button, text="Start 'KLayout' layout editor")
        else:
            tooltip.ToolTip(self.toppane.appbar.layout_button, text="Start 'Magic' layout editor")
        '''  
        self.refreshToolTips()
        
        tooltip.ToolTip(self.toppane.appbar.lvs_button, text="Start LVS tool")
        tooltip.ToolTip(self.toppane.appbar.char_button, text="Start Characterization tool")
        tooltip.ToolTip(self.toppane.appbar.synth_button, text="Start Digital Synthesis tool")
        tooltip.ToolTip(self.toppane.appbar.padframeCalc_button, text="Start Pad Frame Generator")

        #---------------------------------------------
        ttk.Separator(self.toppane, orient='horizontal').grid(row = 6, sticky = 'news')
        #---------------------------------------------
        # List of IP libraries:
        '''
        self.toppane.library_frame = ttk.Frame(self.toppane)
        self.toppane.library_frame.grid(row = 7, sticky = 'news')

        self.toppane.library_frame.library_header = ttk.Label(self.toppane.library_frame, text='IP Library:',
			style='title.TLabel')
        self.toppane.library_frame.library_header.pack(side = 'left', padx = 5)

        self.toppane.library_frame.library_header2 = ttk.Label(self.toppane.library_frame,
			text='(' + self.projectdir + '/ip/)', style='normal.TLabel')
        self.toppane.library_frame.library_header2.pack(side = 'left', padx = 5)

        self.toppane.library_frame.library_header3 = ttk.Button(self.toppane.library_frame,
		text=(allPaneOpen and '-' or '+'), command=self.library_toggle, style = 'normal.TButton', width = 2)
        self.toppane.library_frame.library_header3.pack(side = 'right', padx = 5)

        # Create listbox of IP libraries
        iplist = self.get_library_list() if not deferLoad else []
        height = min(8, max(iplPaneMinh, 2 + len(iplist)))
        self.ipselect = TreeViewChoice(self.toppane, fontsize=fontsize, deferLoad=deferLoad, natSort=True)
        self.ipselect.populate("IP Library:", iplist,
			[], height=height, columns=[0, 1], versioning=True)
        valuelist = self.ipselect.getvaluelist()
        datelist = self.get_date_list(valuelist)
        itemlist = self.ipselect.getlist()
        self.ipselect.populate2("date", itemlist, datelist)
        if allPaneOpen:
            self.library_open()
        

        #---------------------------------------------
        ttk.Separator(self.toppane, orient='horizontal').grid(row = 9, sticky = 'news')
        
        #---------------------------------------------
        # List of imports:
        self.toppane.import_frame = ttk.Frame(self.toppane)
        self.toppane.import_frame.grid(row = 10, sticky = 'news')

        self.toppane.import_frame.import_header = ttk.Label(self.toppane.import_frame, text='Imports:',
			style='title.TLabel')
        self.toppane.import_frame.import_header.pack(side = 'left', padx = 5)

        self.toppane.import_frame.import_header2 = ttk.Label(self.toppane.import_frame,
			text='(' + self.projectdir + '/import/)', style='normal.TLabel')
        self.toppane.import_frame.import_header2.pack(side = 'left', padx = 5)

        self.toppane.import_frame.import_header3 = ttk.Button(self.toppane.import_frame,
		text=(allPaneOpen and '-' or '+'), command=self.import_toggle, style = 'normal.TButton', width = 2)
        self.toppane.import_frame.import_header3.pack(side = 'right', padx = 5)

        # Create listbox of imports
        importlist = self.get_import_list() if not deferLoad else []
        self.number_of_imports = len(importlist) if not deferLoad else None
        height = min(8, max(impPaneMinh, 2 + len(importlist)))
        self.importselect = TreeViewChoice(self.toppane, fontsize=fontsize, markDir=True, deferLoad=deferLoad)
        self.importselect.populate("Pending Imports:", importlist,
			[["Import As", False, self.importdesign],
			["Import Into", False, self.importintodesign],
			["Delete", False, self.deleteimport]], height=height, columns=[0, 1])
        valuelist = self.importselect.getvaluelist()
        datelist = self.get_date_list(valuelist)
        itemlist = self.importselect.getlist()
        self.importselect.populate2("date", itemlist, datelist)

        tooltip.ToolTip(self.importselect.get_button(0), text="Import as a new project")
        tooltip.ToolTip(self.importselect.get_button(1), text="Import into an existing project")
        tooltip.ToolTip(self.importselect.get_button(2), text="Remove the import file(s)")
        if allPaneOpen:
            self.import_open()
        '''
        #---------------------------------------------
        # ttk.Separator(self, orient='horizontal').grid(column = 0, row = 8, columnspan=4, sticky='ew')
        #---------------------------------------------

        # Add a text window below the import to capture output.  Redirect
        # print statements to it.
        self.botpane.console = ttk.Frame(self.botpane)
        self.botpane.console.pack(side = 'top', fill = 'both', expand = 'true')

        self.text_box = ConsoleText(self.botpane.console, wrap='word', height = 4)
        self.text_box.pack(side='left', fill='both', expand = 'true')
        console_scrollbar = ttk.Scrollbar(self.botpane.console)
        console_scrollbar.pack(side='right', fill='y')
        # attach console to scrollbar
        self.text_box.config(yscrollcommand = console_scrollbar.set)
        console_scrollbar.config(command = self.text_box.yview)

        # Give all the expansion weight to the message window.
        # self.rowconfigure(9, weight = 1)
        # self.columnconfigure(0, weight = 1)

        # at bottom (legacy mode): window height grows by one row.
        # at top the buttons share a row with user name, reduce window height, save screen real estate.
        bottomButtons = False

        # Add button bar: at the bottom of window (legacy mode), or share top row with user-name
        if bottomButtons:
            bbar =  ttk.Frame(self.botpane)
            bbar.pack(side='top', fill = 'x')
        else:
            bbar =  self.toppane.user_frame

        # Define help button
        bbar.help_button = ttk.Button(bbar, text='Help',
		                      command=self.help.open, style = 'normal.TButton')

        # Define profile settings button
        bbar.profile_button = ttk.Button(bbar, text='Settings',
		                         command=self.profile.open, style = 'normal.TButton')

        # Define the "quit" button and action
        bbar.quit_button = ttk.Button(bbar, text='Quit', command=self.on_quit,
                                      style = 'normal.TButton')
        # Tool tips for button bar
        tooltip.ToolTip(bbar.quit_button, text="Exit the project manager")
        tooltip.ToolTip(bbar.help_button, text="Show help window")

        if bottomButtons:
            bbar.help_button.pack(side = 'left', padx = 5)
            bbar.profile_button.pack(side = 'left', padx = 5)
            bbar.quit_button.pack(side = 'right', padx = 5)
        else:
            # quit at TR like window-title's close; help towards the outside, settings towards inside
            bbar.quit_button.pack(side = 'right', padx = 5)
            bbar.help_button.pack(side = 'right', padx = 5)
            bbar.profile_button.pack(side = 'right', padx = 5)

        # Add the panes once the internal geometry is known
        pane.add(self.toppane)
        pane.add(self.botpane)
        pane.paneconfig(self.toppane, stretch='first')
        # self.update_idletasks()

        #---------------------------------------------------------------
        # Project list
        # projects = os.listdir(os.path.expanduser('~/' + designdir))
        # self.cur_project.set(projects[0])
        # self.design_select = ttk.OptionMenu(self, self.cur_project, projects[0], *projects,
        #		style='blue.TMenubutton')

        # New import list
        # self.import_select = ttk.Button(self, text=self.cur_import, command=self.choose_import)

        #---------------------------------------------------------
        # Define project design actions
        # self.design_actions = ttk.Frame(self)
        # self.design_actions.characterize = ttk.Button(self.design_actions,
        #  	text='Upload and Characterize', command=self.characterize)
        # self.design_actions.characterize.grid(column = 0, row = 0)

        # Define import actions
        # self.import_actions = ttk.Frame(self)
        # self.import_actions.upload = ttk.Button(self.import_actions,
        #	text='Upload Challenge', command=self.make_challenge)
        # self.import_actions.upload.grid(column = 0, row = 0)

        self.watchclock = WatchClock(self, watchlist, self.update_project_views, 2000,
                                     0 if deferLoad else None) # do immediate forced refresh (1st in mainloop)
        # self.watchclock = WatchClock(self, watchlist, self.update_project_views, 2000)

        # Redirect stdout and stderr to the console as the last thing to do. . .
        # Otherwise errors in the GUI get sucked into the void.
        self.stdout = sys.stdout
        self.stderr = sys.stderr
        sys.stdout = ConsoleText.StdoutRedirector(self.text_box)
        sys.stderr = ConsoleText.StderrRedirector(self.text_box)

        if message:
            print(message)

        if self.prefs == {}:
            print("No user preferences file, using default settings.")

    # helper for Profile to do live mods of some of the user-prefs (without restart projectManager):
    def setUsername(self, newname):
        self.toppane.user_frame.user.config(text=newname)
        
    def refreshToolTips(self):
        if self.prefs['schemeditor'] == 'xcircuit':
            tooltip.ToolTip(self.toppane.appbar.schem_button, text="Start 'XCircuit' schematic editor")
        elif self.prefs['schemeditor'] == 'xschem':
            tooltip.ToolTip(self.toppane.appbar.schem_button, text="Start 'XSchem' schematic editor")
        else:
            tooltip.ToolTip(self.toppane.appbar.schem_button, text="Start 'Electric' schematic editor")

        if self.prefs['layouteditor'] == 'klayout':
            tooltip.ToolTip(self.toppane.appbar.layout_button, text="Start 'KLayout' layout editor")
        else:
            tooltip.ToolTip(self.toppane.appbar.layout_button, text="Start 'Magic' layout editor")
    
    @classmethod
    def config_path(cls, path):
        #returns the config directory that 'path' contains between .config and .ef-config
        if (os.path.exists(path + '/.config')):
            return '/.config'
        elif (os.path.exists(path + '/.ef-config')):
            return '/.ef-config'
        raise Exception('Neither '+path+'/.config nor '+path+'/.ef-config exists.')

    #------------------------------------------------------------------------
    # Check if a name is blacklisted for being a project folder
    #------------------------------------------------------------------------
    
    @classmethod
    def blacklisted(cls, dirname):
        # Blacklist:  Do not show files of these names:
        blacklist = [importdir, 'ip', 'upload', 'export', 'lost+found', 'subcells']
        if dirname in blacklist:
            return True
        else:
            return False

    def write_prefs(self):
        global prefsfile

        if self.prefs:
            expprefsfile = os.path.expanduser(prefsfile)
            prefspath = os.path.split(expprefsfile)[0]
            if not os.path.exists(prefspath):
                os.makedirs(prefspath)
            with open(os.path.expanduser(prefsfile), 'w') as f:
                json.dump(self.prefs, f, indent = 4)

    def read_prefs(self):
        global prefsfile
        global apps_path

        # Set all known defaults even if they are not in the JSON file so
        # that it is not necessary to check for the existence of the keyword
        # in the dictionary every time it is accessed.
        if 'fontsize' not in self.prefs:
            self.prefs['fontsize'] = 11
        userid = os.environ['USER']
        uid = ''
        username = userid
        self.prefs['username'] = username
        
        '''
        if 'username' not in self.prefs:
            
            # 
            #EFABLESS PLATFORM
            p = subprocess.run(['/ef/apps/bin/withnet' ,
			apps_path + '/og_uid_service.py', userid],
			stdout = subprocess.PIPE)
            if p.stdout:
                uid_string = p.stdout.splitlines()[0].decode('utf-8')
                userspec = re.findall(r'[^"\s]\S*|".+?"', uid_string)
                if len(userspec) > 0:
                    username = userspec[0].strip('"')
                    # uid = userspec[1]
                    # Note userspec[1] = UID and userspec[2] = role, useful
                    # for future applications.
                else:
                    username = userid
            else:
                username = userid
            self.prefs['username'] = username
            # self.prefs['uid'] = uid
        '''
        if 'schemeditor' not in self.prefs:
            self.prefs['schemeditor'] = 'electric'

        if 'layouteditor' not in self.prefs:
            self.prefs['layouteditor'] = 'magic'

        if 'magic-graphics' not in self.prefs:
            self.prefs['magic-graphics'] = 'X11'

        if 'development' not in self.prefs:
            self.prefs['development'] = False

        if 'devstdcells' not in self.prefs:
            self.prefs['devstdcells'] = False

        # Any additional user preferences go above this line.

        # Get user preferences from ~/design/.profile/prefs.json and use it to
        # overwrite default entries in self.prefs
        try:
            with open(os.path.expanduser(prefsfile), 'r') as f:
                prefsdict = json.load(f)
                for key in prefsdict:
                    self.prefs[key] = prefsdict[key]
        except:
            # No preferences file, so create an initial one.
            if not os.path.exists(prefsfile):
                self.write_prefs()
        
        # if 'User:' Label exists, this updates it live (Profile calls read_prefs after write)
        try:
            self.setUsername(self.prefs['username'])
        except:
            pass

    #------------------------------------------------------------------------
    # Get a list of the projects in the user's design directory.  Exclude
    # items that are not directories, or which are blacklisted.
    #------------------------------------------------------------------------

    def get_project_list(self):
        global importdir

        badrex1 = re.compile("^\.")
        badrex2 = re.compile(".*[ \t\n].*")

        # Get contents of directory.  Look only at directories
     
        projectlist = []
        
        def add_projects(projectpath):
            # Recursively add subprojects to projectlist
            projectlist.append(projectpath)
            # Check for subprojects and add them
            if os.path.isdir(projectpath + '/subcells'):
                for subproj in os.listdir(projectpath + '/subcells'):
                    if os.path.isdir(projectpath + '/subcells/' + subproj):
                        add_projects(projectpath + '/subcells/' + subproj)
        
        for item in os.listdir(self.projectdir):
            if os.path.isdir(self.projectdir + '/' + item):
                projectpath = self.projectdir + '/' + item
                add_projects(projectpath)
         
                        
        # 'import' and others in the blacklist are not projects!
        # Files beginning with '.' and files with whitespace are
        # also not listed.
        for item in projectlist[:]:
            name = os.path.split(item)[1]
            if self.blacklisted(name):
                projectlist.remove(item)
            elif badrex1.match(name):
                projectlist.remove(item)
            elif badrex2.match(name):
                projectlist.remove(item)
        return projectlist

    #------------------------------------------------------------------------
    # Get a list of the projects in the user's cloudv directory.  Exclude
    # items that are not directories, or which are blacklisted.
    #------------------------------------------------------------------------

    def get_cloudv_project_list(self):
        global importdir

        badrex1 = re.compile("^\.")
        badrex2 = re.compile(".*[ \t\n].*")

        if not os.path.exists(self.cloudvdir):
            print('No user cloudv dir exists;  no projects to import.')
            return None

        # Get contents of cloudv directory.  Look only at directories
        projectlist = list(item for item in os.listdir(self.cloudvdir) if
			os.path.isdir(self.cloudvdir + '/' + item))

        # 'import' and others in the blacklist are not projects!
        # Files beginning with '.' and files with whitespace are
        # also not listed.
        for item in projectlist[:]:
            if self.blacklisted(item):
                projectlist.remove(item)
            elif badrex1.match(item):
                projectlist.remove(item)
            elif badrex2.match(item):
                projectlist.remove(item)

        # Add pathname to all items in projectlist
        projectlist = [self.cloudvdir + '/' + item for item in projectlist]
        return projectlist

    #------------------------------------------------------------------------
    # utility: [re]intialize a project's elec/ dir: the .java preferences and LIBDIRS.
    # So user can just delete .java, and restart electric (from projectManager), to reinit preferences.
    # So user can just delete LIBDIRS, and restart electric (from projectManager), to reinit LIBDIRS.
    # So project copies/imports can filter ngspice/run (and ../.allwaves), we'll recreate it here.
    #
    # The global /ef/efabless/deskel/* is used and the PDK name substituted.
    #
    # This SINGLE function is used to setup elec/ contents for new projects, in addition to being
    # called in-line prior to "Edit Schematics" (on-the-fly).
    #------------------------------------------------------------------------
    @classmethod
    def reinitElec(cls, design):
        pdkdir = os.path.join( design, ".ef-config/techdir")
        elec = os.path.join( design, "elec")

        # on the fly, ensure has elec/ dir, ensure has ngspice/run/allwaves dir
        try:
            os.makedirs(design + '/elec', exist_ok=True)
        except IOError as e:
            print('Error in os.makedirs(elec): ' + str(e))
        try:
            os.makedirs(design + '/ngspice/run/.allwaves', exist_ok=True)
        except IOError as e:
            print('Error in os.makedirs(.../.allwaves): ' + str(e))
        #EFABLESS PLATFORM
        deskel = '/ef/efabless/deskel'
        
        # on the fly:
        # .../elec/.java : reinstall if missing. From PDK-specific if any.
        if not os.path.exists( os.path.join( elec, '.java')):
            # Copy Electric preferences
            try:
                shutil.copytree(deskel + '/dotjava', design + '/elec/.java', symlinks = True)
            except IOError as e:
                print('Error copying files: ' + str(e))

        # .../elec/LIBDIRS : reinstall if missing, from PDK-specific LIBDIRS
        # in libs.tech/elec/LIBDIRS

        libdirsloc = pdkdir + '/libs.tech/elec/LIBDIRS'

        if not os.path.exists( os.path.join( elec, 'LIBDIRS')):
            if os.path.exists( libdirsloc ):
                # Copy Electric LIBDIRS
                try:
                    shutil.copy(libdirsloc, design + '/elec/LIBDIRS')
                except IOError as e:
                    print('Error copying files: ' + str(e))
            else:
                print('Info: PDK not configured for Electric: no libs.tech/elec/LIBDIRS')

        return None

    #------------------------------------------------------------------------
    # utility: filter a list removing: empty strings, strings with any whitespace
    #------------------------------------------------------------------------
    whitespaceREX = re.compile('\s')
    @classmethod
    def filterNullOrWS(cls, inlist):
        return [ i for i in inlist if i and not cls.whitespaceREX.search(i) ]

    #------------------------------------------------------------------------
    # utility: do a glob.glob of relative pattern, but specify the rootDir,
    # so returns the matching paths found below that rootDir.
    #------------------------------------------------------------------------
    @classmethod
    def globFromDir(cls, pattern, dir=None):
        if dir:
            dir = dir.rstrip('/') + '/'
            pattern = dir + pattern
        result = glob.glob(pattern)
        if dir and result:
            nbr = len(dir)
            result = [ i[nbr:] for i in result ]
        return result

    #------------------------------------------------------------------------
    # utility: from a pdkPath, return list of 3 strings: <foundry>, <node>, <description>.
    # i.e. pdkPath has form '[.../]<foundry>[.<ext>]/<node>'. For now the description
    # is always ''. And an optional foundry extension is pruned/dropped.
    # thus '.../XFAB.2/EFXP018A4' -> 'XFAB', 'EFXP018A4', ''
    #
    # optionally store in each PDK: .ef-config/nodeinfo.json which can define keys:
    # 'foundry', 'node', 'description' to override the foundry (computed from the path)
    # and (fixed, empty) description currently returned by this.
    #
    # Intent: keep a short-description field at least, intended to be one-line max 40 chars,
    # suitable for a on-hover-tooltip display. (Distinct from a big multiline description).
    #
    # On error (malformed pdkPath: can't determine foundry or node), the foundry or node
    # or both may be '' or as specified in the optional default values (if you're
    # generating something for display and want an unknown to appear as 'none' etc.).
    #------------------------------------------------------------------------
    @classmethod
    def pdkdir2fnd(cls, pdkdir, def_foundry='', def_node='', def_description=''):
        foundry = ''
        foundry_name = ''
        node = ''
        description = ''
        status = 'active'
        if pdkdir:
            # Code should only be for efabless platform
            '''
            split = os.path.split(os.path.realpath(pdkdir))
            # Full path should be [<something>/]<foundry>[.ext]/<node>
            node = split[1]
            foundry = os.path.split(split[0])[1]
            foundry = os.path.splitext(foundry)[0]
            '''
            # Check for nodeinfo.json
            infofile = pdkdir + '/.config/nodeinfo.json'
            if os.path.exists(infofile):
                with open(infofile, 'r') as ifile:
                    nodeinfo = json.load(ifile)
                if 'foundry' in nodeinfo:
                    foundry = nodeinfo['foundry']
                if 'foundry-name' in nodeinfo:
                    foundry_name = nodeinfo['foundry-name']
                if 'node' in nodeinfo:
                    node = nodeinfo['node']
                if 'description' in nodeinfo:
                    description = nodeinfo['description']
                if 'status' in nodeinfo:
                    status = nodeinfo['status']
                return foundry, foundry_name, node, description, status
            
            infofile = pdkdir + '/.ef-config/nodeinfo.json'
            if os.path.exists(infofile):
                with open(infofile, 'r') as ifile:
                    nodeinfo = json.load(ifile)
                if 'foundry' in nodeinfo:
                    foundry = nodeinfo['foundry']
                if 'foundry-name' in nodeinfo:
                    foundry_name = nodeinfo['foundry-name']
                if 'node' in nodeinfo:
                    node = nodeinfo['node']
                if 'description' in nodeinfo:
                    description = nodeinfo['description']
                if 'status' in nodeinfo:
                    status = nodeinfo['status']
                return foundry, foundry_name, node, description, status
        raise Exception('malformed pdkPath: can\'t determine foundry or node')

    #------------------------------------------------------------------------
    # Get a list of the electric-libraries (DELIB only) in a given project.
    # List of full-paths each ending in '.delib'
    #------------------------------------------------------------------------

    def get_elecLib_list(self, pname):
        elibs = self.globFromDir(pname + '/elec/*.delib/', self.projectdir)
        elibs = [ re.sub("/$", "", i) for i in elibs ]
        return self.filterNullOrWS(elibs)

    #------------------------------------------------------------------------
    # Create a list of datestamps for each import file
    #------------------------------------------------------------------------
    def get_date_list(self, valuelist):
        datelist = []
        for value in valuelist:
            try:
                importfile = value[0]
                try:
                    statbuf = os.stat(importfile)
                except:
                    # Note entries that can't be accessed.
                    datelist.append("(unknown)")
                else:
                    datestamp = datetime.datetime.fromtimestamp(statbuf.st_mtime)
                    datestr = datestamp.strftime("%c")
                    datelist.append(datestr)
            except:
                datelist.append("(N/A)")

        return datelist

    #------------------------------------------------------------------------
    # Get the PDK attached to a project for display as: '<foundry> : <node>'
    # unless path=True: then return true PDK dir-path.
    #
    # TODO: the ef-config prog output is not used below. Intent was use
    # ef-config to be the one official query for *any* project's PDK value, and
    # therein-only hide a built-in default for legacy projects without techdir symlink.
    # In below ef-config will always give an EF_TECHDIR, so that code-branch always
    # says '(default)', the ef-config subproc is wasted, and '(no PDK)' is never
    # reached.
    #------------------------------------------------------------------------
    def get_pdk_dir(self, project, path=False):
        pdkdir = os.path.realpath(project + self.config_path(project)+'/techdir')
        if path:
            return pdkdir
        foundry, foundry_name, node, desc, status = self.pdkdir2fnd( pdkdir )
        return foundry + ' : ' + node
        '''
        if os.path.isdir(project + '/.ef-config'):
            if os.path.exists(project + '/.ef-config/techdir'):
                pdkdir = os.path.realpath(project + '/.ef-config/techdir')
                
        elif os.path.isdir(project + '/.config'):
            if os.path.exists(project + '/.config/techdir'):
                pdkdir = os.path.realpath(project + '/.config/techdir')
                if path:
                    return pdkdir
                foundry, node, desc, status = self.pdkdir2fnd( pdkdir )
                return foundry + ' : ' + node
        '''
        '''
        if not pdkdir:
            # Run "ef-config" script for backward compatibility
            export = {'EF_DESIGNDIR': project}
            #EFABLESS PLATFORM
            p = subprocess.run(['/ef/efabless/bin/ef-config', '-sh', '-t'],
			stdout = subprocess.PIPE, env = export)
            config_out = p.stdout.splitlines()
            for line in config_out:
                setline = line.decode('utf-8').split('=')
                if setline[0] == 'EF_TECHDIR':
                    pdkdir = ( setline[1] if path else '(default)' )
            if not pdkdir:
                pdkdir = ( None if path else '(no PDK)' )    # shouldn't get here
        '''
        
        

        return pdkdir
#------------------------------------------------------------------------
    # Get PDK directory for projects without a techdir (most likely the project is being imported)
    #------------------------------------------------------------------------
    @classmethod
    def get_import_pdk(cls, projectpath):
        print(projectpath)
        yamlname = projectpath + '/info.yaml'
       
        with open(yamlname, 'r') as f:
            datatop = yaml.safe_load(f)
            project_data = datatop['project']
            project_foundry = project_data['foundry']
            project_process = project_data['process']
                
        project_pdkdir = ''
       
        for pdkdir_lr in glob.glob('/usr/share/pdk/*/libs.tech/'):
            pdkdir = os.path.split( os.path.split( pdkdir_lr )[0])[0]
            foundry, foundry_name, node, desc, status = ProjectManager.pdkdir2fnd( pdkdir )
            if not foundry or not node:
                continue
            if (foundry == project_foundry or foundry_name == project_foundry) and node == project_process:
                project_pdkdir = pdkdir
                break
          
        return project_pdkdir, foundry, node #------------------------------------------------------------------------
    # Get the list of PDKs that are attached to each project
    #------------------------------------------------------------------------
    def get_pdk_list(self, projectlist):
        pdklist = []
        for project in projectlist:
            pdkdir = self.get_pdk_dir(project)
            pdklist.append(pdkdir)
            
        return pdklist

    #------------------------------------------------------------------------
    # Find a .json's associated tar.gz (or .tgz) if any.
    # Return path to the tar.gz if any, else None.
    #------------------------------------------------------------------------

    def json2targz(self, jsonPath):
        root = os.path.splitext(jsonPath)[0]
        for ext in ('.tgz', '.tar.gz'):
            if os.path.isfile(root + ext):
                return root + ext
        return None
        
    def yaml2targz(self, yamlPath):
        root = os.path.splitext(yamlPath)[0]
        for ext in ('.tgz', '.tar.gz'):
            if os.path.isfile(root + ext):
                return root + ext
        return None

    #------------------------------------------------------------------------
    # Remove a .json and associated tar.gz (or .tgz) if any.
    # If not a .json, remove just that file (no test for a tar).
    #------------------------------------------------------------------------

    def removeJsonPlus(self, jsonPath):
        ext = os.path.splitext(jsonPath)[1]
        if ext == ".json":
            tar = self.json2targz(jsonPath)
            if tar: os.remove(tar)
        return os.remove(jsonPath)

    #------------------------------------------------------------------------
    # MOVE a .json and associated tar.gz (or .tgz) if any, to targetDir.
    # If not a .json, move just that file (no test for a tar).
    #------------------------------------------------------------------------

    def moveJsonPlus(self, jsonPath, targetDir):
        ext = os.path.splitext(jsonPath)[1]
        if ext == ".json":
            tar = self.json2targz(jsonPath)
            if tar:
                shutil.move(tar,      targetDir)
        # believe the move throws an error. So return value (the targetDir name) isn't really useful.
        return  shutil.move(jsonPath, targetDir)

    #------------------------------------------------------------------------
    # Get a list of the libraries in the user's ip folder
    #------------------------------------------------------------------------

    def get_library_list(self):
        # Get contents of directory
        try:
            iplist = glob.glob(self.projectdir + '/ip/*/*')
        except:
            iplist = []
        else:
            pass
      
        return iplist

    #------------------------------------------------------------------------
    # Get a list of the files in the user's design import folder
    # (use current 'import' but also original 'upload')
    #------------------------------------------------------------------------

    def get_import_list(self):
        # Get contents of directory
        importlist = os.listdir(self.projectdir + '/' + importdir)

        # If entries have both a .json and .tar.gz file, remove the .tar.gz (also .tgz).
        # Also ignore any .swp files dropped by the vim editor.
        # Also ignore any subdirectories of import
        for item in importlist[:]:
            if item[-1] in '#~':
                importlist.remove(item)
                continue
            ipath = self.projectdir + '/' + importdir + '/' + item

            # recognize dirs (as u2u projects) if not symlink and has a 'project.json',
            # hide dirs named *.bak. If originating user does u2u twice before target user
            # can consume/import it, the previous one (only) is retained as *.bak.
            if os.path.isdir(ipath):
                if os.path.islink(ipath) or not self.validProjectName(item) \
                   or self.importProjNameBadrex1.match(item) \
                   or not os.path.isfile(ipath + '/info.yaml'):
                    importlist.remove(item)
                    continue
            else:
                ext = os.path.splitext(item)
                if ext[1] == '.json':
                    if ext[0] + '.tar.gz' in importlist:
                        importlist.remove(ext[0] + '.tar.gz')
                    elif ext[0] + '.tgz' in importlist:
                        importlist.remove(ext[0] + '.tgz')
                elif ext[1] == '.swp':
                    importlist.remove(item)
                elif os.path.isdir(self.projectdir + '/' + importdir + '/' + item):
                    importlist.remove(item)

        # Add pathname to all items in projectlist
        importlist = [self.projectdir + '/' + importdir + '/' + item for item in importlist]

        # Add support for original "upload" directory (backward compatibility)
        if os.path.exists(self.projectdir + '/upload'):
            uploadlist = os.listdir(self.projectdir + '/upload')

            # If entries have both a .json and .tar.gz file, remove the .tar.gz (also .tgz).
            # Also ignore any .swp files dropped by the vim editor.
            for item in uploadlist[:]:
                ext = os.path.splitext(item)
                if ext[1] == '.json':
                    if ext[0] + '.tar.gz' in uploadlist:
                        uploadlist.remove(ext[0] + '.tar.gz')
                    elif ext[0] + '.tgz' in uploadlist:
                        uploadlist.remove(ext[0] + '.tgz')
                elif ext[1] == '.swp':
                    uploadlist.remove(item)

            # Add pathname to all items in projectlist
            uploadlist = [self.projectdir + '/upload/' + item for item in uploadlist]
            importlist.extend(uploadlist)

        # Remember the size of the list so we know when it changed
        self.number_of_imports = len(importlist)
        return importlist 

    #------------------------------------------------------------------------
    # Import for json documents and related tarballs (.gz or .tgz):  
    #------------------------------------------------------------------------

    def importyaml(self, projname, importfile):
        # (1) Check if there is a tarball with the same root name as the JSON
        importroot = os.path.splitext(importfile)[0]
        badrex1 = re.compile("^\.")
        badrex2 = re.compile(".*[/ \t\n\\\><\*\?].*")
        if os.path.isfile(importroot + '.tgz'):
           tarname = importroot + '.tgz'
        elif os.path.isfile(importroot + '.tar.gz'):
           tarname = importroot + '.tar.gz'
        else:
           tarname = []
        # (2) Check for name conflict
        origname = projname
        newproject = self.projectdir + '/' + projname
        newname = projname
        while os.path.isdir(newproject) or self.blacklisted(newname):
            if self.blacklisted(newname):
                warning = "Name " + newname + " is not allowed for a project name."
            elif badrex1.match(newname):
                warning = 'project name may not start with "."'
            elif badrex2.match(newname):
                warning = 'project name contains illegal characters or whitespace.'
            else:
                warning = "Project " + newname + " already exists!"
            newname = ProjectNameDialog(self, warning, seed=newname).result
            if not newname:
                return 0	# Canceled, no action.
            newproject = self.projectdir + '/' + newname
        print("New project name is " + newname + ".")
        # (3) Create new directory
        os.makedirs(newproject)
        # (4) Dump the tarball (if any) in the new directory
        if tarname:
            with tarfile.open(tarname, mode='r:gz') as archive:
                for member in archive:
                    archive.extract(member, newproject)
        # (5) Copy the YAML document into the new directory.  Keep the
        # original name of the project, so as to overwrite any existing
        # document, then change the name to match that of the project
        # folder.

        yamlfile = newproject + '/info.yaml'

        try:
            shutil.copy(importfile, yamlfile)
        except IOError as e:
            print('Error copying files: ' + str(e))
            return None

        # (6) Remove the original files from the import folder
        os.remove(importfile)
        if tarname:
            os.remove(tarname)

        # (7) Standard project setup:  if spi/, elec/, and ngspice/ do not
        # exist, create them.  If elec/.java does not exist, create it and
        # seed from deskel.  If ngspice/run and ngspice/run/.allwaves do not
        # exist, create them.

        if not os.path.exists(newproject + '/spi'):
            os.makedirs(newproject + '/spi')
        if not os.path.exists(newproject + '/spi/pex'):
            os.makedirs(newproject + '/spi/pex')
        if not os.path.exists(newproject + '/spi/lvs'):
            os.makedirs(newproject + '/spi/lvs')
        if not os.path.exists(newproject + '/ngspice'):
            os.makedirs(newproject + '/ngspice')
        if not os.path.exists(newproject + '/ngspice/run'):
            os.makedirs(newproject + '/ngspice/run')
        if not os.path.exists(newproject + '/ngspice/run/.allwaves'):
            os.makedirs(newproject + '/ngspice/run/.allwaves')
        if not os.path.exists(newproject + '/elec'):
            os.makedirs(newproject + '/elec')
        if not os.path.exists(newproject + '/xcirc'):
            os.makedirs(newproject + '/xcirc')
        if not os.path.exists(newproject + '/mag'):
            os.makedirs(newproject + '/mag')

        self.reinitElec(newproject)   # [re]install elec/.java, elec/LIBDIRS if needed, from pdk-specific if-any

        return 1	# Success

    #------------------------------------------------------------------------
    # Import for netlists (.spi):
    # (1) Request project name
    # (2) Create new project if name does not exist, or
    #     place netlist in existing project if it does.
    #------------------------------------------------------------------------

    #--------------------------------------------------------------------
    # Install netlist in electric:
    # "importfile" is the filename in ~/design/import
    # "pname" is the name of the target project (folder)
    # "newfile" is the netlist file name (which may or may not be the same
    #     as 'importfile').
    #--------------------------------------------------------------------

    def install_in_electric(self, importfile, pname, newfile, isnew=True):
        #--------------------------------------------------------------------
        # Install the netlist.
        # If netlist is CDL, then call cdl2spi first
        #--------------------------------------------------------------------

        newproject = self.projectdir + '/' + pname
        if not os.path.isdir(newproject + '/spi/'):
            os.makedirs(newproject + '/spi/')
        if os.path.splitext(newfile)[1] == '.cdl':
            if not os.path.isdir(newproject + '/cdl/'):
                os.makedirs(newproject + '/cdl/')
            shutil.copy(importfile, newproject + '/cdl/' + newfile)
            try:
                p = subprocess.run(['/ef/apps/bin/cdl2spi', importfile],
			stdout = subprocess.PIPE, stderr = subprocess.PIPE,
			check = True)
            except subprocess.CalledProcessError as e:
                print('Error running cdl2spi: ' + e.output.decode('utf-8'))
                if isnew == True:
                    shutil.rmtree(newproject)
                return None
            else:
                spi_string = p.stdout.splitlines()[0].decode('utf-8')
                if p.stderr:
                    err_string = p.stderr.splitlines()[0].decode('utf-8')
                    # Print error messages to console
                    print(err_string)
            if not spi_string:
                print('Error: cdl2spi has no output')
                if isnew == True:
                    shutil.rmtree(newproject)
                return None
            outname = os.path.splitext(newproject + '/spi/' + newfile)[0] + '.spi'
            with open(outname, 'w') as f:
                f.write(spi_string)
        else:
            outname = newproject + '/spi/' + newfile
            try:
                shutil.copy(importfile, outname)
            except IOError as e:
                print('Error copying files: ' + str(e))
                if isnew == True:
                    shutil.rmtree(newproject)
                return None

        #--------------------------------------------------------------------
        # Symbol generator---this code to be moved into its own def.
        #--------------------------------------------------------------------
        # To-do, need a more thorough SPICE parser, maybe use netgen to parse.
        # Need to find topmost subcircuit, by parsing the hieararchy.
        subcktrex = re.compile('\.subckt[ \t]+([^ \t]+)[ \t]+', re.IGNORECASE)
        subnames = []
        with open(importfile, 'r') as f:
            for line in f:
                lmatch = subcktrex.match(line)
                if lmatch:
                    subnames.append(lmatch.group(1))

        if subnames:
            subname = subnames[0]

        # Run cdl2icon perl script
        try:
            p = subprocess.run(['/ef/apps/bin/cdl2icon', '-file', importfile, '-cellname',
			subname, '-libname', pname, '-projname', pname, '--prntgussddirs'],
			stdout = subprocess.PIPE, stderr = subprocess.PIPE, check = True)
        except subprocess.CalledProcessError as e:
            print('Error running cdl2spi: ' + e.output.decode('utf-8'))
            return None
        else:
            pin_string = p.stdout.splitlines()[0].decode('utf-8')
            if not pin_string:
                print('Error: cdl2icon has no output')
                if isnew == True:
                    shutil.rmtree(newproject)
                return None
            if p.stderr:
                err_string = p.stderr.splitlines()[0].decode('utf-8')
                print(err_string)

        # Invoke dialog to arrange pins here
        pin_info_list = SymbolBuilder(self, pin_string.split(), fontsize=self.prefs['fontsize']).result
        if not pin_info_list:
            # Dialog was canceled
            print("Symbol builder was canceled.")
            if isnew == True:
                shutil.rmtree(newproject)
            return 0

        for pin in pin_info_list:
            pin_info = pin.split(':')
            pin_name = pin_info[0]
            pin_type = pin_info[1]

        # Call cdl2icon with the final pin directions
        outname = newproject + '/elec/' + pname + '.delib/' + os.path.splitext(newfile)[0] + '.ic'
        try:
            p = subprocess.run(['/ef/apps/bin/cdl2icon', '-file', importfile, '-cellname',
			subname, '-libname', pname, '-projname', pname, '-output',
			outname, '-pindircmbndstring', ','.join(pin_info_list)],
			stdout = subprocess.PIPE, stderr = subprocess.PIPE, check = True)
        except subprocess.CalledProcessError as e:
            print('Error running cdl2icon: ' + e.output.decode('utf-8'))
            if isnew == True:
                shutil.rmtree(newproject)
            return None
        else:
            icon_string = p.stdout.splitlines()[0].decode('utf-8')   # not used, AFAIK
            if p.stderr:
                err_string = p.stderr.splitlines()[0].decode('utf-8')
                print(err_string)

        return 1	# Success

    #------------------------------------------------------------------------
    # Import netlist file into existing project
    #------------------------------------------------------------------------

    def importspiceinto(self, newfile, importfile):
        # Require existing project location
        ppath = ExistingProjectDialog(self, self.get_project_list()).result
        if not ppath:
            return 0		# Canceled in dialog, no action.
        pname = os.path.split(ppath)[1]
        print("Importing into existing project " + pname)
        result = self.install_in_electric(importfile, pname, newfile, isnew=False)
        if result == None:
            print('Error during import.')
            return None
        elif result == 0:
            return 0    # Canceled
        else:
            # Remove original file from imports area
            os.remove(importfile)
            return 1    # Success

    #------------------------------------------------------------------------
    # Import netlist file as a new project
    #------------------------------------------------------------------------

    def importspice(self, newfile, importfile):
        # Use create project code first to generate a valid project space.
        newname = self.createproject(None)
        if not newname:
            return 0		# Canceled in dialog, no action.
        print("Importing as new project " + newname + ".")
        result = self.install_in_electric(importfile, newname, newfile, isnew=True)
        if result == None:
            print('Error during install')
            return None
        elif result == 0: 
            # Canceled, so do not remove the import
            return 0
        else: 
            # Remove original file from imports area
            os.remove(importfile)
            return 1    # Success

    #------------------------------------------------------------------------
    # Determine if JSON's tar can be imported as-if it were just a *.v.
    # This is thin wrapper around tarVglImportable. Find the JSON's associated
    # tar.gz if any, and call tarVglImportable.
    # Returns list of two:
    #   None if rules not satisified; else path of the single GL .v member.
    #   None if rules not satisified; else root-name of the single .json member.
    #------------------------------------------------------------------------

    def jsonTarVglImportable(self, path):
        ext = os.path.splitext(path)[1]
        if ext != '.json': return None, None, None

        tar = self.json2targz(path)
        if not tar: return None, None, None

        return self.tarVglImportable(tar)
    
    def yamlTarVglImportable(self, path):
        ext = os.path.splitext(path)[1]
        if ext != '.yaml': return None, None, None

        tar = self.yaml2targz(path)
        if not tar: return None, None, None

        return self.tarVglImportable(tar)
    #------------------------------------------------------------------------
    # Get a single named member (memPath) out of a JSON's tar file.
    # This is thin wrapper around tarMember2tempfile. Find the JSON's associated
    # tar.gz if any, and call tarMember2tempfile.
    #------------------------------------------------------------------------

    def jsonTarMember2tempfile(self, path, memPath):
        ext = os.path.splitext(path)[1]
        if ext != '.json': return None

        tar = self.json2targz(path)
        if not tar: return None

        return self.tarMember2tempfile(tar, memPath)
        
    def yamlTarMember2tempfile(self, path, memPath):
        ext = os.path.splitext(path)[1]
        if ext != '.yaml': return None

        tar = self.yaml2targz(path)
        if not tar: return None

        return self.tarMember2tempfile(tar, memPath)

    #------------------------------------------------------------------------
    # Determine if tar-file can be imported as-if it were just a *.v.
    # Require exactly one yosys-output .netlist.v, and exactly one .json.
    # Nothing else matters: Ignore all other *.v, *.tv, *.jelib, *.vcd...
    #
    # If user renames *.netlist.v in cloudv before export to not end in
    # netlist.v, we won't recognize it.
    #
    # Returns list of two:
    #   None if rules not satisified; else path of the single GL netlist.v member.
    #   None if rules not satisified; else root-name of the single .json member.
    #------------------------------------------------------------------------

    def tarVglImportable(self, path):
        # count tar members by extensions. Track the .netlist.v. and .json. Screw the rest.
        nbrExt = {'.v':0, '.netlist.v':0, '.tv':0, '.jelib':0, '.json':0, '/other/':0, '/vgl/':0}
        nbrGLv = 0
        jname = None
        vfile = None
        node = None
        t = tarfile.open(path)
        for i in t:
            # ignore (without counting) dir entries. From cloudv (so far) the tar does not
            # have dir-entries, but most tar do (esp. most manually made test cases).
            if i.isdir():
                continue
            # TODO: should we require all below counted files to be plain files (no symlinks etc.)?
            # get extension, but recognize a multi-ext for .netlist.v case
            basenm = os.path.basename(i.name)
            ext = os.path.splitext(basenm)[1]
            root = os.path.splitext(basenm)[0]
            ext2 = os.path.splitext(root)[1]
            if ext2 == '.netlist' and ext == '.v':
                ext = ext2 + ext
            if ext and ext not in nbrExt:
                ext = '/other/'
            elif ext == '.netlist.v' and self.tarMemberIsGLverilog(t, i.name):
                vfile = i.name
                ext = '/vgl/'
            elif ext == '.json':
                node = self.tarMemberHasFoundryNode(t, i.name)
                jname = root
            nbrExt[ext] += 1

        # check rules. Require exactly one yosys-output .netlist.v, and exactly one .json.
        # Quantities of other types are all don't cares.
        if (nbrExt['/vgl/'] == 1 and nbrExt['.json'] == 1):
            # vfile is the name of the verilog netlist in the tarball, while jname
            # is the root name of the JSON file found in the tarball (if any) 
            return vfile, jname, node

        # failed, not gate-level-verilog importable:
        return None, None, node


    #------------------------------------------------------------------------
    # OBSOLETE VERSION: Determine if tar-file can be imported as-if it were just a *.v.
    # Rules for members: one *.v, {0,1} *.jelib, {0,1} *.json, 0 other types.
    # Return None if rules not satisified; else return path of the single .v.
    #------------------------------------------------------------------------
    #
    # def tarVglImportable(self, path):
    #     # count tar members by extensions. Track the .v.
    #     nbrExt = {'.v':0, '.jelib':0, '.json':0, 'other':0}
    #     vfile = ""
    #     t = tarfile.open(path)
    #     for i in t:
    #         ext = os.path.splitext(i.name)[1]
    #         if ext not in nbrExt:
    #             ext = 'other'
    #         nbrExt[ext] += 1
    #         if ext == ".v": vfile = i.name
    #
    #     # check rules.
    #     if (nbrExt['.v'] != 1 or nbrExt['other'] != 0 or
    #         nbrExt['.jelib'] > 1 or nbrExt['.json'] > 1):
    #         return None
    #     return vfile

    #------------------------------------------------------------------------
    # Get a single named member (memPath) out of a tar file (tarPath), into a
    # temp-file, so subprocesses can process it.
    # Return path to the temp-file, or None if member not found in the tar.
    #------------------------------------------------------------------------

    def tarMember2tempfile(self, tarPath, memPath):
        t = tarfile.open(tarPath)
        member = t.getmember(memPath)
        if not member: return None

        # Change member.name so it extracts into our new temp-file.
        # extract() can specify the root-dir befow which the member path
        # resides. If temp is an absolute-path, that root-dir must be /.
        tmpf1 = tempfile.NamedTemporaryFile(delete=False)
        if tmpf1.name[0] != "/":
            raise ValueError("assertion failed, temp-file path not absolute: %s" % tmpf1.name)
        member.name = tmpf1.name
        t.extract(member,"/")

        return tmpf1.name

    #------------------------------------------------------------------------
    # Create an electric .delib directory and seed it with a header file
    #------------------------------------------------------------------------

    def create_electric_header_file(self, project, libname):
        if not os.path.isdir(project + '/elec/' + libname + '.delib'):
            os.makedirs(project + '/elec/' + libname + '.delib')

        p = subprocess.run(['electric', '-v'], stdout=subprocess.PIPE)
        eversion = p.stdout.splitlines()[0].decode('utf-8')
        # Create header file
        with open(project + '/elec/' + libname + '.delib/header', 'w') as f:
            f.write('# header information:\n')
            f.write('H' + libname + '|' + eversion + '\n\n')
            f.write('# Tools:\n')
            f.write('Ouser|DefaultTechnology()Sschematic\n')
            f.write('Osimulation|VerilogUseAssign()BT\n')
            f.write('C____SEARCH_FOR_CELL_FILES____\n')

    #------------------------------------------------------------------------
    # Create an ad-hoc "project.json" dictionary and fill essential records
    #------------------------------------------------------------------------

    def create_ad_hoc_json(self, ipname, pname):
        # Create ad-hoc JSON file and fill it with the minimum
        # necessary entries to define a project.
        jData = {}
        jDS = {}
        '''
        jDS['ip-name'] = ipname
        
        pdkdir = self.get_pdk_dir(pname, path=True)
        try:
            jDS['foundry'], jDS['node'], pdk_desc, pdk_stat = self.pdkdir2fnd( pdkdir )
        except:
            # Cannot parse PDK name, so foundry and node will remain undefined
            pass
        '''
        jDS['format'] = '3'
        pparams = []
        param = {}
        param['unit'] = "\u00b5m\u00b2"
        param['condition'] = "device_area"
        param['display'] = "Device area"
        pmax = {}
        pmax['penalty'] = '0'
        pmax['target'] = '100000'
        param['max'] = pmax
        pparams.append(param)
    
        param = {}
        param['unit'] = "\u00b5m\u00b2"
        param['condition'] = "area"
        param['display'] = "Layout area"
        pmax = {}
        pmax['penalty'] = '0'
        pmax['target'] = '100000'
        param['max'] = pmax
        pparams.append(param)

        param = {}
        param['unit'] = "\u00b5m"
        param['condition'] = "width"
        param['display'] = "Layout width"
        pmax = {}
        pmax['penalty'] = '0'
        pmax['target'] = '300'
        param['max'] = pmax
        pparams.append(param)

        param = {}
        param['condition'] = "DRC_errors"
        param['display'] = "DRC errors"
        pmax = {}
        pmax['penalty'] = 'fail'
        pmax['target'] = '0'
        param['max'] = pmax
        pparams.append(param)

        param = {}
        param['condition'] = "LVS_errors"
        param['display'] = "LVS errors"
        pmax = {}
        pmax['penalty'] = 'fail'
        pmax['target'] = '0'
        param['max'] = pmax
        pparams.append(param)

        jDS['physical-params'] = pparams
        jData['data-sheet'] = jDS

        return jData

#------------------------------------------------------------------------
    # Create info.yaml file (automatically done in create_project.py in case it's executed from the command line)
    #------------------------------------------------------------------------
   
    def create_yaml(self, ipname, pdk_dir, description="(Add project description here)"):
        # ipname: Project Name
        data = {}
        project= {}
        project['description'] = description
        try:
            project['foundry'], foundry_name, project['process'], pdk_desc, pdk_stat = self.pdkdir2fnd( pdk_dir )
        except:
            # Cannot parse PDK name, so foundry and node will remain undefined
            pass
        project['project_name'] = ipname
        project['flow'] = 'none'
        data['project']=project
        return data
    #------------------------------------------------------------------------
    # For a single named member (memPath) out of an open tarfile (tarf),
    # determine if it is a JSON file, and attempt to extract value of entry
    # 'node' in dictionary entry 'data-sheet'.  Otherwise return None.
    #------------------------------------------------------------------------

    def tarMemberHasFoundryNode(self, tarf, memPath):
        fileJSON = tarf.extractfile(memPath)
        if not fileJSON: return None

        try:
            # NOTE: tarfile data is in bytes, json.load(fileJSON) does not work.
            datatop = json.loads(fileJSON.read().decode('utf-8'))
        except:
            print("Failed to load extract file " + memPath + " as JSON data")
            return None
        else:
            node = None
            if 'data-sheet' in datatop:
                dsheet = datatop['data-sheet']
                if 'node' in dsheet:
                    node = dsheet['node']

        fileJSON.close()     # close open-tarfile before any return
        return node

    #------------------------------------------------------------------------
    # For a single named member (memPath) out of an open tarfile (tarf),
    # determine if first line embeds (case-insensitive match): Generated by Yosys
    # Return True or False. If no such member or it has no 1st line, returns False.
    #------------------------------------------------------------------------

    def tarMemberIsGLverilog(self, tarf, memPath):
        fileHdl = tarf.extractfile(memPath)
        if not fileHdl: return False

        line = fileHdl.readline()
        fileHdl.close()     # close open-tarfile before any return
        if not line: return False
        return ('generated by yosys' in line.decode('utf-8').lower())

    #------------------------------------------------------------------------
    # Import vgl-netlist file INTO existing project.
    # The importfile can be a .v; or a .json-with-tar that embeds a .v.
    # What is newfile? not used here.
    #
    # PROMPT to select an existing project is here.
    # (Is also a PROMPT to select existing electric lib, but that's within importvgl).
    #------------------------------------------------------------------------

    def importvglinto(self, newfile, importfile):
        # Require existing project location
        ppath = ExistingProjectDialog(self, self.get_project_list()).result
        if not ppath:   return 0		# Canceled in dialog, no action.
        pname = os.path.split(ppath)[1]
        print( "Importing into existing project: %s" % (pname))

        return self.importvgl(newfile, importfile, pname)

    #------------------------------------------------------------------------
    # Import cloudv project as new project.
    #------------------------------------------------------------------------

    def install_from_cloudv(self, opath, ppath, pdkname, stdcellname, ydicts):
        oname = os.path.split(opath)[1]
        pname = os.path.split(ppath)[1]

        print('Cloudv project name is ' + str(oname))
        print('New project name is ' + str(pname))

        os.makedirs(ppath + '/verilog', exist_ok=True)

        vfile = None
        isfullchip = False
        ipname = oname

        # First check for single synthesized projects, or all synthesized
	# digital sub-blocks within a full-chip project.

        os.makedirs(ppath + '/verilog/source', exist_ok=True)
        bfiles = glob.glob(opath + '/build/*.netlist.v')
        for bfile in bfiles:
            tname = os.path.split(bfile)[1]
            vname = os.path.splitext(os.path.splitext(tname)[0])[0]
            tfile = ppath + '/verilog/' + vname + '/' + vname + '.vgl'
            print('Making qflow sub-project ' + vname)
            os.makedirs(ppath + '/verilog/' + vname, exist_ok=True)
            shutil.copy(bfile, tfile)
            if vname == oname:
                vfile = tfile

            # Each build project gets its own qflow directory.  Create the
            # source/ subdirectory and make a link back to the .vgl file.
            # qflow prep should do the rest.

            os.makedirs(ppath + '/qflow', exist_ok=True)
            os.makedirs(ppath + '/qflow/' + vname)
            os.makedirs(ppath + '/qflow/' + vname + '/source')

            # Make sure the symbolic link is relative, so that it is portable
            # through a shared project.
            curdir = os.getcwd()
            os.chdir(ppath + '/qflow/' + vname + '/source')
            os.symlink('../../../verilog/' + vname + '/' + vname + '.vgl', vname + '.v')
            os.chdir(curdir)

            # Create a simple qflow_vars.sh file so that the project manager
            # qflow launcher will see it as a qflow sub-project.  If the meta.yaml
            # file has a "stdcell" entry for the subproject, then add the line
            # "techname=" with the name of the standard cell library as pulled
            # from meta.yaml.

            stdcell = None
            buildname = 'build/' + vname + '.netlist.v'
            for ydict in ydicts:
                if buildname in ydict:
                    yentry = ydict[buildname]
                    if 'stdcell' in yentry:
                        stdcell = yentry['stdcell']

            with open(ppath + '/qflow/' + vname + '/qflow_vars.sh', 'w') as ofile:
                print('#!/bin/tcsh -f', file=ofile)
                if stdcell:
                    print('set techname=' + stdcell, file=ofile)

        # Now check for a full-chip verilog SoC (from CloudV)

        modrex = re.compile('[ \t]*module[ \t]+[^ \t(]*_?soc[ \t]*\(')
        genmodrex = re.compile('[ \t]*module[ \t]+([^ \t(]+)[ \t]*\(')

        bfiles = glob.glob(opath + '/*.model/*.v')
        for bfile in bfiles:
            tname = os.path.split(bfile)[1]
            vpath = os.path.split(bfile)[0]
            ipname = os.path.splitext(tname)[0]
            tfile = ppath + '/verilog/' + ipname + '.v'
            isfullchip = True
            break

        if isfullchip:
            print('Cloudv project IP name is ' + str(ipname))

            # All files in */ paths should be copied to project verilog/source/,
            # except for the module containing the SoC itself.  Note that the actual
            # verilog source goes here, not the synthesized netlist, although that is
            # mainly for efficiency of the simulation, which would normally be done in
            # cloudV and not in Open Galaxy.  For Open Galaxy, what is needed is the
            # existence of a verilog file containing a module name, which is used to
            # track down the various files (LEF, DEF, etc.) that are needed for full-
            # chip layout.
            #
            # (Sept. 2019) Added copying of files in /SW/ -> /sw/ and /Verify/ ->
	    # /verify/ for running full-chip simulations on the Open Galaxy side.

            os.makedirs(ppath + '/verilog', exist_ok=True)

            cfiles = glob.glob(vpath + '/source/*')
            for cfile in cfiles:
                cname = os.path.split(cfile)[1]
                if cname != tname:
                    tpath = ppath + '/verilog/source/' + cname
                    os.makedirs(ppath + '/verilog/source', exist_ok=True)
                    shutil.copy(cfile, tpath)

            cfiles = glob.glob(vpath + '/verify/*')
            for cfile in cfiles:
                cname = os.path.split(cfile)[1]
                tpath = ppath + '/verilog/verify/' + cname
                os.makedirs(ppath + '/verilog/verify', exist_ok=True)
                shutil.copy(cfile, tpath)

            cfiles = glob.glob(vpath + '/sw/*')
            for cfile in cfiles:
                cname = os.path.split(cfile)[1]
                tpath = ppath + '/verilog/sw/' + cname
                os.makedirs(ppath + '/verilog/sw', exist_ok=True)
                shutil.copy(cfile, tpath)

            # Read the top-level SoC verilog and recast it for OpenGalaxy.
            with open(bfile, 'r') as ifile:
                chiplines = ifile.read().splitlines()

            # Find the modules used, track them down, and add the source location
            # in the Open Galaxy environment as an "include" line in the top level
            # verilog.

            parentdir = os.path.split(bfile)[0]
            modfile = parentdir + '/docs/modules.txt'

            modules = []
            if os.path.isfile(modfile):
                with open(modfile, 'r') as ifile:
                    modules = ifile.read().splitlines()
            else:
                print("Warning:  No modules.txt file for the chip top level module in "
				+ parentdir + "/docs/.\n")

            # Get the names of verilog libraries in this PDK.
            pdkdir = os.path.realpath(ppath + '/.ef-config/techdir')
            pdkvlog = pdkdir + '/libs.ref/verilog'
            pdkvlogfiles = glob.glob(pdkvlog + '/*/*.v')

            # Read the verilog libraries and create a dictionary mapping each
            # module name to a location of the verilog file where it is located.
            moddict = {}
            for vlogfile in pdkvlogfiles:
                with open(vlogfile, 'r') as ifile:
                    for line in ifile.read().splitlines():
                        mmatch = genmodrex.match(line)
                        if mmatch:
                            modname = mmatch.group(1)
                            moddict[modname] = vlogfile

            # Get the names of verilog libraries in the user IP space.
            # (TO DO:  Need to know the IP version being used!)
            designdir = os.path.split(ppath)[0]
            ipdir = designdir + '/ip/'
            uservlogfiles = glob.glob(ipdir + '/*/*/verilog/*.v')
            for vlogfile in uservlogfiles:
                # Strip ipdir from the front
                vlogpath = vlogfile.replace(ipdir, '', 1)
                with open(vlogfile, 'r') as ifile:
                    for line in ifile.read().splitlines():
                        mmatch = genmodrex.match(line)
                        if mmatch:
                            modname = mmatch.group(1)
                            moddict[modname] = vlogpath

            # Find all netlist builds from the project (those that were copied above)
            buildfiles = glob.glob(ppath + '/verilog/source/*.v')
            for vlogfile in buildfiles:
                # Strip ipdir from the front
                vlogpath = vlogfile.replace(ppath + '/verilog/source/', '', 1)
                with open(vlogfile, 'r') as ifile:
                    for line in ifile.read().splitlines():
                        mmatch = genmodrex.match(line)
                        if mmatch:
                            modname = mmatch.group(1)
                            moddict[modname] = vlogpath

            # (NOTE:  removing 'ifndef LVS' as netgen should be able to handle
            #  the contents of included files, and they are preferred since any
            #  arrays are declared in each module I/O)
            # chiplines.insert(0, '`endif')
            chiplines.insert(0, '//--- End of list of included module dependencies ---')
            includedfiles = []
            for module in modules:
                # Determine where this module comes from.  Look in the PDK, then in
                # the user ip/ directory, then in the local hierarchy.  Note that
                # the local hierarchy expects layouts from synthesized netlists that
                # have not yet been created, so determine the expected location.

                if module in moddict:
                    if moddict[module] not in includedfiles:
                        chiplines.insert(0, '`include "' + moddict[module] + '"')
                        includedfiles.append(moddict[module])

            # chiplines.insert(0, '`ifndef LVS')
            chiplines.insert(0, '//--- List of included module dependencies ---')
            chiplines.insert(0, '// iverilog simulation requires the use of -I source -I ~/design/ip')
            chiplines.insert(0, '// NOTE:  Includes may be rooted at ~/design/ip/ or at ./source')
            chiplines.insert(0, '// SoC top level verilog copied and modified by project manager')

            # Copy file, but replace the module name "soc" with the ip-name
            with open(tfile, 'w') as ofile:
                for chipline in chiplines:
                    print(modrex.sub('module ' + ipname + ' (', chipline), file=ofile)

        # Need to define behavior:  What if there is more than one netlist?
        # Which one is to be imported?  For now, ad-hoc behavior is to select
        # the last netlist file in the list if no file matches the ip-name.

        # Note that for full-chip projects, the full chip verilog file is always
        # the last one set.

        if not vfile:
            try:
                vfile = tfile
            except:
                pass

        # NOTE:  vfile was being used to create a symbol, but not any more;
        # see below.  All the above code referencing vfile can probably be
        # removed.

        try:
            sfiles = glob.glob(vpath + '/source/*')
            sfiles.extend(glob.glob(vpath + '/*/source/*'))
        except:
            sfiles = glob.glob(opath + '/*.v')
            sfiles.extend(glob.glob(opath + '/*.sv'))
            sfiles.extend(glob.glob(opath + '/local/*'))

        for fname in sfiles:
            sname = os.path.split(fname)[1]
            tfile = ppath + '/verilog/source/' + sname
            # Reject '.model' and '.soc" files (these are meaningful only to CloudV)
            fileext = os.path.splitext(fname)[1]
            if fileext == '.model' or fileext == '.soc':
                continue
            if os.path.isfile(fname):
                # Check if /verilog/source/ has been created
                if not os.path.isdir(ppath + '/verilog/source'):
                    os.makedirs(ppath + '/verilog/source')
                shutil.copy(fname, tfile)

        # Add standard cell library name to project.json
        pjsonfile = ppath + '/project.json'
        if os.path.exists(pjsonfile):
            with open(pjsonfile, 'r') as ifile:
                datatop = json.load(ifile)
        else:
            datatop = self.create_ad_hoc_json(ipname, ppath)

        # Generate a symbol in electric for the verilog top module
        iconfile = ppath + '/elec/' + ipname + '.delib/' + ipname + '.ic'
        if not os.path.exists(iconfile):
            # NOTE:  Symbols are created by qflow migration for project
            # builds.  Only the chip top-level needs to run create_symbol
            # here.

            if isfullchip:
                print("Creating symbol for module " + ipname + " automatically from verilog source.")
                create_symbol(ppath, vfile, ipname, iconfile, False)
            # Add header file
            self.create_electric_header_file(ppath, ipname)
          
        dsheet = datatop['data-sheet']
        if not stdcellname or stdcellname == "":
            dsheet['standard-cell'] = 'default'
        else:
            dsheet['standard-cell'] = stdcellname

        with open(pjsonfile, 'w') as ofile:
            json.dump(datatop, ofile, indent = 4)

        return 0

    #------------------------------------------------------------------------
    # Import vgl-netlist AS new project.
    # The importfile can be a .v; or a .json-with-tar that embeds a .v.
    # What is newfile? not used here.
    #
    # PROMPT to select an create new project is within importvgl.
    #------------------------------------------------------------------------

    def importvglas(self, newfile, importfile, seedname):
        print('importvglas:  seedname is ' + str(seedname))
        return self.importvgl(newfile, importfile, newname=None, seedname=seedname)

    #------------------------------------------------------------------------
    # Utility shared/used by both: Import vgl-netlist file AS or INTO a project.
    # Called directly for AS. Called via importvglinto for INTO.
    #   importfile : source of .v to import, actual .v or json-with-tar that embeds a .v
    #   newfile : not used
    #   newname : target project-name (INTO), or None (AS: i.e. prompt to create one).
    # Either newname is given: we PROMPT to pick an existing elecLib;
    # Else PROMPT for new projectName and CREATE it (and use elecLib of same name).
    #------------------------------------------------------------------------

    
    def importvgl(self, newfile, importfile, newname=None, seedname=None):
        elecLib = None
        isnew = not newname

        # Up front:  Determine if this import has a .json file associated
        # with it.  If so, then parse the JSON data to find if there is a
        # foundry and node set for the project.  If so, then the foundry
        # node is not selectable at time of import.  Likewise, if "isnew"
        # is false, then we need to check if there is a directory called
        # "newname" and if it is set to the same foundry node.  If not,
        # then the import must be rejected.

        tarVfile, jName, importnode = self.jsonTarVglImportable(importfile)

        if isnew:
            print('importvgl:  seedname is ' + str(seedname))
            # Use create project code first to generate a valid project space.
            newname = self.createproject(None, seedname, importnode)
            if not newname: return 0		# Canceled in dialog, no action.
            print("Importing as new project " + newname + ".")
            elecLib = newname

        ppath = self.projectdir + '/' + newname
        if not elecLib:
            choices = self.get_elecLib_list(newname)
            if not choices:
                print( "Aborted: No existing electric libraries found to import into.")
                return 0
                
            elecLib = ExistingElecLibDialog(self, choices).result
            if not elecLib:
                # Never a just-created project to delete here: We only PROMPT to pick elecLib in non-new case.
                return 0		# Canceled in dialog, no action.
            
            # Isolate just electric lib name without extension. ../a/b.delib -> b
            elecLib = os.path.splitext(os.path.split(elecLib)[-1])[0]
            print("Importing to project: %s, elecLib: %s" % (newname, elecLib))

        # Determine isolated *.v as importactual. May be importfile or tar-member (as temp-file).
        importactual = importfile
        if tarVfile:
            importactual = self.jsonTarMember2tempfile(importfile, tarVfile)
            print("importing json-with-tar's member: %s" % (tarVfile))

        if not os.path.isfile(importactual):
            # TODO: should this be a raise instead?
            print('Error determining *.v to import')
            return None

        result = self.vgl_install(importactual, newname, elecLib, newfile, isnew=isnew)
        if result == None:
            print('Error during install')
            return None
        elif result == 0: 
            # Canceled, so do not remove the import
            return 0
        else: 
            # If jName is non-NULL then there is a JSON file in the tarball.  This is
            # to be used as the project JSON file.  Contents of file coming from
            # CloudV are correct as of 12/8/2017.
            pname = os.path.expanduser('~/design/' + newname)
            legacyjname = pname + '/' + newname + '.json'
            # New behavior 12/2018:  Project JSON file always named 'project.json'
            jname = pname + '/project.json'

            # Do not overwrite an existing JSON file.  Overwriting is a problem for
            # "import into", as the files go into an existing project, which would
            # normally have its own JSON file.

            if not os.path.exists(jname) and not os.path.exists(legacyjname):
                try:
                    tarJfile = os.path.split(tarVfile)[0] + '/' + jName + '.json'
                    importjson = self.jsonTarMember2tempfile(importfile, tarJfile)
                except:
                    jData = self.create_ad_hoc_json(newname, pname)
    
                    with open(jname, 'w') as ofile:
                        json.dump(jData, ofile, indent = 4)

                else:
                    # Copy the temporary file pulled from the tarball and
                    # remove the temporary file.
                    shutil.copy(importjson, jname)
                    os.remove(importjson)

            # For time-being, if a tar.gz & json: archive them in the target project, also as extracted.
            # Remove original file from imports area (either .v; or .json plus tar)
            # plus temp-file if extracted from the tar.
            if importactual != importfile:
                os.remove(importactual)
                pname = self.projectdir + '/' + newname
                importd = pname + '/' + archiveimportdir      # global: archiveimportdir
                os.makedirs(importd, exist_ok=True)
                # Dirnames to embed a VISIBLE date (UTC) of when populated.
                # TODO: improve dir naming or better way to store & understand later when it was processed (a log?),
                # without relying on file-system mtime.
                archived = tempfile.mkdtemp( dir=importd, prefix='{:%Y-%m-%d.%H:%M:%S}-'.format(datetime.datetime.utcnow()))
                tarname = self.json2targz(importfile)
                if tarname:
                    with tarfile.open(tarname, mode='r:gz') as archive:
                        for member in archive:
                            archive.extract(member, archived)
                self.moveJsonPlus(importfile, archived)
            else:
                self.removeJsonPlus(importfile)
            return 1    # Success

    #------------------------------------------------------------------------
    # Prepare multiline "warning" indicating which files to install already exist.
    # TODO: ugly, don't use a simple confirmation dialogue: present a proper table.
    #------------------------------------------------------------------------
    def installsConfirmMarkOverwrite(self, module, files):
        warning = [ "For import of module: %s," % module ]
        anyExists = False
        for i in files:
            exists = os.path.isfile(os.path.expanduser(i))
            if exists: anyExists = True
            warning += [ (" * " if exists else "   ") + i ]
        if anyExists:
            titleSuffix = "\nCONFIRM installation of (*: OVERWRITE existing):"
        else:
            titleSuffix = "\nCONFIRM installation of:"
        warning[0] += titleSuffix
        return ConfirmInstallDialog(self,   "\n".join(warning)).result

    def vgl_install(self, importfile, pname, elecLib, newfile, isnew=True):
        #--------------------------------------------------------------------
        # Convert the in .v to: spi, cdl, elec-icon, elec-text-view forms.
        # TODO: Prompt to confirm final install of 5 files in dir-structure.
        #
        # newfile: argument is not used. What is it for?
        # Target project AND electricLib MAY BE same (pname) or different.
        # Rest of the filenames are determined by the module name in the source .v.
        #--------------------------------------------------------------------

        newproject = self.projectdir + '/' + pname
        try:
            p = subprocess.run(['/ef/apps/bin/vglImport', importfile, pname, elecLib],
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                               check=True, universal_newlines=True)
        except subprocess.CalledProcessError as e:
            if hasattr(e, 'stdout') and e.stdout: print(e.stdout)
            if hasattr(e, 'stderr') and e.stderr: print(e.stderr)
            print('Error running vglImport: ' + str(e))
            if isnew == True: shutil.rmtree(newproject)
            return None
        else:
            dataLines = p.stdout.splitlines()
            if p.stderr:
                # Print error messages to console
                for i in p.stderr.splitlines(): print(i)
            if not dataLines or len(dataLines) != 11:
                print('Error: vglImport has no output, or wrong #outputs (%d vs 11)' % len(dataLines))
                if isnew == True: shutil.rmtree(newproject)
                return None
            else:
                module = dataLines[0]
                confirm = self.installsConfirmMarkOverwrite(module, dataLines[2::2])
                if not confirm:
                    print("Cancelled")
                    if isnew == True: shutil.rmtree(newproject)
                    return 0
                # print("Proceed")
                clean = dataLines[1:]
                nbr = len(dataLines)
                ndx = 1
                # trap I/O errors and clean-up if any
                try:
                    while ndx+1 < nbr:
                        trg = os.path.expanduser(dataLines[ndx+1])
                        os.makedirs(os.path.dirname(trg), exist_ok=True)
                        shutil.move(dataLines[ndx], trg)
                        ndx += 2
                except IOError as e:
                    print('Error copying files: ' + str(e))
                    for i in clean:
                        with contextlib.suppress(FileNotFoundError): os.remove(i)
                    if isnew == True: shutil.rmtree(newproject)
                    return 0
                print( "For import of module %s installed: %s" % (module, " ".join(dataLines[2::2])))
                return 1    # Success


    #------------------------------------------------------------------------
    # Callback function from "Import Into" button on imports list box.
    #------------------------------------------------------------------------

    def importintodesign(self, value):
        if not value['values']:
            print('No import selected.')
            return

        # Stop the watchdog timer while this is going on
        self.watchclock.stop()
        newname = value['text']
        importfile = value['values'][0]
        print('Import project name: ' + newname + '')
        print('Import file name: ' + importfile + '')

        # Behavior depends on what kind of file is being imported.
        # Tarballs are entire projects.  Other files are individual
        # files and may be imported into new or existing projects

        if os.path.isdir(importfile):
            print('File is a project, must import as new project.')
            result = self.import2project(importfile, addWarn='Redirected: A projectDir must Import-As new project.')
        else:
            ext = os.path.splitext(importfile)[1]
            vFile, jName, importnode = self.jsonTarVglImportable(importfile)
            if ((ext == '.json' and vFile) or ext == '.v'):
                result = self.importvglinto(newname, importfile)
            elif ext == '.json':
                # Same behavior as "Import As", at least for now
                print('File is a project, must import as new project.')
                result = self.importjson(newname, importfile)
            else:
                result = self.importspiceinto(newname, importfile)

        if result:
            self.update_project_views(force=True)
        self.watchclock.restart()

    #------------------------------------------------------------------------
    # Callback function from "Import As" button on imports list box.
    #------------------------------------------------------------------------

    def importdesign(self, value):
        if not value['values']:
            print('No import selected.')
            return

        # Stop the watchdog timer while this is going on
        self.watchclock.stop()
        newname = value['text']
        importfile = value['values'][0]
        print('Import project name: ' + newname)
        print('Import file name: ' + importfile)

        # Behavior depends on what kind of file is being imported.
        # Tarballs are entire projects.  Other files are individual
        # files and may be imported into new or existing projects

        if os.path.isdir(importfile):
            result = self.import2project(importfile)
        else:
            pathext = os.path.splitext(importfile)
            vfile, seedname, importnode = self.jsonTarVglImportable(importfile)
            if ((pathext[1] == '.json' and seedname) or pathext[1] == '.v'):
                result = self.importvglas(newname, importfile, seedname)
            elif pathext[1] == '.json':
                result = self.importjson(newname, importfile)
            else:
                result = self.importspice(newname, importfile)

        if result:
            self.update_project_views(force=True)
        self.watchclock.restart()

    def deleteimport(self, value):
        if not value['values']:
            print('No import selected.')
            return

        print("Delete import " + value['text'] + '  ' + value['values'][0] + " !")
        # Require confirmation
        warning = 'Confirm delete import ' + value['text'] + '?'
        confirm = ProtectedConfirmDialog(self, warning).result
        if not confirm == 'okay':
            return
        print('Delete confirmed!')
        item = value['values'][0]

        if not os.path.islink(item) and os.path.isdir(item):
            shutil.rmtree(item)
            return

        os.remove(item)
        ext = os.path.splitext(item)
        # Where import is a pair of .json and .tar.gz files, remove both.
        if ext[1] == '.json':
            if os.path.exists(ext[0] + '.tar.gz'):
                os.remove(ext[0] + '.tar.gz')
            elif os.path.exists(ext[0] + '.tgz'):
                os.remove(ext[0] + '.tgz')

    def update_project_views(self, force=False):
        # More than updating project views, this updates projects, imports, and
        # IP libraries.
        
        projectlist = self.get_project_list()
        self.projectselect.repopulate(projectlist)
        pdklist = self.get_pdk_list(projectlist)
        self.projectselect.populate2("PDK", projectlist, pdklist)

        '''
        old_imports = self.number_of_imports
        importlist = self.get_import_list()
        self.importselect.repopulate(importlist)
        valuelist = self.importselect.getvaluelist()
        datelist = self.get_date_list(valuelist)
        itemlist = self.importselect.getlist()
        self.importselect.populate2("date", itemlist, datelist)
        

        # To do:  Check if itemlist in imports changed, and open if a new import
        # has arrived.
     
        if force or (old_imports != None) and (old_imports < self.number_of_imports):
            self.import_open()

        iplist = self.get_library_list()
        self.ipselect.repopulate(iplist, versioning=True)
        valuelist = self.ipselect.getvaluelist()
        datelist = self.get_date_list(valuelist)
        itemlist = self.ipselect.getlist()
        self.ipselect.populate2("date", itemlist, datelist)
        '''
    def update_alert(self):
        # Project manager has been updated.  Generate an alert window and
        # provide option to restart the project manager.

        warning = 'Project manager app has been updated.  Restart now?'
        confirm = ConfirmDialog(self, warning).result
        if not confirm == 'okay':
            print('Warning: Must quit and restart to get any fixes or updates.')
            return
        os.execl('/ef/efabless/opengalaxy/project_manager.py', 'appsel_zenity.sh')
        # Does not return; replaces existing process.

    #----------------------------------------------------------------------
    # Delete a project from the design folder.
    #----------------------------------------------------------------------

    def deleteproject(self, value):
        if not value['values']:
            print('No project selected.')
            return
        path = value['values'][0]
        print('Delete project ' + value['values'][0])
        # Require confirmation
        warning = 'Confirm delete entire project ' + value['text'] + '?'
        confirm = ProtectedConfirmDialog(self, warning).result
        if not confirm == 'okay':
            return
        if os.path.islink(path):
            os.unlink(path)
            self.update_project_views()  
        else:
            shutil.rmtree(value['values'][0])
        if ('subcells' in path):
            self.update_project_views()      

    #----------------------------------------------------------------------
    # Clean out the simulation folder.  Traditionally this was named
    # 'ngspice', so this is checked for backward-compatibility.  The
    # proper name of the simulation directory is 'simulation'.
    #----------------------------------------------------------------------

    def cleanproject(self, value):
        if not value['values']:
            print('No project selected.')
            return
        ppath = value['values'][0]
        print('Clean simulation raw data from directory ' + ppath)
        # Require confirmation
        warning = 'Confirm clean project ' + value['text'] + ' contents?'
        confirm = ConfirmDialog(self, warning).result
        if not confirm == 'okay':
            return
        else:
            self.clean(ppath)
            
    def clean(self, ppath):
        if os.path.isdir(ppath + '/simulation'):
            simpath = 'simulation'
        elif os.path.isdir(ppath + '/ngspice'):
            simpath = 'ngspice'
        else:
            print('Project has no simulation folder.')
            return

        filelist = os.listdir(ppath + '/' + simpath)
        for sfile in filelist:
            if os.path.splitext(sfile)[1] == '.raw':
                os.remove(ppath + '/ngspice/' + sfile)                
        print('Project simulation folder cleaned.')

        # Also clean the log file
        filelist = os.listdir(ppath)
        for sfile in filelist:
            if os.path.splitext(sfile)[1] == '.log':
                os.remove(ppath + '/' + sfile)                

    #---------------------------------------------------------------------------------------
    # Determine which schematic editors are compatible with the PDK, and return a list of them.
    #---------------------------------------------------------------------------------------

    def list_valid_schematic_editors(self, pdktechdir):
        # Check PDK technology directory for xcircuit, xschem, and electric
        applist = []
        if os.path.exists(pdktechdir + '/elec'):
            applist.append('electric')
        if os.path.exists(pdktechdir + '/xschem'):
            applist.append('xschem')
        if os.path.exists(pdktechdir + '/xcircuit'):
            applist.append('xcircuit')

        return applist

    #------------------------------------------------------------------------------------------
    # Determine which layout editors are compatible with the PDK, and return a list of them.
    #------------------------------------------------------------------------------------------

    def list_valid_layout_editors(self, pdktechdir):
        # Check PDK technology directory for magic and klayout
        applist = []
        if os.path.exists(pdktechdir + '/magic'):
            applist.append('magic')
        if os.path.exists(pdktechdir + '/klayout'):
            applist.append('klayout')
        return applist

    #----------------------------------------------------------------------
    # Create a new project folder and initialize it (see below for steps)
    #----------------------------------------------------------------------

    def createproject(self, value, seedname=None, importnode=None):
        global currdesign
        global apps_path
        # Note:  value is current selection, if any, and is ignored
        # Require new project location and confirmation
        badrex1 = re.compile("^\.")
        badrex2 = re.compile(".*[/ \t\n\\\><\*\?].*")
        warning = 'Create new project:'
        print(warning)
        development = self.prefs['development']
        
        # Find out whether the user wants to create a subproject or project
        parent_pdk = ''
        try:
            with open(os.path.expanduser(currdesign), 'r') as f:
                pdirCur = f.read().rstrip()
                if ('subcells' in pdirCur):
                    # subproject is selected
                    parent_path = os.path.split(os.path.split(pdirCur)[0])[0]
                    pdkdir = self.get_pdk_dir(parent_path, path=True)
                    (foundry, foundry_name, node, desc, status) = self.pdkdir2fnd( pdkdir )
                    parent_pdk = foundry + '/' + node
                    warning = 'Create new subproject in '+ parent_path + ':'
                elif (pdirCur[0] == '.'):
                    # the project's 'subproject' of itself is selected
                    parent_path = pdirCur[1:]
                    pdkdir = self.get_pdk_dir(parent_path, path=True)
                    (foundry, foundry_name, node, desc, status) = self.pdkdir2fnd( pdkdir )
                    parent_pdk = foundry + '/' + node
                    warning = 'Create new subproject in '+ parent_path + ':'
                
        except:
            pass
        
        while True:
            try:
                if seedname:
                    newname, newpdk = NewProjectDialog(self, warning, seed=seedname, importnode=importnode, development=development, parent_pdk=parent_pdk).result
                else:
                    newname, newpdk = NewProjectDialog(self, warning, seed='', importnode=importnode, development=development, parent_pdk=parent_pdk).result
            except TypeError:
                # TypeError occurs when "Cancel" is pressed, just handle exception.
                return None
            if not newname:
                return None	# Canceled, no action.
            
            if parent_pdk == '':
                newproject = self.projectdir + '/' + newname
            else:
                newproject = parent_path + '/subcells/' + newname
            
            if self.blacklisted(newname):
                warning = newname + ' is not allowed for a project name.'
            elif badrex1.match(newname):
                warning = 'project name may not start with "."'
            elif badrex2.match(newname):
                warning = 'project name contains illegal characters or whitespace.'
            elif os.path.exists(newproject):
                warning = newname + ' is already a project name.'
            else:
                break
        
        if parent_pdk !='' and not os.path.isdir(parent_path + '/subcells'):
            os.makedirs(parent_path + '/subcells')
        
        try:
            subprocess.Popen([apps_path + '/create_project.py', newproject, newpdk]).wait()
            
            # Show subproject in project view
            if parent_pdk != '':
                self.update_project_views()
            
        except IOError as e:
            print('Error copying files: ' + str(e))
            return None
            
        except:
            print('Error making project.')
            return None
        
        return newname
        '''
        # Find what tools are compatible with the given PDK
        schemapps = self.list_valid_schematic_editors(newpdk + '/libs.tech')
        layoutapps = self.list_valid_layout_editors(newpdk + '/libs.tech')

        print('New project name will be ' + newname + '.')
        print('Associated project PDK is ' + newpdk + '.')
        try:
            os.makedirs(newproject)

            # Make standard folders
            if 'magic' in layoutapps:
                os.makedirs(newproject + '/mag')

            os.makedirs(newproject + '/spi')
            os.makedirs(newproject + '/spi/pex')
            os.makedirs(newproject + '/spi/lvs')
            if 'electric' in layoutapps or 'electric' in schemapps:
                os.makedirs(newproject + '/elec')
            if 'xcircuit' in schemapps:
                os.makedirs(newproject + '/xcirc')
            if 'klayout' in schemapps:
                os.makedirs(newproject + '/klayout')
            os.makedirs(newproject + '/ngspice')
            os.makedirs(newproject + '/ngspice/run')
            if 'electric' in schemapps:
                os.makedirs(newproject + '/ngspice/run/.allwaves')
            os.makedirs(newproject + '/testbench')
            os.makedirs(newproject + '/verilog')
            os.makedirs(newproject + '/verilog/source')
            os.makedirs(newproject + '/.ef-config')
            if 'xschem' in schemapps:
                os.makedirs(newproject + '/xschem')

            pdkname = os.path.split(newpdk)[1]

            # Symbolic links
            os.symlink(newpdk, newproject + '/.ef-config/techdir')

            # Copy preferences
            # deskel = '/ef/efabless/deskel'
            #
            # Copy examples (disabled;  this is too confusing to the end user.  Also, they
            # should not be in user space at all, as they are not user editable.
            #
            # for item in os.listdir(deskel + '/exlibs'):
            #     shutil.copytree(deskel + '/exlibs/' + item, newproject + '/elec/' + item)
            # for item in os.listdir(deskel + '/exmag'):
            #     if os.path.splitext(item)[1] == '.mag':
            #         shutil.copy(deskel + '/exmag/' + item, newproject + '/mag/' + item)

            # Put tool-specific startup files into the appropriate user directories.
            if 'electric' in layoutapps or 'electric' in schemapps:
                self.reinitElec(newproject)   # [re]install elec/.java, elec/LIBDIRS if needed, from pdk-specific if-any
                # Set up electric
                self.create_electric_header_file(newproject, newname)

            if 'magic' in layoutapps:
                shutil.copy(newpdk + '/libs.tech/magic/' + pdkname + '.magicrc', newproject + '/mag/.magicrc')

            if 'xcircuit' in schemapps:
                xcircrc = newpdk + '/libs.tech/xcircuit/' + pdkname + '.' + 'xcircuitrc'
                xcircrc2 = newpdk + '/libs.tech/xcircuit/xcircuitrc'
                if os.path.exists(xcircrc):
                    shutil.copy(xcircrc, newproject + '/xcirc/.xcircuitrc')
                elif os.path.exists(xcircrc2):
                    shutil.copy(xcircrc2, newproject + '/xcirc/.xcircuitrc')

            if 'xschem' in schemapps:
                xschemrc = newpdk + '/libs.tech/xschem/xschemrc'
                if os.path.exists(xschemrc):
                    shutil.copy(xschemrc, newproject + '/xschem/xschemrc')
                spinit = newpdk + '/libs.tech/ngpsice/spinit'
                if os.path.exists(spinit):
                    shutil.copy(spinit, newproject + '/xschem/.spiceinit')

        except IOError as e:
            print('Error copying files: ' + str(e))
            return None

        return newname
        '''
    #----------------------------------------------------------------------
    # Import a CloudV project from ~/cloudv/<project_name>
    #----------------------------------------------------------------------

    def cloudvimport(self, value):

        # Require existing project location
        clist = self.get_cloudv_project_list()
        if not clist:
            return 0		# No projects to import
        ppath = ExistingProjectDialog(self, clist, warning="Enter name of cloudV project to import:").result
        if not ppath:
            return 0		# Canceled in dialog, no action.
        pname = os.path.split(ppath)[1]
        print("Importing CloudV project " + pname)

        importnode = None
        stdcell = None
        netlistfile = None

        # Pull process and standard cell library from the YAML file created by
        # CloudV.  NOTE:  YAML file has multiple documents, so must use
        # yaml.load_all(), not yaml.load().  If there are refinements of this
        # process for individual build files, they will override (see further down).

        # To do:  Check entries for SoC builds.  If there are multiple SoC builds,
        # then create an additional drop-down selection to choose one, since only
        # one SoC build can exist as a single Open Galaxy project.  Get the name
        # of the top-level module for the SoC.  (NOTE:  It may not be intended
        # that there can be multiple SoC builds in the project, so for now retaining
        # the existing parsing assuming default names.)

        if os.path.exists(ppath + '/.ef-config/meta.yaml'):
            print("Reading YAML file:")
            ydicts = []
            with open(ppath + '/.ef-config/meta.yaml', 'r') as ifile:
                yalldata = yaml.load_all(ifile, Loader=yaml.Loader)
                for ydict in yalldata:
                    ydicts.append(ydict)

            for ydict in ydicts:
                for yentry in ydict.values():
                    if 'process' in yentry:
                        importnode = yentry['process']

        # If there is a file ().soc and a directory ().model, then pull the file
        # ().model/().model.v, which is a chip top-level netlist.

        ydicts = []
        has_soc = False
        save_vdir = None
        vdirs = glob.glob(ppath + '/*')
        for vdir in vdirs:
            vnameparts = vdir.split('.')
            if len(vnameparts) > 1 and vnameparts[-1] == 'soc' and os.path.isdir(vdir):
                has_soc = True
            if len(vnameparts) > 1 and vnameparts[-1] == 'model':
                save_vdir = vdir

        if has_soc:
            if save_vdir:
                vdir = save_vdir
                print("INFO:  CloudV project " + vdir + " is a full chip SoC project.")

                vroot = os.path.split(vdir)[1]
                netlistfile = vdir + '/' + vroot + '.v'
                if os.path.exists(netlistfile):
                    print("INFO:  CloudV chip top level verilog is " + netlistfile + ".")
            else:
                print("ERROR:  Expected SoC .model directory not found.")

        # Otherwise, if the project has a build/ directory and a netlist.v file,
        # then set the foundry node accordingly.

        elif os.path.exists(ppath + '/build'):
            vfiles = glob.glob(ppath + '/build/*.v')
            for vfile in vfiles:
                vroot = os.path.splitext(vfile)[0]
                if os.path.splitext(vroot)[1] == '.netlist':
                    netlistfile = ppath + '/build/' + vfile

                    # Pull process and standard cell library from the YAML file
                    # created by CloudV
                    # Use yaml.load_all(), not yaml.load() (see above)

                    if os.path.exists(ppath + '/.ef-config/meta.yaml'):
                        print("Reading YAML file:")
                        ydicts = []
                        with open(ppath + '/.ef-config/meta.yaml', 'r') as ifile:
                            yalldata = yaml.load_all(ifile, Loader=yaml.Loader)
                            for ydict in yalldata:
                                ydicts.append(ydict)

                        for ydict in ydicts:
                            for yentry in ydict.values():
                                if 'process' in yentry:
                                    importnode = yentry['process']
                                if 'stdcell' in yentry:
                                    stdcell = yentry['stdcell']
                    break

        if importnode:
            print("INFO:  Project targets foundry process " + importnode + ".")
        else:
            print("WARNING:  Project does not target any foundry process.")

        newname = self.createproject(value, seedname=pname, importnode=importnode)
        if not newname: return 0		# Canceled in dialog, no action.
        newpath = self.projectdir + '/' + newname

        result = self.install_from_cloudv(ppath, newpath, importnode, stdcell, ydicts)
        if result == None:
            print('Error during import.')
            return None
        elif result == 0:
            return 0    # Canceled
        else:
            return 1    # Success

    #----------------------------------------------------------------------
    # Make a copy of a project in the design folder.
    #----------------------------------------------------------------------

    def copyproject(self, value):
        if not value['values']:
            print('No project selected.')
            return
        # Require copy-to location and confirmation
        badrex1 = re.compile("^\.")
        badrex2 = re.compile(".*[/ \t\n\\\><\*\?].*")
        warning = 'Copy project ' + value['text'] + ' to new project.'
        print('Copy project directory ' + value['values'][0])
        newname = ''
        copylist = []
        elprefs = False
        spprefs = False
        while True:
            copylist = CopyProjectDialog(self, warning, seed=newname).result
            if not copylist:
                return		# Canceled, no action.
            else:
                newname = copylist[0]
                elprefs = copylist[1]
                spprefs = copylist[2]
            newproject = self.projectdir + '/' + newname
            if self.blacklisted(newname):
                warning = newname + ' is not allowed for a project name.'
            elif newname == "":
                warning = 'Please enter a project name.'
            elif badrex1.match(newname):
                warning = 'project name may not start with "."'
            elif badrex2.match(newname):
                warning = 'project name contains illegal characters or whitespace.'
            elif os.path.exists(newproject):
                warning = newname + ' is already a project name.'
            else:
                break

        oldpath = value['values'][0]
        oldname = os.path.split(oldpath)[1]
        patterns = [oldname + '.log']
        if not elprefs:
            patterns.append('.java')
        if not spprefs:
            patterns.append('ngspice')
            patterns.append('pv')

        print("New project name will be " + newname)
        try:
            if os.path.islink(oldpath):
                os.symlink(oldpath, newproject)
            else:
                shutil.copytree(oldpath, newproject, symlinks = True,
			    ignore = shutil.ignore_patterns(*patterns))
        except IOError as e:
            print('Error copying files: ' + str(e))
            return

        # NOTE:  Behavior is for project files to depend on "project_name".  Using
        # the project filename as a project name is a fallback behavior.  If
        # there is a info.yaml file, and it defines a project_name entry, then
        # there is no need to make changes within the project.  If there is
        # no info.yaml file, then create one and set the project_name entry to
        # the old project name, which avoids the need to make changes within
        # the project.

        else:
            # Check info.yaml
            yamlname = newproject + '/info.yaml'

            found = False
            if os.path.isfile(yamlname):
                # Pull the project_name into local store (may want to do this with the
                # datasheet as well)
                with open(yamlname, 'r') as f:
                    datatop = yaml.safe_load(f)                
                    if 'project_name' in datatop['project']:
                        found = True

            if not found:
                pdkdir = self.get_pdk_dir(newproject, path=True)
                yData = self.create_yaml(oldname, pdkdir)                               
                with open(newproject + '/info.yaml', 'w') as ofile:
                    print('---',file=ofile)
                    yaml.dump(yData, ofile)

        # If ngspice and electric prefs were not copied from the source
        # to the target, as recommended, then copy these from the
        # skeleton repository as is done when creating a new project.

        if not spprefs:
            try:
                os.makedirs(newproject + '/ngspice')
                os.makedirs(newproject + '/ngspice/run')
                os.makedirs(newproject + '/ngspice/run/.allwaves')
            except FileExistsError:
                pass
        '''
        if not elprefs:
            # Copy preferences
            deskel = '/ef/efabless/deskel'
            try:
                shutil.copytree(deskel + '/dotjava', newproject + '/elec/.java', symlinks = True)
            except IOError as e:
                print('Error copying files: ' + e)
        '''

#----------------------------------------------------------------------
    # Allow the user to choose the flow of the project
    #----------------------------------------------------------------------
    
    def startflow(self, value):
        projectpath = value['values'][0]
        flow = ''
        warning = 'Select a flow for '+value['text']
        is_subproject = False
        try:
            with open(os.path.expanduser(currdesign), 'r') as f:
                pdirCur = f.read().rstrip()
                if ('subcells' in pdirCur):
                    # subproject is selected
                    is_subproject = True      
        except:
            pass
        if not os.path.exists(projectpath + '/info.yaml'):
            project_pdkdir = self.get_pdk_dir(projectpath, path=True)
            data = self.create_yaml(os.path.split(projectpath)[1], project_pdkdir)
            with open(projectpath + '/info.yaml', 'w') as ofile:
                print('---',file=ofile)
                yaml.dump(data, ofile)
        
        # Read yaml file for the selected flow
        with open(projectpath + '/info.yaml','r') as f:
            data = yaml.safe_load(f)
            project = data['project']
            if 'flow' in project.keys() and project['flow']=='none' or 'flow' not in project.keys():
                while True:
                    try:
                        flow = SelectFlowDialog(self, warning, seed='', is_subproject = is_subproject).result
                    except TypeError:
                        # TypeError occurs when "Cancel" is pressed, just handle exception.
                        return None
                    if not flow:
                        return None	# Canceled, no action.
                    break
                project['flow']=flow
                data['project']=project
                with open(projectpath + '/info.yaml', 'w') as ofile:
                    print('---',file=ofile)
                    yaml.dump(data, ofile)
            else:
                flow = project['flow']
        
        print("Starting "+flow+" flow...")
        if flow.lower() == 'digital':
            self.synthesize()
        
 #----------------------------------------------------------------------
    # Change a project IP to a different name.
    #----------------------------------------------------------------------

    def renameproject(self, value):
        if not value['values']:
            print('No project selected.')
            return

        # Require new project name and confirmation
        badrex1 = re.compile("^\.")
        badrex2 = re.compile(".*[/ \t\n\\\><\*\?].*")
        projname = value['text']

        # Find the IP name for project projname.  If it has a YAML file, then
        # read it and pull the ip-name record.  If not, the fallback position
        # is to assume that the project filename is the project name.

        # Check info.yaml
        projectpath = self.projectdir + '/' + projname
        yamlname = projectpath + '/info.yaml'

        oldname = projname
        if os.path.isfile(yamlname):
            # Pull the ipname into local store (may want to do this with the
            # datasheet as well)
            with open(yamlname, 'r') as f:
                datatop = yaml.safe_load(f)   
                project_data = datatop['project']          
                if 'project_name' in project_data:
                    oldname = project_data['project_name']

        warning = 'Rename IP "' + oldname + '" for project ' + projname + ':'
        print(warning)
        newname = projname
        while True:
            try:
                newname = ProjectNameDialog(self, warning, seed=oldname + '_1').result
            except TypeError:
                # TypeError occurs when "Cancel" is pressed, just handle exception.
                return None
            if not newname:
                return None	# Canceled, no action.

            if self.blacklisted(newname):
                warning = newname + ' is not allowed for an IP name.'
            elif badrex1.match(newname):
                warning = 'IP name may not start with "."'
            elif badrex2.match(newname):
                warning = 'IP name contains illegal characters or whitespace.'
            else:
                break

        # Update everything, including schematic, symbol, layout, JSON file, etc.
        print('New project IP name will be ' + newname + '.')
        rename_project_all(projectpath, newname)

    # class vars: one-time compile of regulare expressions for life of the process
    projNameBadrex1 = re.compile("^[-.]")
    projNameBadrex2 = re.compile(".*[][{}()!/ \t\n\\\><#$\*\?\"'|`~]")
    importProjNameBadrex1 = re.compile(".*[.]bak$")

    # centralize legal projectName check.
    # TODO: Several code sections are not yet converted to use this.
    # TODO: Extend to explain to the user the reason why.
    def validProjectName(self, name):
        return not (self.blacklisted(name) or
                    self.projNameBadrex1.match(name) or
                    self.projNameBadrex2.match(name))

#----------------------------------------------------------------------
    # Import a project or subproject to the project manager
    #----------------------------------------------------------------------
    
    def importproject(self, value):
        warning = "Import project:"
        badrex1 = re.compile("^\.")
        badrex2 = re.compile(".*[/ \t\n\\\><\*\?].*")
        print(warning)
        
        # Find out whether the user wants to import a subproject or project based on what they selected in the treeview
        parent_pdk = ''
        parent_path = ''
        try:
            with open(os.path.expanduser(currdesign), 'r') as f:
                pdirCur = f.read().rstrip()
                if ('subcells' in pdirCur):
                    # subproject is selected
                    parent_path = os.path.split(os.path.split(pdirCur)[0])[0]
                    parent_pdkdir = self.get_pdk_dir(parent_path, path=True)
                    (foundry, foundry_name, node, desc, status) = self.pdkdir2fnd( parent_pdkdir )
                    parent_pdk = foundry + '/' + node
                    warning = 'Import a subproject to '+ parent_path + ':'
                elif (pdirCur[0] == '.'):
                    # the project's 'subproject' of itself is selected
                    parent_path = pdirCur[1:]
                    parent_pdkdir = self.get_pdk_dir(parent_path, path=True)
                    (foundry, foundry_name, node, desc, status) = self.pdkdir2fnd( parent_pdkdir )
                    parent_pdk = foundry + '/' + node
                    warning = 'Import a subproject to '+ parent_path + ':'
                
        except:
            pass
        
        while True:
            try:
                newname, project_pdkdir, projectpath, importoption = ImportDialog(self, warning, seed='', parent_pdk = parent_pdk, parent_path = parent_path, project_dir = self.projectdir).result
            except TypeError:
                # TypeError occurs when "Cancel" is pressed, just handle exception.
                return None
            if not newname:
                return None	# Canceled, no action.
            
            if parent_pdk == '':
                newproject = self.projectdir + '/' + newname
            else:
                newproject = parent_path + '/subcells/' + newname
            break
        
        def make_techdirs(projectpath, project_pdkdir):
            # Recursively create techdirs in project and subproject folders
            if not (os.path.exists(projectpath + '/.config') or os.path.exists(projectpath + '/.ef-config')):
                os.makedirs(projectpath + '/.config')
            if not os.path.exists(projectpath + self.config_path(projectpath) + '/techdir'):
                os.symlink(project_pdkdir, projectpath + self.config_path(projectpath) + '/techdir')
            if os.path.isdir(projectpath + '/subcells'):
                for subproject in os.listdir(projectpath + '/subcells'):
                    subproject_path = projectpath + '/subcells/' + subproject
                    make_techdirs(subproject_path, project_pdkdir)
                    
        make_techdirs(projectpath, project_pdkdir)
        
        # Make symbolic link/copy projects
        if parent_path=='':
            # Create a regular project
            if importoption == "link":
                os.symlink(projectpath, self.projectdir + '/' + newname)
            else:
                shutil.copytree(projectpath, self.projectdir + '/' + newname, symlinks = True)
            if not os.path.exists(projectpath + '/info.yaml'):
                yData = self.create_yaml(newname, project_pdkdir)                             
                with open(projectpath + '/info.yaml', 'w') as ofile:
                    print('---',file=ofile)
                    yaml.dump(yData, ofile)
        else:
            #Create a subproject
            if not os.path.exists(parent_path + '/subcells'):
                os.makedirs(parent_path + '/subcells')
            if importoption == "copy":
                shutil.copytree(projectpath, parent_path + '/subcells/' + newname, symlinks = True)
                if parent_pdkdir != project_pdkdir:
                    self.clean(parent_path + '/subcells/' + newname)
            else:
                os.symlink(projectpath, parent_path + '/subcells/' + newname)
            if not os.path.exists(parent_path + '/subcells/' + newname + '/info.yaml'):
                yData = self.create_yaml(newname, project_pdkdir)                             
                with open(parent_path + '/subcells/' + newname + '/info.yaml', 'w') as ofile:
                    print('---',file=ofile)
                    yaml.dump(yData, ofile)
            self.update_project_views() 
        #----------------------------------------------------------------------
    # "Import As" a dir in import/ as a project. based on renameproject().
    # addWarn is used to augment confirm-dialogue if redirected here via erroneous ImportInto
    #----------------------------------------------------------------------

    def import2project(self, importfile, addWarn=None):
        name = os.path.split(importfile)[1]
        projpath = self.projectdir + '/' + name

        bakname = name + '.bak'
        bakpath = self.projectdir + '/' + bakname
        warns = []
        if addWarn:
            warns += [ addWarn ]

        # Require new project name and confirmation
        confirmPrompt = None    # use default: I am sure I want to do this.
        if os.path.isdir(projpath):
            if warns:
                warns += [ '' ]  # blank line between addWarn and below two Warnings:
            if os.path.isdir(bakpath):
                warns += [ 'Warning: Replacing EXISTING: ' + name + ' AND ' + bakname + '!' ]
            else:
                warns += [ 'Warning: Replacing EXISTING: ' + name + '!' ]
            warns += [ 'Warning: Check for & exit any Electric,magic,qflow... for above project(s)!\n' ]
            confirmPrompt = 'I checked & exited apps and am sure I want to do this.'

        warns += [ 'Confirm import-as new project: ' + name + '?' ]
        warning = '\n'.join(warns)
        confirm = ProtectedConfirmDialog(self, warning, confirmPrompt=confirmPrompt).result
        if not confirm == 'okay':
            return

        print('New project name will be ' + name + '.')
        try:
            if os.path.isdir(projpath):
                if os.path.isdir(bakpath):
                    print('Deleting old project: ' + bakpath);
                    shutil.rmtree(bakpath)
                print('Moving old project ' + name + ' to ' + bakname)
                os.rename(                projpath,           bakpath)
            print("Importing as new project " + name)
            os.rename(importfile, projpath)
            return True
        except IOError as e:
            print("Error importing-as project: " + str(e))
            return None

    #----------------------------------------------------------------------
    # Helper subroutine:
    # Check if a project is a valid project.  Return the name of the
    # datasheet if the project has a valid one in the project top level
    # path.
    #----------------------------------------------------------------------

    def get_datasheet_name(self, dpath):
        if not os.path.isdir(dpath):
            print('Error:  Project is not a folder!')
            return
        # Check for valid datasheet name in the following order:
        # (1) project.json (Legacy)
        # (2) <name of directory>.json (Legacy)
        # (3) not "datasheet.json" or "datasheet_anno.json" 
        # (4) "datasheet.json"
        # (5) "datasheet_anno.json"

        dsname = os.path.split(dpath)[1]
        if os.path.isfile(dpath + '/project.json'):
            datasheet = dpath + '/project.json'
        elif os.path.isfile(dpath + '/' + dsname + '.json'):
            datasheet = dpath + '/' + dsname + '.json'
        else:
            has_generic = False
            has_generic_anno = False
            filelist = os.listdir(dpath)
            for file in filelist[:]:
                if os.path.splitext(file)[1] != '.json':
                    filelist.remove(file)
            if 'datasheet.json' in filelist:
                has_generic = True
                filelist.remove('datasheet.json')
            if 'datasheet_anno.json' in filelist:
                has_generic_anno = True
                filelist.remove('datasheet_anno.json')
            if len(filelist) == 1:
                print('Trying ' + dpath + '/' + filelist[0])
                datasheet = dpath + '/' + filelist[0]
            elif has_generic:
                datasheet + dpath + '/datasheet.json'
            elif has_generic_anno:
                datasheet + dpath + '/datasheet_anno.json'
            else:
                if len(filelist) > 1:
                    print('Error:  Path ' + dpath + ' has ' + str(len(filelist)) +
                            ' valid datasheets.')
                else:
                    print('Error:  Path ' + dpath + ' has no valid datasheets.')
                return None

        if not os.path.isfile(datasheet):
            print('Error:  File ' + datasheet + ' not found.')
            return None
        else:
            return datasheet

    #----------------------------------------------------------------------
    # Run the LVS manager
    #----------------------------------------------------------------------

    def run_lvs(self):
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            # designname = value['text']
            designname = self.project_name
            print('Run LVS on design ' + designname + ' (' + design + ')')
            # use Popen, not run, so that application does not wait for it to exit.
            subprocess.Popen(['netgen','-gui',design, designname])
        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the local characterization checker
    #----------------------------------------------------------------------

    def characterize(self):
        global apps_path
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            # designname = value['text']
            designname = self.project_name
            datasheet = self.get_datasheet_name(design)
            print('Characterize design ' + designname + ' (' + datasheet + ' )')
            if datasheet:
                # use Popen, not run, so that application does not wait for it to exit.
                dsheetroot = os.path.splitext(datasheet)[0]
                subprocess.Popen([apps_path + '/cace.py',
				datasheet])
        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the local synthesis tool (qflow)
    #----------------------------------------------------------------------

    def synthesize(self):
        value = self.projectselect.selected()
        if value:
            design = value['values'][0] # project path
            pdkdir = self.get_pdk_dir(design, path = True)
            qflowdir = pdkdir + '/libs.tech/qflow'
            # designname = value['text']
            designname = self.project_name
            development = self.prefs['devstdcells']
            if not designname:
                # A project without a datasheet has no designname (which comes from
                # the 'ip-name' record in the datasheet JSON) but can still be
                # synthesized.
                designname = design

            # Normally there is one digital design in a project.  However, full-chip
            # designs (in particular) may have multiple sub-projects that are
            # independently synthesized digital blocks.  Find all subdirectories of
            # the top level or subdirectories of qflow that contain a 'qflow_vars.sh'
            # file.  If there is more than one, then present a list.  If there is
            # only one but it is not in 'qflow/', then be sure to pass the actual
            # directory name to the qflow manager.
            qvlist = glob.glob(design + '/*/qflow_vars.sh')
            qvlist.extend(glob.glob(design + '/qflow/*/qflow_vars.sh'))
            if len(qvlist) > 1 or (len(qvlist) == 1 and not os.path.exists(design + '/qflow/qflow_vars.sh')):
                # Generate selection menu
                if len(qvlist) > 1:
                    clist = list(os.path.split(item)[0] for item in qvlist)
                    ppath = ExistingProjectDialog(self, clist, warning="Enter name of qflow project to open:").result
                    if not ppath:
                        return 0		# Canceled in dialog, no action.
                else:
                    ppath = os.path.split(qvlist[0])[0]

                # pname is everything in ppath after matching design:
                pname = ppath.replace(design + '/', '')

                print('Synthesize design in qflow project directory ' + pname)
                print('Loading digital flow manager...')
                #TODO: replace hard-coded path with function that gets the qflow manager path
                if development:
                    subprocess.Popen(['/usr/local/share/qflow/scripts/qflow_manager.py',
				qflowdir, design, '-development', '-subproject=' + pname])
                else:
                    subprocess.Popen(['/usr/local/share/qflow/scripts/qflow_manager.py',
				qflowdir, design, '-subproject=' + pname])
            else:
                print('Synthesize design ' + designname + ' (' + design + ')')
                print('Loading digital flow manager...')
                # use Popen, not run, so that application does not wait for it to exit.
                if development:
                    subprocess.Popen(['/usr/local/share/qflow/scripts/qflow_manager.py',
				qflowdir, design, designname, '-development'])
                else:
                    subprocess.Popen(['/usr/local/share/qflow/scripts/qflow_manager.py',
                qflowdir, design, designname])
        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Switch between showing and hiding the import list (default hidden)
    #----------------------------------------------------------------------

    def import_toggle(self):
        import_state = self.toppane.import_frame.import_header3.cget('text')
        if import_state == '+':
            self.importselect.grid(row = 11, sticky = 'news')
            self.toppane.import_frame.import_header3.config(text='-')
        else:
            self.importselect.grid_forget()
            self.toppane.import_frame.import_header3.config(text='+')

    def import_open(self):
        self.importselect.grid(row = 11, sticky = 'news')
        self.toppane.import_frame.import_header3.config(text='-')

    #----------------------------------------------------------------------
    # Switch between showing and hiding the IP library list (default hidden)
    #----------------------------------------------------------------------

    def library_toggle(self):
        library_state = self.toppane.library_frame.library_header3.cget('text')
        if library_state == '+':
            self.ipselect.grid(row = 8, sticky = 'news')
            self.toppane.library_frame.library_header3.config(text='-')
        else:
            self.ipselect.grid_forget()
            self.toppane.library_frame.library_header3.config(text='+')

    def library_open(self):
        self.ipselect.grid(row = 8, sticky = 'news')
        self.toppane.library_frame.library_header3.config(text='-')

    #----------------------------------------------------------------------
    # Run padframe-calc (today internally invokes libreoffice, we only need cwd set to design project)
    #----------------------------------------------------------------------
    def padframe_calc(self):
        value = self.projectselect.selected()
        if value:
            designname = self.project_name
            self.padframe_calc_work(newname=designname)
        else:
            print("You must first select a project.", file=sys.stderr)

    #------------------------------------------------------------------------
    # Run padframe-calc (today internally invokes libreoffice, we set cwd to design project)
    # Modelled somewhat after 'def importvgl':
    #   Prompt for an existing electric lib.
    #   Prompt for a target cellname (for both mag and electric icon).
    # (The AS vs INTO behavior is incomplete as yet. Used so far with current-project as newname arg).
    #   newname : target project-name (INTO), or None (AS: i.e. prompt to create one).
    # Either newname is given: we PROMPT to pick an existing elecLib;
    # Else PROMPT for new projectName and CREATE it (and use elecLib of same name).
    #------------------------------------------------------------------------
    def padframe_calc_work(self, newname=None):
        elecLib = newname
        isnew = not newname
        if isnew:
            # Use create project code first to generate a valid project space.
            newname = self.createproject(None)
            if not newname: return 0		# Canceled in dialog, no action.
            # print("padframe-calc in new project " + newname + ".")
            elecLib = newname

        # For life of this projectManager process, store/recall last PadFrame Settings per project
        global project2pfd
        try:
            project2pfd
        except:
            project2pfd = {}
        if newname not in project2pfd:
            project2pfd[newname] = {"libEntry": None, "cellName": None}

        ppath = self.projectdir + '/' + newname
        choices = self.get_elecLib_list(newname)
        if not choices:
            print( "Aborted: No existing electric libraries found to write symbol into.")
            return 0
                
        elecLib = newname + '/elec/' + elecLib + '.delib'
        elecLib = project2pfd[newname]["libEntry"] or elecLib
        cellname = project2pfd[newname]["cellName"] or "padframe"
        libAndCell = ExistingElecLibCellDialog(self, None, title="PadFrame Settings", plist=choices, descPost="of icon&layout", seedLibNm=elecLib, seedCellNm=cellname).result
        if not libAndCell:
            return 0		# Canceled in dialog, no action.
            
        (elecLib, cellname) = libAndCell
        if not cellname:
            return 0		# empty cellname, no action.

        project2pfd[newname]["libEntry"] = elecLib
        project2pfd[newname]["cellName"] = cellname

        # Isolate just electric lib name without extension. ../a/b.delib -> b
        elecLib = os.path.splitext(os.path.split(elecLib)[-1])[0]
        print("padframe-calc in project: %s, elecLib: %s, cellName: %s" % (newname, elecLib, cellname))

        export = dict(os.environ)
        export['EF_DESIGNDIR'] = ppath
        subprocess.Popen(['/ef/apps/bin/padframe-calc', elecLib, cellname], cwd = ppath, env = export)

        # not yet any useful return value or reporting of results here in projectManager...
        return 1

    #----------------------------------------------------------------------
    # Run the schematic editor (tool as given by user preference)
    #----------------------------------------------------------------------

    def edit_schematic(self):
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            
            pdktechdir = design + self.config_path(design)+'/techdir/libs.tech'
            
            applist = self.list_valid_schematic_editors(pdktechdir)

            if len(applist)==0:
                print("Unable to find a valid schematic editor.")
                return
                
            # If the preferred app is in the list, then use it.
            
            if self.prefs['schemeditor'] in applist:
                appused = self.prefs['schemeditor']
            else:
                appused = applist[0]

            if appused == 'xcircuit':
                return self.edit_schematic_with_xcircuit()
            elif appused == 'xschem':
                return self.edit_schematic_with_xschem()
            elif appused == 'electric':
                return self.edit_schematic_with_electric()
            else:
                print("Unknown/unsupported schematic editor " + appused + ".", file=sys.stderr)

        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the schematic editor (electric)
    #----------------------------------------------------------------------

    def edit_schematic_with_electric(self):
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            # designname = value['text']
            # self.project_name set by setcurrent.  This is the true project
            # name, as opposed to the directory name.
            designname = self.project_name
            print('Edit schematic ' + designname + ' (' + design + ' )')
            # Collect libs on command-line;  electric opens these in Explorer
            libs = []
            ellibrex = re.compile(r'^(tech_.*|ef_examples)\.[dj]elib$', re.IGNORECASE)

            self.reinitElec(design)

            # /elec and /.java are prerequisites for running electric
            if not os.path.exists(design + '/elec'):
                print("No path to electric design folder.")
                return

            if not os.path.exists(design + '/elec/.java'):
                print("No path to electric .java folder.")
                return

            # Fix the LIBDIRS file if needed
            #fix_libdirs(design, create = True)

            # Check for legacy directory (missing .ef-config and/or .ef-config/techdir);
            # Handle as necessary.

            # don't sometimes yield pdkdir as some subdir of techdir
            pdkdir = design + self.config_path(design) + '/techdir/'
            if not os.path.exists(pdkdir):
                export = dict(os.environ)
                export['EF_DESIGNDIR'] = design
                '''
                p = subprocess.run(['/ef/efabless/bin/ef-config', '-sh', '-t'],
			stdout = subprocess.PIPE, env = export)
                config_out = p.stdout.splitlines()
                for line in config_out:
                    setline = line.decode('utf-8').split('=')
                    if setline[0] == 'EF_TECHDIR':
                        pdkdir = re.sub("[';]", "", setline[1])
                '''

            for subpath in ('libs.tech/elec/', 'libs.ref/elec/'):
                pdkelec = os.path.join(pdkdir, subpath)
                if os.path.exists(pdkelec) and os.path.isdir(pdkelec):
                    # don't use os.walk(), it is recursive, wastes time
                    for entry in os.scandir(pdkelec):
                        if ellibrex.match(entry.name):
                                libs.append(entry.path)

            # Locate most useful project-local elec-lib to open on electric cmd-line.
            designroot = os.path.split(design)[1]
            finalInDesDirLibAdded = False
            if os.path.exists(design + '/elec/' + designname + '.jelib'):
                libs.append(design + '/elec/' + designname + '.jelib')
                finalInDesDirLibAdded = True
            elif os.path.isdir(design + '/elec/' + designname + '.delib'):
                libs.append(design + '/elec/' + designname + '.delib')
                finalInDesDirLibAdded = True
            else:
                # Alternative path is the project name + .delib
                if os.path.isdir(design + '/elec/' + designroot + '.delib'):
                    libs.append(design + '/elec/' + designroot + '.delib')
                    finalInDesDirLibAdded = True

            # Finally, check for the one absolute requirement for a project,
            # which is that there must be a symbol designname + .ic in the
            # last directory.  If not, then do a search for it.
            if not finalInDesDirLibAdded or not os.path.isfile(libs[-1] + '/' + designname + '.ic'):
                delibdirs = os.listdir(design + '/elec')
                for delibdir in delibdirs:
                    if os.path.splitext(delibdir)[1] == '.delib':
                        iconfiles = os.listdir(design + '/elec/' + delibdir)
                        for iconfile in iconfiles:
                            if iconfile == designname + '.ic':
                                libs.append(design + '/elec/' + delibdir)
                                finalInDesDirLibAdded = True
                                break
            
            # Above project-local lib-adds are all conditional on finding some lib
            # with an expected name or content: all of which may fail.
            # Force last item ALWAYS to be 'a path' in the project's elec/ dir.
            # Usually it's a real library (found above). (If lib does not exist the messages
            # window does get an error message). But the purpose is for the universal side-effect:
            # To EVERY TIME reseed the File/OpenLibrary dialogue WorkDir to start in
            # project's elec/ dir; avoid it starting somewhere in the PDK, which
            # is what will happen if last actual cmd-line arg is a lib in the PDK, and
            # about which users have complained. (Optimal fix needs electric enhancement).
            if not finalInDesDirLibAdded:
                libs.append(design + '/elec/' + designroot + '.delib')

            # Pull last item from libs and make it a command-line argument.
            # All other libraries become part of the EOPENARGS environment variable,
            # and electric is called with the elecOpen.bsh script.
            indirectlibs = libs[:-1]
            export = dict(os.environ)
            arguments = []
            if indirectlibs:
                export['EOPENARGS'] = ' '.join(indirectlibs)
                arguments.append('-s')
                arguments.append('/ef/efabless/lib/elec/elecOpen.bsh')

            try:
                arguments.append(libs[-1])
            except IndexError:
                print('Error:  Electric project directories not set up correctly?')
            else:
                subprocess.Popen(['electric', *arguments], cwd = design + '/elec',
				env = export)
        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the schematic editor (xcircuit)
    #----------------------------------------------------------------------

    def edit_schematic_with_xcircuit(self):
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            # designname = value['text']
            # self.project_name set by setcurrent.  This is the true project
            # name, as opposed to the directory name.
            designname = self.project_name
            print('Edit schematic ' + designname + ' (' + design + ' )')
            xcircdirpath = design + '/xcirc'
            pdkdir = design + self.config_path(design) + '/techdir/libs.tech/xcircuit'

            # /xcirc directory is a prerequisite for running xcircuit.  If it doesn't
            # exist, create it and seed it with .xcircuitrc from the tech directory
            if not os.path.exists(xcircdirpath):
                os.makedirs(xcircdirpath)

            # Copy xcircuit startup file from tech directory
            hasxcircrcfile = os.path.exists(xcircdirpath + '/.xcircuitrc')
            if not hasxcircrcfile:
                if os.path.exists(pdkdir + '/xcircuitrc'):
                    shutil.copy(pdkdir + '/xcircuitrc', xcircdirpath + '/.xcircuitrc')

            # Command line argument is the project name
            arguments = [design + '/xcirc' + designname]
            subprocess.Popen(['xcircuit', *arguments])
        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the schematic editor (xschem)
    #----------------------------------------------------------------------

    def edit_schematic_with_xschem(self):
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            # self.project_name set by setcurrent.  This is the true project
            # name, as opposed to the directory name.
            designname = self.project_name
            print('Edit schematic ' + designname + ' (' + design + ' )')
            xschemdirpath = design + '/xschem'
            
            pdkdir = design + self.config_path(design) + '/techdir/libs.tech/xschem'

            
            # /xschem directory is a prerequisite for running xschem.  If it doesn't
            # exist, create it and seed it with xschemrc from the tech directory
            if not os.path.exists(xschemdirpath):
                os.makedirs(xschemdirpath)

            # Copy xschem startup file from tech directory
            hasxschemrcfile = os.path.exists(xschemdirpath + '/xschemrc')
            if not hasxschemrcfile:
                if os.path.exists(pdkdir + '/xschemrc'):
                    shutil.copy(pdkdir + '/xschemrc', xschemdirpath + '/xschemrc')

            # Command line argument is the project name.  The "-r" option is recommended if there
            # is no stdin/stdout piping.
            
            arguments = ['-r', design + '/xschem/' + designname]
            subprocess.Popen(['xschem', *arguments])
        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the layout editor (magic or klayout)
    #----------------------------------------------------------------------

    def edit_layout(self):
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            pdktechdir = design + self.config_path(design) + '/techdir/libs.tech'
            
            applist = self.list_valid_layout_editors(pdktechdir)

            if len(applist)==0:
                print("Unable to find a valid layout editor.")
                return

            # If the preferred app is in the list, then use it.
            if self.prefs['layouteditor'] in applist:
                appused = self.prefs['layouteditor']
            else:
                appused = applist[0]

            if appused == 'magic':
                return self.edit_layout_with_magic()
            elif appused == 'klayout':
                return self.edit_layout_with_klayout()
            elif appused == 'electric':
                return self.edit_layout_with_electric()
            else:
                print("Unknown/unsupported layout editor " + appused + ".", file=sys.stderr)

        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the magic layout editor
    #----------------------------------------------------------------------

    def edit_layout_with_magic(self):
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            # designname = value['text']
            designname = self.project_name
            
            pdkdir = ''
            pdkname = ''
            
            if os.path.exists(design + '/.ef-config/techdir/libs.tech'):
                pdkdir = design + '/.ef-config/techdir/libs.tech/magic/current'
                pdkname = os.path.split(os.path.realpath(design + '/.ef-config/techdir'))[1]
            elif os.path.exists(design + '/.config/techdir/libs.tech'):
                pdkdir = design + '/.config/techdir/libs.tech/magic'
                pdkname = os.path.split(os.path.realpath(design + '/.config/techdir'))[1]
            

            # Check if the project has a /mag directory.  Create it and
            # put the correct .magicrc file in it, if it doesn't.
            magdirpath = design + '/mag'
            hasmagdir = os.path.exists(magdirpath)
            if not hasmagdir:
                os.makedirs(magdirpath)

            hasmagrcfile = os.path.exists(magdirpath + '/.magicrc')
            if not hasmagrcfile:
                shutil.copy(pdkdir + '/' + pdkname + '.magicrc', magdirpath + '/.magicrc')

            # Check if the .mag file exists for the project.  If not,
            # generate a dialog.
            magpath = design + '/mag/' + designname + '.mag'
            netpath = design + '/spi/' + designname + '.spi'
            # print("magpath is " + magpath)
            hasmag = os.path.exists(magpath)
            hasnet = os.path.exists(netpath)
            if hasmag:
                if hasnet:
                    statbuf1 = os.stat(magpath)
                    statbuf2 = os.stat(netpath)
                    # No specific action for out-of-date layout.  To be done:
                    # Check contents and determine if additional devices need to
                    # be added to the layout.  This may be more trouble than it's
                    # worth.
                    #
                    # if statbuf2.st_mtime > statbuf1.st_mtime:
                    #     hasmag = False

            if not hasmag:
                # Does the project have any .mag files at all?  If so, the project
                # layout may be under a name different than the project name.  If
                # so, present the user with a selectable list of layout names,
                # with the option to start a new layout or import from schematic.

                maglist = os.listdir(design + '/mag/')
                if len(maglist) > 1:
                    # Generate selection menu
                    warning = 'No layout matches IP name ' + designname + '.'
                    maglist = list(item for item in maglist if os.path.splitext(item)[1] == '.mag')
                    clist = list(os.path.splitext(item)[0] for item in maglist)
                    ppath = EditLayoutDialog(self, clist, ppath=design,
					pname=designname, warning=warning,
					hasnet=hasnet).result
                    if not ppath:
                        return 0		# Canceled in dialog, no action.
                    elif ppath != '(New layout)':
                        hasmag = True
                        designname = ppath
                elif len(maglist) == 1:
                    # Only one magic file, no selection, just bring it up.
                    designname = os.path.split(maglist[0])[1]
                    hasmag = True

            if not hasmag:
                populate = NewLayoutDialog(self, "No layout for project.").result
                if not populate:
                    return 0	# Canceled, no action.
                elif populate():
                    # Name of PDK deprecated.  The .magicrc file in the /mag directory
                    # will load the correct PDK and specify the proper library for the
                    # low-level device namespace, which may not be the same as techdir.
                    # NOTE:  netlist_to_layout script will attempt to generate a
                    # schematic netlist if one does not exist.

                    print('Running /ef/efabless/bin/netlist_to_layout.py ../spi/' + designname + '.spi')
                    try:
                        p = subprocess.run(['/ef/efabless/bin/netlist_to_layout.py',
					'../spi/' + designname + '.spi'],
					stdin = subprocess.PIPE, stdout = subprocess.PIPE,
					stderr = subprocess.PIPE, cwd = design + '/mag')
                        if p.stderr:
                            err_string = p.stderr.splitlines()[0].decode('utf-8')
                            # Print error messages to console
                            print(err_string)

                    except subprocess.CalledProcessError as e:
                        print('Error running netlist_to_layout.py: ' + e.output.decode('utf-8'))
                    else:
                        if os.path.exists(design + '/mag/create_script.tcl'):
                            with open(design + '/mag/create_script.tcl', 'r') as infile:
                                magproc = subprocess.run(['/ef/apps/bin/magic',
					'-dnull', '-noconsole', '-rcfile ',
					pdkdir + '/' + pdkname + '.magicrc', designname],
					stdin = infile, stdout = subprocess.PIPE,
					stderr = subprocess.PIPE, cwd = design + '/mag')
                            print("Populated layout cell")
                            # os.remove(design + '/mag/create_script.tcl')
                        else:
                            print("No device generating script was created.", file=sys.stderr)

            print('Edit layout ' + designname + ' (' + design + ' )')

            magiccommand = ['magic']
            # Select the graphics package used by magic from the profile settings.
            if 'magic-graphics' in self.prefs:
                magiccommand.extend(['-d', self.prefs['magic-graphics']])
            # Check if .magicrc predates the latest and warn if so.
            statbuf1 = os.stat(design + '/mag/.magicrc')
            statbuf2 = os.stat(pdkdir + '/' + pdkname + '.magicrc')
            if statbuf2.st_mtime > statbuf1.st_mtime:
                print('NOTE:  File .magicrc predates technology startup file.  Using default instead.')
                magiccommand.extend(['-rcfile', pdkdir + '/' + pdkname + '.magicrc'])
            magiccommand.append(designname)

            # Run magic and don't wait for it to finish
            subprocess.Popen(magiccommand, cwd = design + '/mag')
        else:
            print("You must first select a project.", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the klayout layout editor
    #----------------------------------------------------------------------

    def edit_layout_with_klayout(self):
        value = self.projectselect.selected()
        print("Klayout unsupported from project manager (work in progress);  run manually", file=sys.stderr)

    #----------------------------------------------------------------------
    # Run the electric layout editor
    #----------------------------------------------------------------------

    def edit_layout_with_electric(self):
        value = self.projectselect.selected()
        print("Electric layout editing unsupported from project manager (work in progress);  run manually", file=sys.stderr)

    #----------------------------------------------------------------------
    # Upload design to the marketplace
    # NOTE:  This is not being called by anything.  Use version in the
    # characterization script, which can check for local results before
    # approving (or forcing) an upload.
    #----------------------------------------------------------------------

    def upload(self):
        '''
        global apps_path
        value = self.projectselect.selected()
        if value:
            design = value['values'][0]
            # designname = value['text']
            designname = self.project_name
            print('Upload design ' + designname + ' (' + design + ' )')
            subprocess.run(['/ef/apps/bin/withnet',
			apps_path + '/cace_design_upload.py',
			design, '-test'])
	'''

    #--------------------------------------------------------------------------

    # Runs whenever a user selects a project
    def setcurrent(self, value):
        global currdesign
        treeview = value.widget
        selection = treeview.item(treeview.selection()) # dict with text, values, tags, etc. as keys
        pname = selection['text']
        pdir = treeview.selection()[0]  # iid of the selected project
        #print("setcurrent returned value " + pname)
        metapath = os.path.expanduser(currdesign)
        if not os.path.exists(metapath):
            os.makedirs(os.path.split(metapath)[0], exist_ok=True)
        with open(metapath, 'w') as f:
            f.write(pdir + '\n')

        # Pick up the PDK from "values", use it to find the PDK folder, determine
        # if it has a "magic" subfolder, and enable/disable the "Edit Layout"
        # button accordingly
        
        svalues = selection['values']
        #print("svalues :"+str(svalues))
        pdkitems = svalues[1].split()
        pdkdir = ''
        
        ef_style=False
        
        if os.path.exists(svalues[0] + '/.config'):
            pdkdir = svalues[0] + '/.config/techdir'
        elif os.path.exists(svalues[0] + '/.ef-config'):
            pdkdir = svalues[0] + '/.ef-config/techdir'
            ef_style=True
        
        if pdkdir == '':
            print('No pdkname found; layout editing disabled')
            self.toppane.appbar.layout_button.config(state='disabled')
        else:
            try:
                if ef_style:
                    subf = os.listdir(pdkdir + '/libs.tech/magic/current')
                else:
                    subf = os.listdir(pdkdir + '/libs.tech/magic')
            except:
                print('PDK ' + pdkname + ' has no layout setup; layout editing disabled')
                self.toppane.appbar.layout_button.config(state='disabled') 
        
        # If the selected project directory has a JSON file and netlists in the "spi"
        # and "testbench" folders, then enable the "Characterize" button;  else disable
        # it.
        # NOTE:  project.json is the preferred name for the datasheet
        # file.  However, the .spi file, .delib file, etc., all have the name of the
        # project from "project_name" in the info.yaml file, which is separate from the datasheet.

        found = False
        ppath = selection['values'][0]
        yamlname = ppath + '/info.yaml'
        
        if os.path.isfile(yamlname):
            # Pull the project_name into local store
            with open(yamlname, 'r') as f:
                datatop = yaml.safe_load(f)
                project_data = datatop['project']
                ipname = project_data['project_name']
                self.project_name = ipname
        else:
            print('Setting project ip-name from the project folder name.')
            self.project_name = pname
        jsonname = ppath + '/project.json'
        if os.path.isfile(jsonname):
            with open(jsonname, 'r') as f:
                datatop = json.load(f)
                dsheet = datatop['data-sheet']
                found = True
            # Do not specifically prohibit opening the characterization app if
            # there is no schematic or netlist.  Otherwise the user is prevented
            # even from seeing the electrical parameters.  Let the characterization
            # tool allow or prohibit simulation based on this.
            # if os.path.exists(ppath + '/spi'):
            #     if os.path.isfile(ppath + '/spi/' + ipname + '.spi'):
            #         found = True
            #
            # if found == False and os.path.exists(ppath + '/elec'):
            #     if os.path.isdir(ppath + '/elec/' + ipname + '.delib'):
            #         if os.path.isfile(ppath + '/elec/' + ipname + '.delib/' + ipname + '.sch'):
            #             found = True
        else:
            # Use 'pname' as the default project name.
            print('No characterization file ' + jsonname)

        # If datasheet has physical parameters but not electrical parameters, then it's okay
        # for it not to have a testbench directory;  it's still valid.  However, having
        # neither physical nor electrical parameters means there's nothing to characterize.
        if found and 'electrical-params' in dsheet and len(dsheet['electrical-params']) > 0:
            if not os.path.isdir(ppath + '/testbench'):
                print('No testbench directory for eletrical parameter simulation methods.', file=sys.stderr)
                found = False
        elif found and not 'physical-params' in dsheet:
            print('Characterization file defines no characterization tests.', file=sys.stderr)
            found = False
        elif found and 'physical-params' in dsheet and len(dsheet['physical-params']) == 0:
            print('Characterization file defines no characterization tests.', file=sys.stderr)
            found = False

        if found == True:
            self.toppane.appbar.char_button.config(state='enabled')
        else:
            self.toppane.appbar.char_button.config(state='disabled')

        # Warning: temporary hack (Tim, 1/9/2018)
        # Pad frame generator is currently limited to the XH035 cells, so if the
        # project PDK is not XH035, disable the pad frame button

        if len(pdkitems) > 1 and pdkitems[1] == 'EFXH035B':
            self.toppane.appbar.padframeCalc_button.config(state='enabled')
        else:
            self.toppane.appbar.padframeCalc_button.config(state='disabled')

#----------------------------------------------------------------------------
# Main application
#----------------------------------------------------------------------------

if __name__ == '__main__':
    faulthandler.register(signal.SIGUSR2)

    ProjectManager(root)
    if deferLoad:
        # Without this, mainloop may find and run very short clock-delayed
        # events before the main form displays. With it, the first project
        # load can be scheduled using after-time=0
        root.update_idletasks()
    root.mainloop()
