diff --git a/common/project_manager.py b/common/project_manager.py
new file mode 100755
index 0000000..73ff0d8
--- /dev/null
+++ b/common/project_manager.py
@@ -0,0 +1,4138 @@
+#!/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):
+    """Open Galaxy 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):
+        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, node, desc, status) = OpenGalaxyManager.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])
+
+        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:
+            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):
+            dname = os.path.split(ppath)[1]
+            jname = ppath + '/' + dname + '.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'
+
+#------------------------------------------------------
+# Open Galaxy Manager class
+#------------------------------------------------------
+
+class OpenGalaxyManager(ttk.Frame):
+    """Open Galaxy 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('Open Galaxy 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 ~/.efmeta/currdesign and set the selection.
+        try:
+            with open(os.path.expanduser(currdesign), 'r') as f:
+                pnameCur = f.read().rstrip()
+        except:
+            pnameCur = 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=pnameCur, natSort=True)
+        self.projectselect.populate("Available Projects:", projectlist,
+			[["Create", True, self.createproject],
+			 ["Copy", False, self.copyproject],
+			 ["Rename IP", False, self.renameproject],
+			 ["<CloudV", True, self.cloudvimport],
+			 ["Clean", False, self.cleanproject],
+			 ["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")
+        tooltip.ToolTip(self.projectselect.get_button(1), text="Make a copy of an entire project")
+        tooltip.ToolTip(self.projectselect.get_button(2), text="Rename a project folder")
+        tooltip.ToolTip(self.projectselect.get_button(3), text="Import CloudV project as new project")
+        tooltip.ToolTip(self.projectselect.get_button(4), text="Clean simulation data from project")
+        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 pnameCur:
+            try:
+                curitem = next(item for item in projectlist if pnameCur == os.path.split(item)[1])
+            except StopIteration:
+                pass
+            else:
+                if curitem:
+                    self.projectselect.setselect(pnameCur)
+
+        # 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")
+            
+    def config_path(self, path):
+        #returns the 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 FileNotFoundError('Neither '+path+'/.config nor '+path+'/.ef-config exists.')
+
+    #------------------------------------------------------------------------
+    # Check if a name is blacklisted for being a project folder
+    #------------------------------------------------------------------------
+
+    def blacklisted(self, dirname):
+        # Blacklist:  Do not show files of these names:
+        blacklist = [importdir, 'ip', 'upload', 'export', 'lost+found']
+        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' ,
+			og_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 = list(item for item in os.listdir(self.projectdir) if
+			os.path.isdir(self.projectdir + '/' + 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.projectdir + '/' + item for item in projectlist]
+        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 = ''
+        node = ''
+        description = ''
+        status = 'active'
+        if pdkdir:
+            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 'node' in nodeinfo:
+                    node = nodeinfo['node']
+                if 'description' in nodeinfo:
+                    description = nodeinfo['description']
+                if 'status' in nodeinfo:
+                    status = nodeinfo['status']
+                return foundry, 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 'node' in nodeinfo:
+                    node = nodeinfo['node']
+                if 'description' in nodeinfo:
+                    description = nodeinfo['description']
+                if 'status' in nodeinfo:
+                    status = nodeinfo['status']
+            
+
+        return foundry, node, description, status
+
+    #------------------------------------------------------------------------
+    # 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, 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 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
+
+    #------------------------------------------------------------------------
+    # 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 + '/project.json'):
+                    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 importjson(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 JSON 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.
+        # New behavior 12/2018:  JSON file is always called 'project.json'.
+        # Also support legacy JSON name if it exists (don't generate files with
+        # both names)
+
+        jsonfile = newproject + '/project.json'
+        if not os.path.isfile(jsonfile):
+            if os.path.isfile(newproject + '/' + projname + '.json'):
+                jsonfile = newproject + '/' + projname + '.json'
+
+        try:
+            shutil.copy(importfile, jsonfile)
+        except IOError as e:
+            print('Error copying files: ' + str(e))
+            return None
+        else:
+            # If filename is 'project.json' then it does not need to be changed.
+            # This is for legacy name support only.
+            if jsonfile != newproject + '/project.json':
+                shutil.move(jsonfile, newproject + '/' + newname + '.json')
+
+        # (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)
+
+    #------------------------------------------------------------------------
+    # 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)
+
+    #------------------------------------------------------------------------
+    # 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
+
+    #------------------------------------------------------------------------
+    # 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 Open Galaxy 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/og_gui_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
+        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
+        shutil.rmtree(value['values'][0])
+
+    #----------------------------------------------------------------------
+    # 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
+        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):
+        # 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']
+        while True:
+            try:
+                if seedname:
+                    newname, newpdk = NewProjectDialog(self, warning, seed=seedname, importnode=importnode, development=development).result
+                else:
+                    newname, newpdk = NewProjectDialog(self, warning, seed='', importnode=importnode, development=development).result
+            except TypeError:
+                # TypeError occurs when "Cancel" is pressed, just handle exception.
+                return None
+            if not newname:
+                return None	# Canceled, no action.
+
+            newproject = self.projectdir + '/' + 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
+        
+        try:
+            
+            subprocess.Popen([config.apps_path + '/create_project.py', newproject, newpdk])
+            
+        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 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:
+            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 "ip-name".  Using
+        # the project filename as a project name is a fallback behavior.  If
+        # there is a project.json file, and it defines an ip-name entry, then
+        # there is no need to make changes within the project.  If there is
+        # no project.json file, then create one and set the ip-name entry to
+        # the old project name, which avoids the need to make changes within
+        # the project.
+
+        else:
+            # Check project.json
+            jsonname = newproject + '/project.json'
+            legacyname = newproject + '/' + oldname + '.json'
+            if not os.path.isfile(jsonname):
+                if os.path.isfile(legacyname):
+                    jsonname = legacyname
+
+            found = False
+            if os.path.isfile(jsonname):
+                # Pull the ipname into local store (may want to do this with the
+                # datasheet as well)
+                with open(jsonname, 'r') as f:
+                    datatop = json.load(f)
+                    dsheet = datatop['data-sheet']
+                    if 'ip-name' in dsheet:
+                        found = True
+
+            if not found:
+                jData = self.create_ad_hoc_json(oldname, newproject)
+                with open(newproject + '/project.json', 'w') as ofile:
+                    json.dump(jData, ofile, indent = 4)
+
+        # 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)
+
+    #----------------------------------------------------------------------
+    # 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 JSON 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 project.json
+        projectpath = self.projectdir + '/' + projname
+        jsonname = projectpath + '/project.json'
+        legacyname = projectpath + '/' + projname + '.json'
+        if not os.path.isfile(jsonname):
+            if os.path.isfile(legacyname):
+                jsonname = legacyname
+
+        oldname = projname
+        if os.path.isfile(jsonname):
+            # Pull the ipname into local store (may want to do this with the
+            # datasheet as well)
+            with open(jsonname, 'r') as f:
+                datatop = json.load(f)
+                dsheet = datatop['data-sheet']
+                if 'ip-name' in dsheet:
+                    oldname = dsheet['ip-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 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]
+            # 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)
+                if development:
+                    subprocess.Popen([config.apps_path + '/qflow_manager.py',
+				design, '-development', '-subproject=' + pname])
+                else:
+                    subprocess.Popen([config.apps_path + '/qflow_manager.py',
+				design, '-subproject=' + pname])
+            else:
+                print('Synthesize design ' + designname + ' (' + design + ')')
+                # use Popen, not run, so that application does not wait for it to exit.
+                if development:
+                    subprocess.Popen([config.apps_path + '/qflow_manager.py',
+				design, designname, '-development'])
+                else:
+                    subprocess.Popen([config.apps_path + '/qflow_manager.py',
+				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',
+			og_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([og_config.apps_path + '/cace_import_upload.py', importp, '-test'])
+
+    def setcurrent(self, value):
+        global currdesign
+        treeview = value.widget
+        selection = treeview.item(treeview.selection())
+        pname = selection['text']
+        #print("setcurrent returned value " + pname)
+        efmetapath = os.path.expanduser(currdesign)
+        if not os.path.exists(efmetapath):
+            os.makedirs(os.path.split(efmetapath)[0], exist_ok=True)
+        with open(efmetapath, 'w') as f:
+            f.write(pname + '\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']
+        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') 
+        '''
+        svalues = selection['values'][1]
+        print('selection: '+str(selection))
+        pdkitems = svalues.split()
+        print('Contents of pdkitems: '+str(pdkitems))
+        pdkname = ''
+        if ':' in pdkitems:
+            pdkitems.remove(':')
+        if len(pdkitems) == 2:
+            # New behavior Sept. 2017, have to cope with <foundry>.<N> directories, ugh.
+            pdkdirs = os.listdir('/usr/share/pdk/')
+            #TODO: pdkdirs = os.listdir('PREFIX/pdk/')
+            
+            for pdkdir in pdkdirs:
+                if pdkitems[0] == pdkdir:
+                    pdkname = pdkdir
+                    #TODO: PREFIX
+                    if os.path.exists('/usr/share/pdk/' + pdkname + '/' + pdkitems[1]):
+                        break
+                else:
+                    pdkpair = pdkdir.split('.')
+                    if pdkpair[0] == pdkitems[0]:
+                        pdkname = pdkdir
+                        #TODO: PREFIX
+                        if os.path.exists('/usr/share/pdk/' + pdkname + '/' + pdkitems[1]):
+                            break
+            if pdkname == '':
+                print('No pdkname found; layout editing disabled')
+                self.toppane.appbar.layout_button.config(state='disabled')
+            else:
+                try:
+                    subf = os.listdir('/ef/tech/' + pdkname + '/' + pdkitems[1] + '/libs.tech/magic/current')
+                except:
+                    print('PDK ' + pdkname + ' has no layout setup; layout editing disabled')
+                    self.toppane.appbar.layout_button.config(state='disabled')
+                else:
+                    self.toppane.appbar.layout_button.config(state='enabled')
+        else:
+            print('No PDK returned in project selection data;  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 "ip-name" in the datasheet.
+        # "<project_folder_name>.json" is the legacy name for the datasheet, deprecated.
+
+        found = False
+        ppath = selection['values'][0]
+        jsonname = ppath + '/project.json'
+        legacyname = ppath + '/' + pname + '.json'
+        if not os.path.isfile(jsonname):
+            if os.path.isfile(legacyname):
+                jsonname = legacyname
+
+        if os.path.isfile(jsonname):
+            # Pull the ipname into local store (may want to do this with the
+            # datasheet as well)
+            with open(jsonname, 'r') as f:
+                datatop = json.load(f)
+                dsheet = datatop['data-sheet']
+                ipname = dsheet['ip-name']
+                self.project_name = ipname
+                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)
+            print('Setting project ip-name from the project folder name.')
+            self.project_name = pname
+
+        # 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__':
+    OpenGalaxyManager(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()
