def addToGW(self): lix = self.selectedIndexes() if len(lix) == 1 : # just one selected, presumably the on clicked-on qs = self.model().data(lix[0], Qt.DisplayRole).toString() mtxt = u'Add {0} to the good-words list?'.format(unicode(qs)) else : mtxt = u'Add {0} words to the good-words list?'.format(len(lix)) b = pqMsgs.okCancelMsg(mtxt,"This action cannot be undone.") if b : # user says do it, so let's do it. for ix in lix : qs = self.model().data(ix, Qt.DisplayRole).toString() # If the word has an alt spellcheck dictionary it has the # form "word/xx_XX" but we get rid of that with a split. # 'word'.split('/')[0] ==> 'word' word = unicode(qs).split('/')[0] IMC.goodWordList.insert(word) # fabricate an index to the flags field of the indexed row findex = self.model().index(ix.row(), 2) # get flag as an int instead of a fancy char string (flag, b) = self.model().data(findex, Qt.UserRole).toInt() flag &= 0xfff - IMC.WordMisspelt self.model().setData(findex,flag,Qt.UserRole) IMC.needMetadataSave |= IMC.wordlistsChanged IMC.mainWindow.setWinModStatus() # and, having done it, spellcheck is now appropriate IMC.needSpellCheck = True
def insertMarkers(self): # Copy the text and if it is empty, complain and exit. qi = QString(self.insertText.text()) if qi.isEmpty(): pqMsgs.warningMsg("No insert text specified") return # See how many pages are involved: all the ones that aren't marked skip n = 0 for i in range(IMC.pageTable.size()): if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip: n += 1 if n == 0: # page table empty or all rows marked skip pqMsgs.warningMsg("No pages to give folios to") return m = "Insert this string at the top of {0} pages?".format(n) b = pqMsgs.okCancelMsg(QString(m), pqMsgs.trunc(qi, 35)) if b: # Convert any '\n' in the text to the QT line delimiter char # we do this in the copy so the lineEdit text doesn't change qi.replace(QString(u'\\n'), QString(IMC.QtLineDelim)) # get a cursor on the edit document tc = QTextCursor(IMC.editWidget.textCursor()) tc.beginEditBlock() # start single undoable operation # Working from the end of the document backward, go to the # top of each page and insert the string for i in reversed(range(IMC.pageTable.size())): if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip: # Note the page's start position and set our work cursor to it pos = IMC.pageTable.getCursor(i).position() tc.setPosition(pos) # Make a copy of the insert string replacing %f with this folio f = IMC.pageTable.getDisplay(i) qf = QString(qi) qf.replace(QString(u'%f'), f, Qt.CaseInsensitive) tc.insertText(qf) # The insertion goes in ahead of the saved cursor position so now # it points after the inserted string. Put it back where it was. IMC.pageTable.setPosition(i, pos) tc.endEditBlock() # wrap up the undo op
def insertMarkers(self): # Copy the text and if it is empty, complain and exit. qi = QString(self.insertText.text()) if qi.isEmpty() : pqMsgs.warningMsg("No insert text specified") return # See how many pages are involved: all the ones that aren't marked skip n = 0 for i in range(IMC.pageTable.size()): if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip : n += 1 if n == 0 : # page table empty or all rows marked skip pqMsgs.warningMsg("No pages to give folios to") return m = "Insert this string at the top of {0} pages?".format(n) b = pqMsgs.okCancelMsg(QString(m),pqMsgs.trunc(qi,35)) if b : # Convert any '\n' in the text to the QT line delimiter char # we do this in the copy so the lineEdit text doesn't change qi.replace(QString(u'\\n'),QString(IMC.QtLineDelim)) # get a cursor on the edit document tc = QTextCursor(IMC.editWidget.textCursor()) tc.beginEditBlock() # start single undoable operation # Working from the end of the document backward, go to the # top of each page and insert the string for i in reversed( range( IMC.pageTable.size() ) ) : if IMC.pageTable.getAction(i) != IMC.FolioRuleSkip : # Note the page's start position and set our work cursor to it pos = IMC.pageTable.getCursor(i).position() tc.setPosition(pos) # Make a copy of the insert string replacing %f with this folio f = IMC.pageTable.getDisplay(i) qf = QString(qi) qf.replace(QString(u'%f'),f,Qt.CaseInsensitive) tc.insertText(qf) # The insertion goes in ahead of the saved cursor position so now # it points after the inserted string. Put it back where it was. IMC.pageTable.setPosition(i, pos) tc.endEditBlock() # wrap up the undo op
def checkForUpdates(): # Step one, read the code display for the master page = slurp('https://github.com/tallforasmurf/PPQT') if page is None: pqMsgs.warningMsg('Unable to contact Github', 'Perhaps try again later?') return # the embedded URLs usable. hit = reGetMasterSHA.search(page) if hit is None: pqMsgs.warningMsg('Github page format not as expected', 'Probable bug, update not available') return masterSHA = hit.group(1) page = re.sub(masterSHA, 'master', page) # Step three, make a list of all the "blobs" mentioned, which is just # all the committed modules, pqXXX.py and pqHelp.html. Ignoring the # extras -- the extras folder appears as a "tree" item and we could # follow it and list all the blobs extras/* but we are not. blobs = reBlobLine.findall(page) # blobs is a list of 4-tuples, the (/1, /2, /3, /4) from reBlobLine above # Now make a dict with 3-item values, # { modname:[ None, masterhash, masterURL] } where None will be filled # in with the local hash value shortly. blobTab = {} for blob in blobs: blobURL = u'https://raw.github.com' + blob[0] + u'/' + blob[1] blobName = blob[3] blobHash = blob[2] blobTab[blobName] = [None, blobHash, blobURL] # Look for the file modulehash.txt and if it exists, use it to fill # in the local hashes it lists. We do not distribute so it doesn't # show up in the github listing. We want the local hash to reflect # the actual local files, which might have been diddled locally. mhPath = os.path.join(IMC.appBasePath, 'modulehashes.txt') try: mhFile = open(mhPath, 'r') for line in mhFile: [modname, localhash] = line.split() if modname in blobTab: blobTab[modname][0] = localhash except: # presumably the file doesn't exist pass # Run through the blobTab and try to get hash values for any # modules that don't have a local hash yet (because modulehashes # didn't exist -- or didn't list them because they're new to us). for modName in blobTab: if blobTab[modName][0] is None: modPath = os.path.join(IMC.appBasePath, modName) try: modFile = open(modPath, 'r') modText = modFile.read() hasher = initializedSHA1.copy() hasher.update(str(len(modText))) hasher.update(b'\000') hasher.update(modText) blobTab[modName][0] = hasher.hexdigest() except: # presumably modname doesn't exist (new module?) pass # Run through the blobTab and make a new table, updaTab, listing # the members where localhash differs from master hash. updaTab = {} for modName in blobTab: if blobTab[modName][0] != blobTab[modName][1]: updaTab[modName] = blobTab[modName] # If there are no names left in the updaTab, the app is up to date! if len(updaTab) == 0: pqMsgs.infoMsg('PPQT is up to date.') return # There are one or more modules needing updating. Ask the user # if we should proceed. ans = pqMsgs.okCancelMsg( '{0} module(s) can be updated.'.format(len(updaTab)), 'Shall we proceed?') if not ans: pqMsgs.infoMsg('PPQT remains unchanged.') return # User said OK to do it. Read the text of the updated modules from # github and save it in the updaTab. for modName in updaTab: page = slurp(updaTab[modName][2]) if page is None: pqMsgs.warningMsg('Some problem reading update modules', 'PPQT is unchanged.') return updaTab[modName].append(page) # All update texts read correctly. Now open each for writing, # appending the file object to the updaTab entry. for modName in updaTab: try: modPath = os.path.join(IMC.appBasePath, modName) modFile = open(modPath, 'w') updaTab[modName].append(modFile) except Exception: pqMsgs.warningMsg('Updated modules are not writable' 'PPQT is unchanged.') return # All files open for writing and text is ready. Write them. for modName in updaTab: try: modFile = updaTab[modName][4] modFile.write(updaTab[modName][3]) modFile.flush() os.fsync(modFile.fileno()) modFile.close() except Exception as e: # This is the bad case: some amount of writing done but not # all of it complete. PPQT is in an inconsistent state. pqMsgs.warningMsg( 'Error writing updated module(s)!', 'PPQT is in an inconsistent state\nDownload a complete new copy' ) return # All updates complete. Record local hashes in modulehashes.txt try: mhFile = open(mhPath, 'w') for modName in blobTab: mhFile.write(modName + ' ' + blobTab[modName][1] + '\n') mhFile.close() except Exception as e: pass pqMsgs.infoMsg('Updates applied.', 'Changes take effect when PPQT is restarted.') return
def checkForUpdates(): # Step one, read the code display for the master page = slurp('https://github.com/tallforasmurf/PPQT') if page is None: pqMsgs.warningMsg('Unable to contact Github', 'Perhaps try again later?') return # the embedded URLs usable. hit = reGetMasterSHA.search(page) if hit is None: pqMsgs.warningMsg('Github page format not as expected', 'Probable bug, update not available') return masterSHA = hit.group(1) page = re.sub(masterSHA,'master',page) # Step three, make a list of all the "blobs" mentioned, which is just # all the committed modules, pqXXX.py and pqHelp.html. Ignoring the # extras -- the extras folder appears as a "tree" item and we could # follow it and list all the blobs extras/* but we are not. blobs = reBlobLine.findall(page) # blobs is a list of 4-tuples, the (/1, /2, /3, /4) from reBlobLine above # Now make a dict with 3-item values, # { modname:[ None, masterhash, masterURL] } where None will be filled # in with the local hash value shortly. blobTab = {} for blob in blobs: blobURL = u'https://raw.github.com' + blob[0] + u'/' + blob[1] blobName = blob[3] blobHash = blob[2] blobTab[blobName] =[None,blobHash,blobURL] # Look for the file modulehash.txt and if it exists, use it to fill # in the local hashes it lists. We do not distribute so it doesn't # show up in the github listing. We want the local hash to reflect # the actual local files, which might have been diddled locally. mhPath = os.path.join(IMC.appBasePath,'modulehashes.txt') try: mhFile = open(mhPath,'r') for line in mhFile: [modname, localhash] = line.split() if modname in blobTab: blobTab[modname][0] = localhash except: # presumably the file doesn't exist pass # Run through the blobTab and try to get hash values for any # modules that don't have a local hash yet (because modulehashes # didn't exist -- or didn't list them because they're new to us). for modName in blobTab: if blobTab[modName][0] is None: modPath = os.path.join(IMC.appBasePath,modName) try: modFile = open(modPath,'r') modText = modFile.read() hasher = initializedSHA1.copy() hasher.update(str(len(modText))) hasher.update(b'\000') hasher.update(modText) blobTab[modName][0] = hasher.hexdigest() except: # presumably modname doesn't exist (new module?) pass # Run through the blobTab and make a new table, updaTab, listing # the members where localhash differs from master hash. updaTab = {} for modName in blobTab: if blobTab[modName][0] != blobTab[modName][1] : updaTab[modName] = blobTab[modName] # If there are no names left in the updaTab, the app is up to date! if len(updaTab) == 0: pqMsgs.infoMsg('PPQT is up to date.') return # There are one or more modules needing updating. Ask the user # if we should proceed. ans = pqMsgs.okCancelMsg('{0} module(s) can be updated.'.format(len(updaTab)), 'Shall we proceed?') if not ans: pqMsgs.infoMsg('PPQT remains unchanged.') return # User said OK to do it. Read the text of the updated modules from # github and save it in the updaTab. for modName in updaTab: page = slurp(updaTab[modName][2]) if page is None: pqMsgs.warningMsg('Some problem reading update modules', 'PPQT is unchanged.') return updaTab[modName].append(page) # All update texts read correctly. Now open each for writing, # appending the file object to the updaTab entry. for modName in updaTab: try: modPath = os.path.join(IMC.appBasePath,modName) modFile = open(modPath, 'w') updaTab[modName].append(modFile) except Exception: pqMsgs.warningMsg('Updated modules are not writable' 'PPQT is unchanged.') return # All files open for writing and text is ready. Write them. for modName in updaTab: try: modFile = updaTab[modName][4] modFile.write(updaTab[modName][3]) modFile.flush() os.fsync(modFile.fileno()) modFile.close() except Exception as e: # This is the bad case: some amount of writing done but not # all of it complete. PPQT is in an inconsistent state. pqMsgs.warningMsg('Error writing updated module(s)!', 'PPQT is in an inconsistent state\nDownload a complete new copy') return # All updates complete. Record local hashes in modulehashes.txt try: mhFile = open(mhPath,'w') for modName in blobTab: mhFile.write(modName + ' ' + blobTab[modName][1] + '\n') mhFile.close() except Exception as e: pass pqMsgs.infoMsg('Updates applied.', 'Changes take effect when PPQT is restarted.') return