Project manager displays subprojects (projects located under the 'subcells' folder) in the project treeview. Changed some of the buttons on the project manager home screen.
diff --git a/common/project_manager.py b/common/project_manager.py index 441f852..0af75f4 100755 --- a/common/project_manager.py +++ b/common/project_manager.py
@@ -742,22 +742,21 @@ 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], + [["New", True, self.createproject], + ["Flow", False, self.synthesize], ["Copy", False, self.copyproject], - ["Rename IP", False, self.renameproject], - ["<CloudV", True, self.cloudvimport], - ["Clean", False, self.cleanproject], + ["Rename", False, self.renameproject], ["Delete", False, self.deleteproject]], height=height, columns=[0, 1]) self.projectselect.grid(row = 3, sticky = 'news') self.projectselect.bindselect(self.setcurrent) - tooltip.ToolTip(self.projectselect.get_button(0), text="Create a new project") - 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") + tooltip.ToolTip(self.projectselect.get_button(0), text="Create a new project/subproject") + #TODO: Try to have tooltip display what type of flow if possible + tooltip.ToolTip(self.projectselect.get_button(1), text="Start design flow") + tooltip.ToolTip(self.projectselect.get_button(2), text="Make a copy of an entire project") + tooltip.ToolTip(self.projectselect.get_button(3), text="Rename a project folder") + tooltip.ToolTip(self.projectselect.get_button(4), text="Delete an entire project") pdklist = self.get_pdk_list(projectlist) self.projectselect.populate2("PDK", projectlist, pdklist) @@ -1028,7 +1027,7 @@ 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 + #returns the config directory that 'path' contains between .config and .ef-config if (os.path.exists(path + '/.config')): return '/.config' elif (os.path.exists(path + '/.ef-config')): @@ -1041,7 +1040,7 @@ def blacklisted(self, dirname): # Blacklist: Do not show files of these names: - blacklist = [importdir, 'ip', 'upload', 'export', 'lost+found'] + blacklist = [importdir, 'ip', 'upload', 'export', 'lost+found', 'subcells'] if dirname in blacklist: return True else: @@ -1141,22 +1140,33 @@ 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)) - + + projectlist = [] + + for item in os.listdir(self.projectdir): + if os.path.isdir(self.projectdir + '/' + item): + projectpath = self.projectdir + '/' + item + projectlist.append(projectpath) + + #check for subprojects and add them + if os.path.isdir(projectpath + '/subcells'): + for subproj in os.listdir(projectpath + '/subcells'): + if os.path.isdir(projectpath + '/subcells/' + subproj): + projectlist.append(projectpath + '/subcells/' + subproj) + + + # '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): + name = os.path.split(item)[1] + if self.blacklisted(name): projectlist.remove(item) - elif badrex1.match(item): + elif badrex1.match(name): projectlist.remove(item) - elif badrex2.match(item): + elif badrex2.match(name): projectlist.remove(item) - - # Add pathname to all items in projectlist - projectlist = [self.projectdir + '/' + item for item in projectlist] return projectlist #------------------------------------------------------------------------ @@ -1423,7 +1433,7 @@ for project in projectlist: pdkdir = self.get_pdk_dir(project) pdklist.append(pdkdir) - + return pdklist #------------------------------------------------------------------------ @@ -4003,16 +4013,17 @@ # print("Make a Challenge from import " + importp + "!") # # subprocess.run([config.apps_path + '/cace_import_upload.py', importp, '-test']) + # Runs whenever a user selects a project def setcurrent(self, value): global currdesign treeview = value.widget selection = treeview.item(treeview.selection()) 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: + metapath = os.path.expanduser(currdesign) + if not os.path.exists(metapath): + os.makedirs(os.path.split(metapath)[0], exist_ok=True) + with open(metapath, 'w') as f: f.write(pname + '\n') # Pick up the PDK from "values", use it to find the PDK folder, determine @@ -4020,6 +4031,7 @@ # button accordingly svalues = selection['values'] + #print("svalues :"+str(svalues)) pdkitems = svalues[1].split() pdkdir = '' @@ -4043,47 +4055,7 @@ 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.
diff --git a/common/treeviewchoice.py b/common/treeviewchoice.py index 7db3620..ebfd3ce 100755 --- a/common/treeviewchoice.py +++ b/common/treeviewchoice.py
@@ -98,6 +98,8 @@ self.lastselected = selection self.lasttag = oldtag + + #Populate the project view def repopulate(self, itemlist=[], versioning=False): # Remove all children of treeview @@ -113,6 +115,9 @@ self.itemlist.sort() mode = 'even' + + m=0 + for item in self.itemlist: # Special handling of JSON files. The following reads a JSON file and # finds key 'ip-name' in dictionary 'data-sheet', if such exists. If @@ -142,14 +147,16 @@ # If versioning is true, then the last path component is the # version number, and the penultimate path component is the # name. - version = os.path.split(item)[1] + version = os.path.split(item)[1] name = os.path.split(os.path.split(item)[0])[1] + ' (v' + version + ')' else: name = os.path.split(item)[1] # Watch for duplicate items! + n = 0 origname = name + while self.treeView.exists(name): n += 1 name = origname + '(' + str(n) + ')' @@ -157,12 +164,28 @@ # Note: iid value with spaces in it is a bad idea. if ' ' in name: name = name.replace(' ', '_') - + # optionally: Mark directories with trailing slash if self.markDir and os.path.isdir(item): origname += "/" self.treeView.insert('', 'end', text=origname, iid=name, value=item, tag=mode) + + + if 'subcells' in os.path.split(item)[0]: + # If a project is a subproject, move it under its parent + parent_path = os.path.split(os.path.split(item)[0])[0] + parent_name = os.path.split(parent_path)[1] + self.treeView.move(name,parent_name,m) + m+=1 + else: + # If its not a subproject, create a "subproject" of itself + # iid shouldn't be repeated since it starts with '.' + self.treeView.insert('', 'end', text=origname, iid='.'+name, value=item, tag=mode) + self.treeView.move('.'+name,name,0) + m=1 + + if self.initSelected and self.treeView.exists(self.initSelected): self.setselect(self.initSelected) self.initSelected = None @@ -189,7 +212,7 @@ valuelist.append(value) return valuelist - # Return items from the treeview + # Return items (id's) from the treeview def getlist(self): return self.treeView.get_children() @@ -201,15 +224,30 @@ # Populate another column self.treeView.heading(1, text = title) self.treeView.column(1, anchor='center') + children=list(self.getlist()) + + # Add id's of subprojects + i=1 + for c in list(self.getlist()): + grandchildren=self.treeView.get_children(item=c) + for g in grandchildren: + children.insert(i,g) + i+=1 + i+=1 + n = 0 for item in valuelist: - child = os.path.split(itemlist[n])[1] - # Get the item at this index + child = children[n] + # Get the value at this index oldvalue = self.treeView.item(child, 'values') newvalue = (oldvalue, item) self.treeView.item(child, values = newvalue) + # Add pdk for the "copy" of the project that is made in the treeview + if (n+1<len(children) and children[n+1]=='.'+child): + valuelist.insert(n,item) n += 1 - + + def func_callback(self, callback, event=None): callback(self.treeView.item(self.treeView.selection()))