Hi Borys,<br><br>That is an excellent plugin, but I found an error and fixed for xp. The error occurs when insert a new field and click the save button in win xp. <br><br>i actually do not know how to prepare a python patch in pythonic way, but i marked my changed code between the commented blocks like "BEGIN SECTION"<br>
<br>you can find more explanation in the code.<br><br>could you look at my suggestion and if it is ok for you, could you let me know when the plugin is revised in your repo?<br><br>i want to test your plugin.<br><br>regards,<br>
volkan.<br><br> def doSave(self): # Called when appropriate button was pressed<br> # I believe the procedure below is as much safe as it's only possible...<br><br> ##temporary checking<br> for i in self.fields:<br>
for j in self.fields:<br> if self.fields[i].name().toUpper() == self.fields[j].name().toUpper() and self.fields[i]!=self.fields[j]:<br> QMessageBox.warning(self, 'Table Manager', 'The names of two fields (%s and %s) are the same.\nQuantum GIS isn\'t fully case-sensitive yet, so you have to type unique field names, without distinguishing lower and upper case.' % (self.fields[i].name(), self.fields[j].name()))<br>
return<br> ##end of temporary checking<br><br> tmpDir = QDir.tempPath()<br> srcPath = self.provider.dataSourceUri()<br><br> # BEGIN SECTION: PATCH #1 <br> # without this one line code in win xp, srcName return something wrong, see below.<br>
srcPath = srcPath.replace("\\","/")<br> # END PATCH<br> <br> if srcPath.right(4).toUpper() == '.SHP': # if the path points to the shp file, remove the extension...<br> srcPath.chop(4)<br>
srcName = srcPath.right(srcPath.size() - srcPath.lastIndexOf('/') - 1)<br> else: # ...but if it points only to a directory, try to determine the name of the file inside!<br> qPath = QDir(srcPath)<br>
qPath.setNameFilters(['*.shp', '*.SHP'])<br> if len(qPath.entryList()) == 1: # there is exactly one shapefile inside<br> srcName = qPath.entryList()[0]<br> srcName.chop(4)<br> srcPath += '/' + srcName <br>
else:<br> QMessageBox.warning(self, 'Table Manager', 'I cannot determine the layer source file: ' + srcPath + " !\nThe layer won't be changed, please use the Save As button.")<br>
return<br> <br> # BEGIN SECTION: PATCH #2 <br> # if one line code - srcPath = srcPath.replace("\\","/") - is NOT added, the error with msgbox is - Error creating file. Check permissions. -, because<br>
# srcPath returns: "C:\temp\noNumeric"<br> # and srcName is "C:\temp\noNumeric" -- that is not OK for writeToShp function<br><br> # when this code added, now is ok, because then both variable returns:<br>
# srcPath: "C:/temp/noNumeric"<br> # srcName: "noNumeric"<br><br> # these suggestions are specific to win xp, but NOT tested in linux.<br> # END PATCH<br> <br> # write the layer to the temporary directory<br>
if self.writeToShp(tmpDir+'/'+srcName+'.shp', self.provider.encoding()) != 0:<br> QMessageBox.warning(self, 'Table Manager', 'Failed saving the changes to the temporary directory: ' + tmpDir + " !\nThe layer won't be changed, please use the Save As button.")<br>
QgsVectorFileWriter.deleteShapeFile(tmpDir+'/'+srcName+'.shp')<br> return<br> # try to remove the old .dbf~ backup<br> QFile(srcPath+'.dbf~').remove()<br> # rename the oryginal .dbf file to .dbf~<br>
if not QFile(srcPath+'.dbf').rename(srcPath+'.dbf~'):<br> QMessageBox.warning(self, 'Table Manager', 'Failed backuping the old table to '+srcPath+".dbf~\nThe layer won't be changed, please use the Save As button.")<br>
QgsVectorFileWriter.deleteShapeFile(tmpDir+'/'+srcName+'.shp')<br> return<br><br> # BEGIN SECTION: PATCH #3<br> # QFile can not overwrite for copy and rename. srcPath+'.dbf' file is already exist. instead of QFile, i used shutil.copy<br>
import shutil<br> shutil.copy(tmpDir+'/'+srcName+'.dbf', srcPath+'.dbf')<br> QFile(srcPath+'.dbf~').remove() <br> """<br> # copy the .dbf from the temp directory to the target location<br>
#if not QFile(tmpDir+'/'+srcName+'.dbf').copy(srcPath+'.dbf'):<br> # something went wrong. Restore the dbf~ file<br> if not QFile(srcPath+'.dbf~').rename(srcPath+'.dbf'):<br>
QMessageBox.warning(self, 'Table Manager', 'WARNING! I can neither save the new '+srcPath+'.dbf file\nnor restore it from the '+srcPath+'.dbf~ backup.\nPlease check it manually!')<br>
return<br> QMessageBox.warning(self, 'Table Manager', 'Failed saving the changes to '+srcPath+".dbf\nThe layer will not be changed, please use the Save As button.")<br> QgsVectorFileWriter.deleteShapeFile(tmpDir+'/'+srcName+'.shp')<br>
return<br> """<br> # END PATCH<br> <br> # clean the temp directory<br> QgsVectorFileWriter.deleteShapeFile(tmpDir+'/'+srcName+'.shp')<br> # create the new layer<br> layerName = <a href="http://self.layer.name">self.layer.name</a>()<br>
newLayer = QgsVectorLayer(srcPath+'.shp', layerName, 'ogr')<br> if not newLayer.isValid():<br> QMessageBox.warning(self, 'Table Manager', "WARNING! The changes seem to be commited, but I can't reload the layer!\nPlease check it out!\nThe old table is backuped as "+srcName+'.dbf~.')<br>
return<br> # copy the symbology (it's possible only if the clasyfying field was not moved nor changed!)<br> if QMessageBox.question(self, 'Saving successful','Saving successful. The old table has been backuped as '+srcName+".dbf~. Do you wish to keep the old symbology? Note that if the clasyfying field was moved, all objects can become invisible. In that case please adjust the symbology manually.", QMessageBox.Yes, QMessageBox.No) == QMessageBox.Yes:<br>
newLayer.copySymbologySettings(self.layer)<br> # reload the layer<br> QgsMapLayerRegistry.instance().removeMapLayer(self.layer.getLayerID())<br> QgsMapLayerRegistry.instance().addMapLayer(newLayer)<br> # point the self.layer to the new one.<br>
self.layer = self.iface.activeLayer()<br> self.provider = self.layer.dataProvider()<br> self.fields = self.provider.fields()<br> self.butSave.setEnabled(False)<br> self.saveCfg() # save cfg only in case of any successfull operations, not when user just play ;)<br>
self.isUnsaved = False<br><br>