|  | @@ -1,4 +1,4 @@
 | 
	
		
			
				|  |  | -#!/usr/bin/python
 | 
	
		
			
				|  |  | +#!/usr/bin/python3
 | 
	
		
			
				|  |  |  """ a simple gui or command line app
 | 
	
		
			
				|  |  |  to view and create/edit file comments
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -14,6 +14,9 @@ where possible, comments are duplicated in
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	these comments stick to the symlink, not the deref
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +nav tools are enabled, so you can double-click to go into a dir, and 
 | 
	
		
			
				|  |  | +	there's an UP arrow to navigate back
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  """
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -42,8 +45,9 @@ comment box gets a light yellow background.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import sys,os,argparse,stat
 | 
	
		
			
				|  |  |  #~ from dirWidget import DirWidget
 | 
	
		
			
				|  |  | -from PyQt4.QtGui import *
 | 
	
		
			
				|  |  | -from PyQt4 import QtGui, QtCore
 | 
	
		
			
				|  |  | +from PyQt5.QtGui import *
 | 
	
		
			
				|  |  | +from PyQt5.QtWidgets import *
 | 
	
		
			
				|  |  | +from PyQt5.QtCore import Qt
 | 
	
		
			
				|  |  |  import xattr, sqlite3, time
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  VERSION = "0.2"
 | 
	
	
		
			
				|  | @@ -52,7 +56,7 @@ DATABASE_NAME = "~/.dirnotes.db"
 | 
	
		
			
				|  |  |  # convert the ~/ form to a fully qualified path
 | 
	
		
			
				|  |  |  DATABASE_NAME = os.path.expanduser(DATABASE_NAME)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -class DataBase:
 | 
	
		
			
				|  |  | +class dnDataBase:
 | 
	
		
			
				|  |  |  	''' the database is flat
 | 
	
		
			
				|  |  |  		fileName: fully qualified name
 | 
	
		
			
				|  |  |  		st_mtime: a float
 | 
	
	
		
			
				|  | @@ -81,22 +85,22 @@ class DataBase:
 | 
	
		
			
				|  |  |  		c = self.db.cursor()
 | 
	
		
			
				|  |  |  		c.execute("select * from dirnotes where name=? and comment<>'' order by comment_date desc",(os.path.abspath(fileName),))
 | 
	
		
			
				|  |  |  		return c.fetchone()
 | 
	
		
			
				|  |  | -	def setData(self, fileName, _date, _size, comment):
 | 
	
		
			
				|  |  | -		c = self.db.cursor()
 | 
	
		
			
				|  |  | -		c.execute("insert into dirnotes values (?,?,?,?,?)",
 | 
	
		
			
				|  |  | -			(fileName, _date, _size, comment, time.time()))
 | 
	
		
			
				|  |  | -		self.db.commit()
 | 
	
		
			
				|  |  | -		return True
 | 
	
		
			
				|  |  | -	def log(self, fileName, comment):
 | 
	
		
			
				|  |  | +	def setData(self, fileName, comment):
 | 
	
		
			
				|  |  |  		''' TODO: convert filename to canonical '''
 | 
	
		
			
				|  |  |  		c = self.db.cursor()
 | 
	
		
			
				|  |  |  		s = os.lstat(fileName)
 | 
	
		
			
				|  |  | -		print "params: %s %s %d %s %s" % ((os.path.abspath(fileName), 
 | 
	
		
			
				|  |  | -				DataBase.epochToDb(s.st_mtime), s.st_size, comment, 
 | 
	
		
			
				|  |  | -				DataBase.epochToDb(time.time())))
 | 
	
		
			
				|  |  | -		c.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()))
 | 
	
		
			
				|  |  | -		self.db.commit()
 | 
	
		
			
				|  |  | +		print ("params: %s %s %d %s %s" % ((os.path.abspath(fileName), 
 | 
	
		
			
				|  |  | +				dnDataBase.epochToDb(s.st_mtime), s.st_size, comment, 
 | 
	
		
			
				|  |  | +				dnDataBase.epochToDb(time.time()))))
 | 
	
		
			
				|  |  | +		try:
 | 
	
		
			
				|  |  | +			c.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()))
 | 
	
		
			
				|  |  | +			self.db.commit()
 | 
	
		
			
				|  |  | +		except sqlite3.OperationalError:
 | 
	
		
			
				|  |  | +			print("database is locked or unwriteable")
 | 
	
		
			
				|  |  | +			#TODO: put up a message box for locked database
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	@staticmethod
 | 
	
		
			
				|  |  |  	def epochToDb(epoch):
 | 
	
		
			
				|  |  |  		return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(epoch))
 | 
	
	
		
			
				|  | @@ -105,7 +109,7 @@ class DataBase:
 | 
	
		
			
				|  |  |  		return time.mktime(time.strptime(dbTime,"%Y-%m-%d %H:%M:%S"))
 | 
	
		
			
				|  |  |  	@staticmethod
 | 
	
		
			
				|  |  |  	def getShortDate(longDate):
 | 
	
		
			
				|  |  | -		e = DataBase.DbToEpoch(longDate)
 | 
	
		
			
				|  |  | +		e = dnDataBase.DbToEpoch(longDate)
 | 
	
		
			
				|  |  |  		sd = time.strptime(longDate,"%Y-%m-%d %H:%M:%S")
 | 
	
		
			
				|  |  |  		# check for this year, or today
 | 
	
		
			
				|  |  |  		ty = time.mktime((time.localtime()[0],1,1,0,0,0,0,1,-1))
 | 
	
	
		
			
				|  | @@ -118,10 +122,10 @@ class DataBase:
 | 
	
		
			
				|  |  |  			return time.strftime("%X",sd)
 | 
	
		
			
				|  |  |  	#~ test code for this routine
 | 
	
		
			
				|  |  |  	#~ for i in range(int(time.time() - 370*24*3600),
 | 
	
		
			
				|  |  | -			#~ int(time.time() + 48*3600),
 | 
	
		
			
				|  |  | -			#~ 3599):
 | 
	
		
			
				|  |  | -		#~ ds = DataBase.epochToDb(i)
 | 
	
		
			
				|  |  | -		#~ print("%d\t%s\t%s" % (i,ds,DataBase.getShortDate(ds)))
 | 
	
		
			
				|  |  | +		#~ int(time.time() + 48*3600),
 | 
	
		
			
				|  |  | +		#~ 3599):
 | 
	
		
			
				|  |  | +		#~ ds = dnDataBase.epochToDb(i)
 | 
	
		
			
				|  |  | +		#~ print("%d\t%s\t%s" % (i,ds,dnDataBase.getShortDate(ds)))
 | 
	
		
			
				|  |  |  				
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		
 | 
	
	
		
			
				|  | @@ -146,29 +150,31 @@ class FileObj():
 | 
	
		
			
				|  |  |  	def __init__(self, fileName):
 | 
	
		
			
				|  |  |  		self.fileName = fileName
 | 
	
		
			
				|  |  |  		s = os.lstat(fileName)
 | 
	
		
			
				|  |  | -		self.date = DataBase.epochToDb(s.st_mtime)
 | 
	
		
			
				|  |  | +		self.date = dnDataBase.epochToDb(s.st_mtime)
 | 
	
		
			
				|  |  |  		if stat.S_ISDIR(s.st_mode):
 | 
	
		
			
				|  |  |  			self.size = FileObj.FILE_IS_DIR
 | 
	
		
			
				|  |  |  		elif stat.S_ISLNK(s.st_mode):
 | 
	
		
			
				|  |  |  			self.size = FileObj.FILE_IS_LINK
 | 
	
		
			
				|  |  |  		else:
 | 
	
		
			
				|  |  |  			self.size = s.st_size
 | 
	
		
			
				|  |  | -		self.comment = ''
 | 
	
		
			
				|  |  | +		self.xattrComment = ''
 | 
	
		
			
				|  |  |  		try:
 | 
	
		
			
				|  |  | -			self.comment = xattr.get(fileName,COMMENT_KEY,nofollow=True)
 | 
	
		
			
				|  |  | +			self.xattrComment = xattr.get(fileName,COMMENT_KEY,nofollow=True).decode()
 | 
	
		
			
				|  |  |  		except Exception as e:
 | 
	
		
			
				|  |  | -			print("comment read on %s failed, execption %s" % (self.fileName,e)) 
 | 
	
		
			
				|  |  | +			#print("comment read on %s failed, execption %s" % (self.fileName,e)) 
 | 
	
		
			
				|  |  |  			pass
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	def getName(self):
 | 
	
		
			
				|  |  |  		return self.fileName
 | 
	
		
			
				|  |  |  	def getFileName(self):
 | 
	
		
			
				|  |  |  		return os.path.split(self.fileName)[1]
 | 
	
		
			
				|  |  | -	def getComment(self):
 | 
	
		
			
				|  |  | -		return self.comment
 | 
	
		
			
				|  |  | -	def setComment(self,newComment):
 | 
	
		
			
				|  |  | -		self.comment = newComment
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	def getXattrComment(self):
 | 
	
		
			
				|  |  | +		return self.xattrComment
 | 
	
		
			
				|  |  | +	def setXattrComment(self,newComment):
 | 
	
		
			
				|  |  | +		self.xattrComment = newComment
 | 
	
		
			
				|  |  |  		try:
 | 
	
		
			
				|  |  | -			xattr.set(self.fileName,COMMENT_KEY,self.comment,nofollow=True)
 | 
	
		
			
				|  |  | +			xattr.set(self.fileName,COMMENT_KEY,self.xattrComment,nofollow=True)
 | 
	
		
			
				|  |  |  			return True
 | 
	
		
			
				|  |  |  		# we need to move these cases out to a handler 
 | 
	
		
			
				|  |  |  		except Exception as e:
 | 
	
	
		
			
				|  | @@ -184,6 +190,15 @@ class FileObj():
 | 
	
		
			
				|  |  |  			elif "Errno 95" in str(e):
 | 
	
		
			
				|  |  |  				print("is this a VFAT or EXFAT volume? these don't allow comments")
 | 
	
		
			
				|  |  |  			return False
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	def getDbComment(self,db):
 | 
	
		
			
				|  |  | +		self.dbComment = ""
 | 
	
		
			
				|  |  | +		row = db.getData(self.fileName)
 | 
	
		
			
				|  |  | +		if row and len(row)>1:
 | 
	
		
			
				|  |  | +			self.dbComment = row[3]
 | 
	
		
			
				|  |  | +	def setDbComment(self,db,comment):
 | 
	
		
			
				|  |  | +		db.setData(self.fileName,comment)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	def getDate(self):
 | 
	
		
			
				|  |  |  		return self.date
 | 
	
		
			
				|  |  |  	def getSize(self):
 | 
	
	
		
			
				|  | @@ -207,10 +222,12 @@ class HelpWidget(QDialog):
 | 
	
		
			
				|  |  |  # sortable TableWidgetItem, based on idea by Aledsandar
 | 
	
		
			
				|  |  |  # http://stackoverflow.com/questions/12673598/python-numerical-sorting-in-qtablewidget
 | 
	
		
			
				|  |  |  # NOTE: the QTableWidgetItem has setData() and data() which may allow data bonding
 | 
	
		
			
				|  |  | +# in Qt5, data() binding is more awkward, so do it here
 | 
	
		
			
				|  |  |  class SortableTableWidgetItem(QTableWidgetItem):
 | 
	
		
			
				|  |  | -	def __init__(self, text, sortValue):
 | 
	
		
			
				|  |  | +	def __init__(self, text, sortValue, file_object):
 | 
	
		
			
				|  |  |  		QTableWidgetItem.__init__(self, text, QTableWidgetItem.UserType)
 | 
	
		
			
				|  |  |  		self.sortValue = sortValue
 | 
	
		
			
				|  |  | +		self.file_object = file_object
 | 
	
		
			
				|  |  |  	def __lt__(self, other):
 | 
	
		
			
				|  |  |  		return self.sortValue < other.sortValue
 | 
	
		
			
				|  |  |  		
 | 
	
	
		
			
				|  | @@ -231,7 +248,7 @@ class DirNotes(QMainWindow):
 | 
	
		
			
				|  |  |  		lb = QTableWidget()
 | 
	
		
			
				|  |  |  		self.lb = lb
 | 
	
		
			
				|  |  |  		lb.setColumnCount(4)
 | 
	
		
			
				|  |  | -		lb.horizontalHeader().setResizeMode( 3, QHeaderView.Stretch );
 | 
	
		
			
				|  |  | +		lb.horizontalHeader().setSectionResizeMode( 3, QHeaderView.Stretch );
 | 
	
		
			
				|  |  |  		lb.verticalHeader().setDefaultSectionSize(20);	# thinner rows
 | 
	
		
			
				|  |  |  		lb.verticalHeader().setVisible(False)
 | 
	
		
			
				|  |  |  		
 | 
	
	
		
			
				|  | @@ -306,7 +323,7 @@ class DirNotes(QMainWindow):
 | 
	
		
			
				|  |  |  		print("closing")
 | 
	
		
			
				|  |  |  	def sbd(self):
 | 
	
		
			
				|  |  |  		print("sort by date")
 | 
	
		
			
				|  |  | -		self.lb.sortItems(1,QtCore.Qt.DescendingOrder)
 | 
	
		
			
				|  |  | +		self.lb.sortItems(1,Qt.DescendingOrder)
 | 
	
		
			
				|  |  |  	def sbs(self):
 | 
	
		
			
				|  |  |  		print("sort by size")
 | 
	
		
			
				|  |  |  		self.lb.sortItems(2)
 | 
	
	
		
			
				|  | @@ -317,12 +334,12 @@ class DirNotes(QMainWindow):
 | 
	
		
			
				|  |  |  		HelpWidget(self)
 | 
	
		
			
				|  |  |  	def sbc(self):
 | 
	
		
			
				|  |  |  		print("sort by comment")
 | 
	
		
			
				|  |  | -		self.lb.sortItems(3,QtCore.Qt.DescendingOrder)
 | 
	
		
			
				|  |  | +		self.lb.sortItems(3,Qt.DescendingOrder)
 | 
	
		
			
				|  |  |  	def newDir(self):
 | 
	
		
			
				|  |  |  		print("change dir to "+self.dirLeft.currentPath())
 | 
	
		
			
				|  |  |  	def double(self,row,col):
 | 
	
		
			
				|  |  |  		print("double click {} {}".format(row, col))
 | 
	
		
			
				|  |  | -		fo = self.lb.item(row,0).data(32).toPyObject()
 | 
	
		
			
				|  |  | +		fo = self.lb.item(row,0).file_object
 | 
	
		
			
				|  |  |  		if col==0 and fo.getSize() == FileObj.FILE_IS_DIR:
 | 
	
		
			
				|  |  |  			print("double click on {}".format(fo.getName()))
 | 
	
		
			
				|  |  |  			self.curPath = fo.getName()
 | 
	
	
		
			
				|  | @@ -339,8 +356,8 @@ class DirNotes(QMainWindow):
 | 
	
		
			
				|  |  |  		dirIcon = QIcon.fromTheme('folder')
 | 
	
		
			
				|  |  |  		fileIcon = QIcon.fromTheme('text-x-generic')
 | 
	
		
			
				|  |  |  		linkIcon = QIcon.fromTheme('emblem-symbolic-link')
 | 
	
		
			
				|  |  | -		current, dirs, files = os.walk(self.curPath,followlinks=True).next()
 | 
	
		
			
				|  |  | -		dirs = map(lambda x:x+'/', dirs)
 | 
	
		
			
				|  |  | +		current, dirs, files = next(os.walk(self.curPath,followlinks=True))
 | 
	
		
			
				|  |  | +		dirs = list(map(lambda x:x+'/', dirs))
 | 
	
		
			
				|  |  |  		dirs.sort()
 | 
	
		
			
				|  |  |  		files.sort()
 | 
	
		
			
				|  |  |  		
 | 
	
	
		
			
				|  | @@ -353,40 +370,52 @@ class DirNotes(QMainWindow):
 | 
	
		
			
				|  |  |  		#~ print("insert {} items into cleared table {}".format(len(d),current))
 | 
	
		
			
				|  |  |  		for i in range(len(d)):
 | 
	
		
			
				|  |  |  			this_file = FileObj(current+'/'+d[i])
 | 
	
		
			
				|  |  | +			this_file.getDbComment(self.db)
 | 
	
		
			
				|  |  | +			print("FileObj created as {} and the db-comment is <{}>".format(this_file.fileName, 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]
 | 
	
		
			
				|  |  |  			if this_file.getSize() == FileObj.FILE_IS_DIR:
 | 
	
		
			
				|  |  | -				item = SortableTableWidgetItem(d[i],' '+d[i])	# directories sort first
 | 
	
		
			
				|  |  | +				item = SortableTableWidgetItem(d[i],' '+d[i], this_file)	# directories sort first
 | 
	
		
			
				|  |  |  			else:
 | 
	
		
			
				|  |  | -				item = SortableTableWidgetItem(d[i],d[i])
 | 
	
		
			
				|  |  | -			item.setFlags(QtCore.Qt.ItemIsEnabled)
 | 
	
		
			
				|  |  | -			item.setData(32,this_file)	# keep a hidden copy of the file object
 | 
	
		
			
				|  |  | +				item = SortableTableWidgetItem(d[i],d[i], this_file)
 | 
	
		
			
				|  |  | +			item.setFlags(Qt.ItemIsEnabled)
 | 
	
		
			
				|  |  | +			#item.setData(32,this_file)	# keep a hidden copy of the file object
 | 
	
		
			
				|  |  |  			item.setToolTip(this_file.getName())
 | 
	
		
			
				|  |  |  			self.lb.setItem(i,0,item)
 | 
	
		
			
				|  |  |  			#lb.itemAt(i,0).setFlags(Qt.ItemIsEnabled) #NoItemFlags) 
 | 
	
		
			
				|  |  | -			comment = this_file.getComment()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			# get the comment from database & xattrs, either can fail
 | 
	
		
			
				|  |  | +			comment = "" 
 | 
	
		
			
				|  |  | +			row = self.db.getData(this_file.getName())
 | 
	
		
			
				|  |  | +			if row and len(row)>0:
 | 
	
		
			
				|  |  | +				comment = row[3]
 | 
	
		
			
				|  |  | +			xattrComment = this_file.getXattrComment()
 | 
	
		
			
				|  |  |  			self.lb.setItem(i,3,QTableWidgetItem(comment))
 | 
	
		
			
				|  |  | +			if xattrComment != comment:
 | 
	
		
			
				|  |  | +				self.lb.item(i,3).setBackground(QBrush(Qt.yellow))
 | 
	
		
			
				|  |  | +				print("got two comments <{}> and <{}>".format(comment, xattrComment))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  			dt = this_file.getDate()
 | 
	
		
			
				|  |  | -			da = SortableTableWidgetItem(DataBase.getShortDate(dt),dt)
 | 
	
		
			
				|  |  | +			da = SortableTableWidgetItem(dnDataBase.getShortDate(dt),dt,this_file)
 | 
	
		
			
				|  |  |  			#da.setFont(small_font)
 | 
	
		
			
				|  |  |  			da.setToolTip(dt)
 | 
	
		
			
				|  |  | -			da.setFlags(QtCore.Qt.ItemIsEnabled)
 | 
	
		
			
				|  |  | +			da.setFlags(Qt.ItemIsEnabled)
 | 
	
		
			
				|  |  |  			self.lb.setItem(i,1,da)
 | 
	
		
			
				|  |  |  			si = this_file.getSize()
 | 
	
		
			
				|  |  |  			if si==FileObj.FILE_IS_DIR:
 | 
	
		
			
				|  |  | -				sa = SortableTableWidgetItem('',0)
 | 
	
		
			
				|  |  | +				sa = SortableTableWidgetItem('',0,this_file)
 | 
	
		
			
				|  |  |  				item.setIcon(dirIcon)
 | 
	
		
			
				|  |  |  			elif si==FileObj.FILE_IS_LINK:
 | 
	
		
			
				|  |  | -				sa = SortableTableWidgetItem('symlink',-1)
 | 
	
		
			
				|  |  | +				sa = SortableTableWidgetItem('symlink',-1,this_file)
 | 
	
		
			
				|  |  |  				item.setIcon(linkIcon)
 | 
	
		
			
				|  |  |  				dst = os.path.realpath(this_file.getName())
 | 
	
		
			
				|  |  |  				sa.setToolTip("symlink: " + dst)
 | 
	
		
			
				|  |  |  			else:
 | 
	
		
			
				|  |  | -				sa = SortableTableWidgetItem(str(si),si)
 | 
	
		
			
				|  |  | +				sa = SortableTableWidgetItem(str(si),si,this_file)
 | 
	
		
			
				|  |  |  				item.setIcon(fileIcon)
 | 
	
		
			
				|  |  | -			sa.setTextAlignment(QtCore.Qt.AlignRight)
 | 
	
		
			
				|  |  | -			sa.setFlags(QtCore.Qt.ItemIsEnabled)
 | 
	
		
			
				|  |  | +			sa.setTextAlignment(Qt.AlignRight)
 | 
	
		
			
				|  |  | +			sa.setFlags(Qt.ItemIsEnabled)
 | 
	
		
			
				|  |  |  			self.lb.setItem(i,2,sa)
 | 
	
		
			
				|  |  |  		self.refilling = False
 | 
	
		
			
				|  |  |  		self.lb.sortingEnabled = True
 | 
	
	
		
			
				|  | @@ -396,16 +425,17 @@ class DirNotes(QMainWindow):
 | 
	
		
			
				|  |  |  		if self.refilling:
 | 
	
		
			
				|  |  |  			return
 | 
	
		
			
				|  |  |  		print("debugging " + x.text() + " r:" + str(x.row()) + " c:" + str(x.column()))
 | 
	
		
			
				|  |  | -		print("      selected file: "+self.lb.item(x.row(),0).data(32).toPyObject().getName())
 | 
	
		
			
				|  |  | -		the_file = self.lb.item(x.row(),0).data(32).toPyObject()
 | 
	
		
			
				|  |  | +		print("      selected file: "+self.lb.item(x.row(),0).file_object.getName())
 | 
	
		
			
				|  |  | +		the_file = self.lb.item(x.row(),0).file_object
 | 
	
		
			
				|  |  |  		print("      and the row file is "+the_file.getName())
 | 
	
		
			
				|  |  | -		r = the_file.setComment(str(x.text())) # TODO: change priority
 | 
	
		
			
				|  |  | +		r = the_file.setXattrComment(str(x.text())) # TODO: change priority
 | 
	
		
			
				|  |  |  		if r:
 | 
	
		
			
				|  |  | -			self.db.log(the_file.getName(),x.text())
 | 
	
		
			
				|  |  | +			self.db.setData(the_file.getName(),x.text())
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	def restore_from_database(self):
 | 
	
		
			
				|  |  |  		print("restore from database")
 | 
	
		
			
				|  |  |  		# retrieve the full path name
 | 
	
		
			
				|  |  | -		fileName = str(self.lb.item(self.lb.currentRow(),0).data(32).toPyObject().getName())
 | 
	
		
			
				|  |  | +		fileName = str(self.lb.item(self.lb.currentRow(),0).file_object.getName())
 | 
	
		
			
				|  |  |  		print("using filename: "+fileName)
 | 
	
		
			
				|  |  |  		existing_comment = str(self.lb.item(self.lb.currentRow(),3).text())
 | 
	
		
			
				|  |  |  		print("restore....existing="+existing_comment+"=")
 | 
	
	
		
			
				|  | @@ -431,8 +461,9 @@ if __name__=="__main__":
 | 
	
		
			
				|  |  |  		p.dirname = p.dirname + '/'
 | 
	
		
			
				|  |  |  	print(p.dirname)
 | 
	
		
			
				|  |  |  	
 | 
	
		
			
				|  |  | -	db = DataBase()
 | 
	
		
			
				|  |  | +	db = dnDataBase()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	# TODO: if there's a file specified, jump to it
 | 
	
		
			
				|  |  |  	a = QApplication([])
 | 
	
		
			
				|  |  |  	dn = DirNotes(p.dirname,db)
 | 
	
		
			
				|  |  |  	dn.show()
 | 
	
	
		
			
				|  | @@ -471,7 +502,4 @@ user.xdg.publisher
 | 
	
		
			
				|  |  |  ''' commandline xattr
 | 
	
		
			
				|  |  |  getfattr -h (don't follow symlink) -d (dump all properties)
 | 
	
		
			
				|  |  |  '''
 | 
	
		
			
				|  |  | -''' qt set color
 | 
	
		
			
				|  |  | -               newitem.setData(Qt.BackgroundRole,QBrush(QColor("yellow")))
 | 
	
		
			
				|  |  | -'''
 | 
	
		
			
				|  |  |  ''' if the args line contains a file, jump to it '''
 |