| 
					
				 | 
			
			
				@@ -1,4 +1,9 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #!/usr/bin/python3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# TODO: get rid of sqlite cursors; execute on connection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# TODO: add index to table creation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# TODO: why are there TWO sqlite.connect()?? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#   try auto-commit (isolation_level = "IMMEDIATE") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#   try dict-parameters in sql statements 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # TODO: pick up comment for cwd and display at the top somewhere, or maybe status line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 """ a simple gui or command line app 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 to view and create/edit file comments 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -18,7 +23,7 @@ nav tools are enabled, so you can double-click to go into a dir 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-VERSION = "0.4" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+VERSION = "0.5" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 helpMsg = f"""<table width=100%><tr><td><h1>Dirnotes</h1><td> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <td align=right>Version: {VERSION}</td></tr></table> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -52,8 +57,7 @@ media (as long as the disk format allows it). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 the comment box gets a light yellow background. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import sys,os,argparse,stat,getpass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#~ from dirWidget import DirWidget 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import sys,os,argparse,stat,getpass,shutil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from PyQt5.QtGui import * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from PyQt5.QtWidgets import * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from PyQt5.QtCore import Qt, pyqtSignal 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -108,30 +112,16 @@ class dnDataBase: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     except sqlite3.OperationalError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       print(f"Database {dbFile} not found") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       raise 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.db_cursor = self.db.cursor() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      self.db_cursor.execute("select * from dirnotes") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self.db.execute("select * from dirnotes") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     except sqlite3.OperationalError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       print_v("Table %s created" % ("dirnotes")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      self.db_cursor.execute("create table dirnotes (name TEXT, date DATETIME, size INTEGER, comment TEXT, comment_date DATETIME, author TEXT)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self.db.execute("create table dirnotes (name TEXT, date DATETIME, size INTEGER, comment TEXT, comment_date DATETIME, author TEXT)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self.db_cursor.execute("create index dirnotes_i on dirnotes(name)")  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  # getData is only used by the restore-from-database.......consider deleting it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def getData(self, fileName): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.db_cursor.execute("select * from dirnotes where name=? and comment<>'' order by comment_date desc",(os.path.abspath(fileName),)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return self.db_cursor.fetchone() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def setData(self, fileName, comment): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    s = os.lstat(fileName) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    print_v ("params: %s %s %d %s %s" % ((os.path.abspath(fileName),  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dnDataBase.epochToDb(s.st_mtime), s.st_size, comment,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dnDataBase.epochToDb(time.time())))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      self.db_cursor.execute("insert into dirnotes values (?,datetime(?,'unixepoch','localtime'),?,?,datetime(?,'unixepoch','localtime'),?)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (os.path.abspath(fileName), s.st_mtime, s.st_size, str(comment), time.time(), getpass.getuser())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      self.db.commit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    except sqlite3.OperationalError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      print("database is locked or unwriteable") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      errorBox("database is locked or unwriteable") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      #TODO: put up a message box for locked database 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c = self.db.execute("select * from dirnotes where name=? and comment<>'' order by comment_date desc",(os.path.abspath(fileName),)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return c.fetchone() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   @staticmethod 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def epochToDb(epoch): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -157,13 +147,14 @@ class FileObj(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   FILE_IS_LINK   = -2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   FILE_IS_SOCKET = -3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def __init__(self, fileName): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.fileName = os.path.abspath(fileName) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.displayName = os.path.split(fileName)[1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    self.fileName = os.path.abspath(fileName) # full path; dirs end WITHOUT a terminal / 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    self.displayName = os.path.split(fileName)[1]   # base name; dirs end with a / 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     s = os.lstat(self.fileName) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     self.date = s.st_mtime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if stat.S_ISDIR(s.st_mode): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       self.size = FileObj.FILE_IS_DIR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      self.displayName += '/' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if not self.displayName.endswith('/'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.displayName += '/' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     elif stat.S_ISLNK(s.st_mode): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       self.size = FileObj.FILE_IS_LINK 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     elif stat.S_ISSOCK(s.st_mode): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -187,13 +178,13 @@ class FileObj(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def getName(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return self.fileName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def getFileName(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def getDisplayName(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return self.displayName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   # with an already open database cursor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def loadDbComment(self,cursor): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    cursor.execute("select comment,author,comment_date from dirnotes where name=? and comment<>'' order by comment_date desc",(self.fileName,)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    a = cursor.fetchone() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def loadDbComment(self,db): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c = db.execute("select comment,author,comment_date from dirnotes where name=? and comment<>'' order by comment_date desc",(self.fileName,)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    a = c.fetchone() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if a: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       self.dbComment, self.dbAuthor, self.dbDate = a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       self.commentsDiffer = True if self.xattrComment == self.dbComment else False 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -204,19 +195,19 @@ class FileObj(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return self.dbAuthor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def getDbDate(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return self.dbDate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def setDbComment(self,newComment): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      self.db = sqlite3.connect(dbName) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    except sqlite3.OperationalError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      print_v(f"database {dbName} not found") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      raise 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c = self.db.cursor() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def setDbComment(self,db,newComment): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     s = os.lstat(self.fileName) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      c.execute("insert into dirnotes (name,date,size,comment,comment_date,author) values (?,datetime(?,'unixepoch','localtime'),?,?,datetime(?,'unixepoch','localtime'),?)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          (os.path.abspath(self.fileName), s.st_mtime, s.st_size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      # TODO: copy from /g/test_file to /home/patb/project/dirnotes/r    fails on database.commit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      print_v(f"setDbComment db {db}, file: {self.fileName}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      print_v("insert into dirnotes (name,date,size,comment,comment_date,author) values (?,datetime(?,'unixepoch','localtime'),?,?,datetime(?,'unixepoch','localtime'),?)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (self.fileName, s.st_mtime, s.st_size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           str(newComment), time.time(), getpass.getuser())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      self.db.commit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      db.execute("insert into dirnotes (name,date,size,comment,comment_date,author) values (?,datetime(?,'unixepoch','localtime'),?,?,datetime(?,'unixepoch','localtime'),?)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (self.fileName, s.st_mtime, s.st_size, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          str(newComment), time.time(), getpass.getuser())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      print_v(f"setDbComment, execute done, about to commit()") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      db.commit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       print_v(f"database write for {self.fileName}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       self.dbComment = newComment 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     except sqlite3.OperationalError: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -341,47 +332,6 @@ icon = ["32 32 6 1",  # the QPixmap constructor allows for str[] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 "  ...........................   ", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 "                                "] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-''' a widget that shows only a dir listing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-class DirWidget(QListWidget): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ''' a simple widget that shows a list of directories, staring 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  at the directory passed into the constructor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  a mouse click or 'enter' key will send a 'selected' signal to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  anyone who connects to this. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  the .. parent directory is shown for all dirs except / 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  the most interesting parts of the interface are: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  constructor - send in the directory to view 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  method - currentPath() returns text of current path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  signal - selected calls a slot with a single arg: new path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ''' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  selected = pyqtSignal(str) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def __init__(self, directory='.', parent=None): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    super(DirWidget,self).__init__(parent) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.directory = directory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.refill() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.itemActivated.connect(self.selectionByLWI) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # it would be nice to pick up single-mouse-click for selection as well 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # but that seems to be a system-preferences global 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def selectionByLWI(self, li): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.directory = os.path.abspath(self.directory + '/' + str(li.text())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.refill() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.selected.emit(self.directory) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def refill(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    current,dirs,files = next(os.walk(self.directory,followlinks=True)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dirs.sort() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if '/' not in dirs: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      dirs = ['..'] + dirs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    self.clear() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for d in dirs: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      li = QListWidgetItem(d,self) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  def currentPath(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return self.directory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # sortable TableWidgetItem, based on idea by Aledsandar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # http://stackoverflow.com/questions/12673598/python-numerical-sorting-in-qtablewidget 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -457,7 +407,7 @@ class DirNotes(QMainWindow): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if len(filename)>0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       for i in range(lb.rowCount()): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if filename == lb.item(i,0).data(32).getFileName(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if filename == lb.item(i,0).data(32).getDisplayName(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           lb.setCurrentCell(i,3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -509,19 +459,16 @@ class DirNotes(QMainWindow): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if not fo.isDir() and not fo.isLink():  # TODO: add check for socket  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       print_v(f"copy file {fo.getName()}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       # open the dir.picker 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      # TODO: move all this out to a function 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      qd = QDialog(self.parent) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      qd.setWindowTitle("Select destination for FileCopy") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      qd.setWindowModality(Qt.ApplicationModal) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      dw = DirWidget('.',qd) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      d_ok = QPushButton('select') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      d_ok.setDefault(True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      d_ok.clicked.connect(QDialog.accept) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      d_nope = QPushButton('cancel') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      d_nope.clicked.connect(QDialog.reject) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      # if returns from <enter>, copy the file and comments 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      r = qd.exec()  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      r = QFileDialog.getExistingDirectory(self.parent, "Select destination for FileCopy") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       print_v(f"copy to {r}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if r: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dest = os.path.join(r,fo.getDisplayName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          shutil.copy2(fo.getName(), dest) # copy2 preserves the xattr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          f = FileObj(dest)       # can't make the FileObj until it exists 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          f.setDbComment(self.db,fo.getDbComment()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        except: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          errorBox(f"file copy to <{dest}> failed; check permissions") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def refill(self): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -550,13 +497,13 @@ class DirNotes(QMainWindow): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     # this is a list of all the file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #~ print("insert {} items into cleared table {}".format(len(d),current)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for i,name in enumerate(d): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this_file = FileObj(current+'/'+name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this_file.loadDbComment(self.db.db_cursor) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this_file = FileObj(os.path.join(current,name)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this_file.loadDbComment(self.db) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       print_v("FileObj created as {} and the db-comment is <{}>".format(this_file.displayName, this_file.dbComment)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       #~ print("insert order check: {} {} {} {}".format(d[i],i,this_file.getName(),this_file.getDate())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       #~ self.files.update({this_file.getName(),this_file}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       self.files = self.files + [this_file] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      display_name = this_file.getFileName() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      display_name = this_file.getDisplayName() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if this_file.getSize() == FileObj.FILE_IS_DIR: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         item = SortableTableWidgetItem(display_name,' '+display_name, this_file)  # directories sort first 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       else: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -569,7 +516,7 @@ class DirNotes(QMainWindow): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       # get the comment from database & xattrs, either can fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       comment = this_file.getComment() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       other_comment = this_file.getOtherComment() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ci = QTableWidgetItem(comment) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ci = SortableTableWidgetItem(comment,'',this_file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       ci.setToolTip(f"comment: {comment}\ncomment date: {this_file.getDbDate()}\nauthor: {this_file.getDbAuthor()}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if other_comment != comment: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ci.setBackground(QBrush(QColor(255,255,160))) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -607,11 +554,10 @@ class DirNotes(QMainWindow): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print_v("      selected file: "+self.lb.item(x.row(),0).file_object.getName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     the_file = self.lb.item(x.row(),0).file_object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     print_v("      and the row file is "+the_file.getName()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    the_file.setDbComment(str(x.text())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    the_file.setDbComment(self.db,str(x.text())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     r = the_file.setXattrComment(str(x.text()))  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # TODO: change this to FileObj.setDbComment() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if r: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      self.db.setData(the_file.getName(),x.text()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      the_file.setDbComment(self.db,x.text()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   def switchMode(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     global mode 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -686,7 +632,7 @@ if __name__=="__main__": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   print_v(f"here is the .json {repr(config)}") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   dbName = os.path.expanduser(config["database"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  db = dnDataBase(dbName) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  db = dnDataBase(dbName).db 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   xattr_comment = config["xattr_tag"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   xattr_author  = xattr_comment + ".author" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   xattr_date    = xattr_comment + ".date" 
			 |