#!/usr/bin/env python3 -B
#
#--------------------------------------------------------
# Open Galaxy Project Manager GUI.
#
# This is a Python tkinter script that handles local
# project management.  It is meant as a replacement for
# appsel_zenity.sh
#
#--------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# September 9, 2016
# Modifications 2017, 2018
# Version 1.0
#--------------------------------------------------------

import sys
# Require python 3.5.x (and not python 3.6.x). Without this trap here, in several
# instances of VMs where /usr/bin/python3 symlinked to 3.6.x by mistake, it manifests
# as (misleading) errors like: ImportError: No module named 'yaml'
#
# '%x' % sys.hexversion  ->  '30502f0'

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

# globals
theProg = sys.argv[0]
root = tkinter.Tk()      # WARNING: must be exactly one instance of Tk; don't call again elsewhere

# 4 configurations based on booleans: splash,defer
# n,n:  no splash, show only form when completed: LEGACY MODE, user confused by visual lag.
# n,y:  no splash but defer projLoad: show an empty form ASAP
# y,n:  yes splash, and wait for projLoad before showing completed form
# y,y:  yes splash, but also defer projLoad: show empty form ASAP

# deferLoad = False        # LEGACY: no splash, and wait for completed form
# doSplash = False

deferLoad = True         # True: display GUI before (slow) loading of projects, so no splash:
doSplash = not deferLoad # splash IFF GUI-construction includes slow loading of projects

# deferLoad = False        # load projects before showing form, so need splash:
# doSplash = not deferLoad # splash IFF GUI-construction includes slow loading of projects

# deferLoad = True         # here keep splash also, despite also deferred-loading
# doSplash = True

#------------------------------------------------------
# Splash screen: display ASAP: BEFORE bulk of imports.
#------------------------------------------------------

class SplashScreen(tkinter.Toplevel):
    """Project Management Splash Screen"""

    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        parent.withdraw()
        #EFABLESS PLATFORM
        #image = tkinter.PhotoImage(file="/ef/efabless/opengalaxy/og_splashscreen50.gif")
        label = ttk.Label(self, image=image)
        label.pack()

        # required to make window show before the program gets to the mainloop
        self.update_idletasks()

import faulthandler
import signal

# SplashScreen here. fyi: there's a 2nd/later __main__ section for main app
splash = None     # a global
if __name__ == '__main__':
    faulthandler.register(signal.SIGUSR2)
    if doSplash:
        splash = SplashScreen(root)

import io
import os
import re
import json
import yaml
import shutil
import tarfile
import datetime
import subprocess
import contextlib
import tempfile
import glob

import tksimpledialog
import tooltip
from rename_project import rename_project_all
#from fix_libdirs import fix_libdirs
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

import config

# Global name for design directory
designdir = 'design'
# Global name for import directory
importdir = 'import'
# Global name for cloudv directory
cloudvdir = 'cloudv'
# Global name for archived imports project sub-directory
archiveimportdir = 'imported'
# Global name for current design file
#EFABLESS PLATFORM
currdesign = '~/.open_pdks/currdesign'
prefsfile = '~/.open_pdks/prefs.json'


#---------------------------------------------------------------
# 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=''):
        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
        #TODO: Replace with PREFIX
        for pdkdir_lr in glob.glob('/usr/share/pdk/*/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()
        self.update_idletasks()     # erase small initial frame asap
        self.init_gui()
        parent.protocol("WM_DELETE_WINDOW", self.on_quit)
        if splash:
            splash.destroy()
        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

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

        # if deferLoad:         # temp. for testing... open all panes
        #     allPaneOpen = True

        # 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(config.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')

        # Put logo image in corner.  Ignore if something goes wrong, as this
        # is only decorative.  Note: ef_logo must be kept as a record in self,
        # or else it gets garbage collected.
        try:
            #EFABLESS PLATFORM
            self.ef_logo = tkinter.PhotoImage(file='/ef/efabless/opengalaxy/efabless_logo_small.gif')
            self.toppane.user_frame.logo = ttk.Label(self.toppane.user_frame, image=self.ef_logo)
            self.toppane.user_frame.logo.pack(side = 'left', padx = 5)
        except:
            pass

        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

        # 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' ,
			config.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
        # 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([config.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/current/' + 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')

        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):
        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([config.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):
        '''
        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',
			config.apps_path + '/cace_design_upload.py',
			design, '-test'])
	'''

    #--------------------------------------------------------------------------
    # Upload a datasheet to the marketplace (Administrative use only, for now)
    #--------------------------------------------------------------------------

    # def make_challenge(self):
    #      importp = self.cur_import
    #      print("Make a Challenge from import " + importp + "!")
    #      # subprocess.run([config.apps_path + '/cace_import_upload.py', importp, '-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 app. fyi: there's a 2nd/earlier __main__ section for splashscreen
if __name__ == '__main__':
    ProjectManager(root)
    if deferLoad:
        # Without this, mainloop may find&run very short clock-delayed events BEFORE main form display.
        # With it 1st project-load can be scheduled using after-time=0 (needn't tune a delay like 100ms).
        root.update_idletasks()
    root.mainloop()
