diff --git a/common/og_gui_manager.py b/common/og_gui_manager.py
new file mode 100755
index 0000000..921b3f1
--- /dev/null
+++ b/common/og_gui_manager.py
@@ -0,0 +1,4138 @@
+#!/ef/efabless/opengalaxy/venv/bin/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 og_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(og_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([og_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([og_config.apps_path + '/lvs_manager.py', 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([og_config.apps_path + '/og_gui_characterize.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([og_config.apps_path + '/qflow_manager.py',
+				design, '-development', '-subproject=' + pname])
+                else:
+                    subprocess.Popen([og_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([og_config.apps_path + '/qflow_manager.py',
+				design, designname, '-development'])
+                else:
+                    subprocess.Popen([og_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()
