"""
     qtgui/CCP4FileBrowser.py: CCP4 Gui Project
     Copyright (C) 2001-2008 University of York, CCLRC
     Copyright (C) 2009-2010 University of York

     This library is free software: you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public License
     version 3, modified in accordance with the provisions of the 
     license to address the requirements of UK law. 
     You should have received a copy of the modified GNU Lesser General 
     Public License along with this library.  If not, copies may be 
     downloaded from http://www.ccp4.ac.uk/ccp4license.php
 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU Lesser General Public License for more details.
"""

'''
Liz Potterton Mar 10 - Copied from ccp4mg/qtgui/MGWidgets.py
Liz Potterton Apr 12 - Rewrite from basics to fix the failure of select by double clicking
'''


##@package CCP4FileBrowser (QtGui) File browser - based on QtFileDialog but aware of ccp4 projects
import os
from PyQt4 import QtGui,QtCore
import CCP4Modules
import CCP4File

class CFileDialog(QtGui.QDialog):
  NewDirectory = 101
  NewFolder = 102
  def __init__(self,parent=None,title='Open file',filters=[],defaultSuffix=None,defaultFileName='',
               fileMode=QtGui.QFileDialog.ExistingFile,fileLabel=None,**kw):
    QtGui.QDialog.__init__(self,parent)

    if CCP4Modules.PREFERENCES().NATIVEFILEBROWSER:
      self.input = { 'title' : title,
                     'filters' : filters,
                     'defaultSuffix':defaultSuffix,
                     'defaultFileName' : defaultFileName,
                     'fileMode' : fileMode,
                     'fileLabel' : fileLabel,
                     'kw' : kw }
      
      return
    
    self.setWindowTitle(title)
    self.useGetExistingDirectory = False
    #print 'CFileDialog',filters,defaultSuffix,fileMode,fileLabel
  
    layout = QtGui.QGridLayout()
    self.widget = CFileDialog1(self,fileLabel=fileLabel,projectCombo=kw.get('projectCombo',True))
    layout.addWidget(self.widget,1,0)
    self.setLayout(layout)
    if fileMode in [QtGui.QFileDialog.ExistingFile,QtGui.QFileDialog.ExistingFiles,QtGui.QFileDialog.Directory]:
      self.widget.fileDialog.setFileMode(fileMode)
    elif fileMode == CFileDialog.NewDirectory:
      self.widget.fileDialog.setFileMode(QtGui.QFileDialog.AnyFile)
      #print 'CFileDialog.__init__ saveButton',fileMode, self.widget.fileDialog.saveButton()
      saveButton = self.widget.fileDialog.saveButton()
      if saveButton is not None: saveButton.setText('Create')
    elif fileMode == CFileDialog.NewFolder:
      self.widget.fileDialog.setFileMode(QtGui.QFileDialog.Directory)
      self.useGetExistingDirectory = True
    elif fileMode == QtGui.QFileDialog.AnyFile:
      self.widget.fileDialog.setFileMode(QtGui.QFileDialog.AnyFile)
      self.widget.fileDialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)
      self.widget.fileDialog.setConfirmOverwrite(False)
      if defaultSuffix is not None: self.widget.fileDialog.setDefaultSuffix(defaultSuffix)

    if fileMode in [QtGui.QFileDialog.Directory,CFileDialog.NewDirectory,CFileDialog.NewFolder]: self.widget.fileDialog.setOptions(QtGui.QFileDialog.ShowDirsOnly)

    if kw.has_key('saveButtonText'):
      saveButton = self.widget.fileDialog.saveButton()
      if saveButton is not None: saveButton.setText(kw['saveButtonText'])

    self.suffix_lookup = {}
    filters = self.makeSuffixLookup(filters,addAll=kw.get('addAll',True))
    filters.append('All files ( *.* )')
    #print 'CFileDialog filter',filters
    self.widget.fileDialog.setFilters(filters)
    #self.connect(self.widget.fileDialog,QtCore.SIGNAL('fileSelected(const QString&)'),self.handleFilesSelected)
    if self.suffix_lookup:
      self.setSuffix(filters[0][0])
      self.connect(self,QtCore.SIGNAL('filterSelected(QString)'),self.setSuffix)

    self.connect(self.widget.fileDialog,QtCore.SIGNAL('filesSelected(const QStringList&)'),self.handleFilesSelected)
    self.connect(self.widget.fileDialog,QtCore.SIGNAL('rejected()'),self.handleRejected)
    

  def handleRejected(self):
    self.emit(QtCore.SIGNAL('rejected()'))
    self.close()

  def setFileMode(self,arg):
    self.widget.fileDialog.setFileMode(arg)

  def setAcceptMode(self,arg):
    self.widget.fileDialog.setAcceptMode(arg)

  def setConfirmOverwrite(self,arg):
    self.widget.fileDialog.setConfirmOverwrite(arg)
                                                                                      
  def setSuffix(self,filter):
    filter = str(filter)
    #print "setSuffix",filter
    if self.suffix_lookup.has_key(filter):
      self.widget.fileDialog.setDefaultSuffix(self.suffix_lookup[filter])

  def handleFilesSelected(self,selectedFiles):
    files = self.filesToPy(selectedFiles)
    #print 'CFileDialog.handleFilesSelected',files
    #if self.widget.fileDialog.fileMode == QtGui.QFileDialog.Directory and len(files) == 1:
    #  print 'CFileDialog.handleFilesSelected is directory',os.path.exisists(files[0])
    #print 'CFileDialog.handleFilesSelected', files, self.widget.download
    if files[0] != self.widget.download.get('fileName',''): self.widget.download = {}
    self.emit(QtCore.SIGNAL('selectDownloadedFile'),files[0],self.widget.download)
    self.emit(QtCore.SIGNAL('selectFile'),files[0])
    self.emit(QtCore.SIGNAL('selectFiles'),files)
    self.close()

  
  def handleSaveButton(self):
    selectedFiles = self.widget.fileDialog.selectedFiles()
    files = self.filesToPy(selectedFiles)
    print 'CFileDialog.handleSaveButton',files
    if files[0] != self.widget.download.get('fileName',''): self.widget.download = {}
    self.emit(QtCore.SIGNAL('selectDownloadedFile'),files[0],self.widget.download)
    self.emit(QtCore.SIGNAL('selectFile'),files[0])
    self.emit(QtCore.SIGNAL('selectFiles'),files)
    self.close()

  def filesToPy(self,selectedFiles):
    #mode = self.widget.fileDialog.fileMode()
    files = []
    for ff in selectedFiles:
      f = str(ff)
      # QFileDialog should have added suffux for us if the defaultSuffix has been set
      #if mode == QtGui.QFileDialog.AnyFile and len(os.path.splitext(f)[1])==0: f = f + str(self.widget.fileDialog.defaultSuffix())
      files.append(f)
    return files

  def isVisible(self):
    return self.widget.fileDialog.isVisible()

  def show(self):
    #print 'CFileDialog.show',self.useGetExistingDirectory
    if CCP4Modules.PREFERENCES().NATIVEFILEBROWSER:
      # OpenFileName with double extension messing up see: https://bugreports.qt.io/browse/QTBUG-44227
      print 'CFileDialog.show',self.input['filters'][0]
      filterText,secondExt = self.makeFilterText(self.input['filters'],truncateExt=(self.input['fileMode'] == QtGui.QFileDialog.AnyFile))
      if self.input['fileMode'] == QtGui.QFileDialog.ExistingFile:
        fileName = QtGui.QFileDialog.getOpenFileName ( self, self.input['title'], '',filterText, '' )
      elif self.input['fileMode'] == QtGui.QFileDialog.AnyFile:
        fileName = QtGui.QFileDialog.getSaveFileName ( self, self.input['title'], '', filterText, '' )
      elif self.input['fileMode'] == QtGui.QFileDialog.ExistingDirectory:
        fileName = QtGui.QFileDialog.getSaveFileName ( self, self.input['title'], '', filterText, '' )
      if fileName is not None:
        fileName = str(fileName)
        if self.input['fileMode'] == QtGui.QFileDialog.AnyFile and secondExt is not None and not fileName.endswith(secondExt):
          fileName = fileName+'.'+secondExt
        print 'CFileDialog.show',fileName
        self.emit(QtCore.SIGNAL('selectFile'),fileName)
        self.emit(QtCore.SIGNAL('selectFiles'),fileName)
        self.close()
        return

    
    if self.useGetExistingDirectory:
      rv = self.widget.fileDialog.getExistingDirectory(self)
      fileName = str(rv)
      self.emit(QtCore.SIGNAL('selectFile'),fileName)
      self.emit(QtCore.SIGNAL('selectFiles'),fileName)
      self.close()
    else:
      self.widget.fileDialog.show()
      QtGui.QDialog.show(self)

  def makeFilterText(self,filterList,truncateExt=False):
    import re
    filterText = ''
    secondExt = None
    for ff in filterList:
      if not truncateExt:
        filterText = filterText + ff + ';;'
      else:
        try:
          m = re.match('(.*)\((.*)\)',ff)
          lab,exTxt = m.groups()
          lab = lab + '('
          exList = exTxt.split()
          if exList[0].count('.')>1: secondExt = exList[0].split('.')[-1]
          for ex in exList:
            lab = lab + '*.'+ ex.split('.')[1] + ' '
          filterText = filterText + lab[0:-1]+');;'
        except Exception as e:
          print 'makeFilterText error',e
          filterText = filterText + ff + ';;'
    print 'makeFilterText',filterList,filterText[0:-2],'secondExt',secondExt
    return filterText[0:-2],secondExt

    
  def makeSuffixLookup(self,filters,addAll=True):
    import types
    if len(filters)==0: return []
    all_filters = "All files ("
    new_filters = []
    for filt in filters:
      #print "setNameFilters filt",filt
      if isinstance(filt,types.ListType):
        self.suffix_lookup[filt[0]] = filt[1]
        filter = str(filt[0])
      else:
        filter = str(filt)
      if len(filter)>11 and filter[:11] == 'All files (' and (filter).rfind(')') > 0:
        pass
      else:
        new_filters.append(filter)
        left_par = filter.rfind('(')
        right_par = filter.rfind(')')
        if left_par > -1 and right_par > 0 and right_par > left_par:
          if (filter[left_par+1:right_par]).find('*')>-1:
             all_filters = all_filters + " " + filter[left_par+1:right_par]
          else:
            all_filters = all_filters + " " + filter
        else:
          all_filters = all_filters + " " + filter
    all_filters = all_filters + " )"
    if addAll and len(new_filters)>1: new_filters.append(all_filters)
    return new_filters
        
  def setDownloadMode(self,modeList=['ebiPdb'],projectId=None):
    self.widget.drawDownload(modeList=modeList,projectId=projectId)

  def addWidget(self,widget):
    self.layout().addWidget(widget,0,0)
    
class CFileDialog1(QtGui.QWidget):
  def __init__(self,parent=None,projectCombo=True,downloadOnlyMode=False,fileLabel=None):
    QtGui.QWidget.__init__(self,parent)
    self.DOWNLOAD_DEFINITIONS = { 'ebiPdb' : { 'label' : 'Download PDB from EBI-PDBe. 4-letter code:' ,
                                      #'url' : 'http://www.ebi.ac.uk/pdbe-srv/view/files/CODE.ent'
                                       'url' :  'ftp://ftp.ebi.ac.uk/pub/databases/msd/pdb_uncompressed/pdbCODE.ent',
                                       'page' : 'www.ebi.ac.uk/pdbe',
                                       'rename' : 'CODE.pdb',
                                        'ext' : '.pdb' },
                                  'ebiSFs' : { 'label' : 'Download structure factord from EBI-PDBe. 4-letter code:' ,
                                               'url' : 'http://www.ebi.ac.uk/pdbe/entry-files/download/rCODEsf.ent',
                                               'page' : 'www.ebi.ac.uk/pdbe',
                                               'ext' : '.cif' },
                                  'Uppsala-EDS' : { 'label' : 'Download map coefficients from Uppsala Electron Density Server.  4-letter code:' ,
                                               'url' : 'http://eds.bmc.uu.se/eds/dfs/CODE13/CODE/CODE_sigmaa.mtz',
                                                'page' : 'http://eds.bmc.uu.se/eds/',
                                                 'ext' : '_sigmaa.mtz' },
                                   'rcsbPdb' : {  'label' : 'Download PDB from RCSB. 4-letter code:' ,
                                                 'url' : 'http://www.rcsb.org/pdb/cgi/export.cgi/CODE.pdb?job=download;pdbId=CODE;opt=show;format=PDB;pre=1',
                                                 'page' : 'http://www.rcsb.org/pdb/home/home.do',
                                                 'rename' : 'CODE.pdb',
                                                 'ext' : '.pdb' },
                                  'uniprotFasta' : { 'label' : 'Download sequence from uniprot database',
                                                     'url':'http://www.uniprot.org/uniprot/CODE.fasta',
                                                     'page' : 'www.uniprot.org',
                                                     'ext' : '.fasta' }
                         }
    self.projectId = None
    self.fileLabel = fileLabel
    self.downloadOnlyMode = downloadOnlyMode
    self.downloader = None
    self.download = {}
    self.downloadProgressFrame= None
    self.downloadProgress = None
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(2)
    layout.setContentsMargins(2,2,2,2)
    self.setLayout(layout)
    # This is the weird bit - CFileDialog0 must have the CFileDialog as parent
    # for it to appear in the CFileDialog diaolog box
    if not self.downloadOnlyMode:
      if projectCombo: self.drawProjectCombo()
      self.fileDialog = CFileDialog0(parent)
      layout.addWidget(self.fileDialog)
    self.ccp4i_combo = None

  def drawProjectCombo(self):
    ccp4_dirs,ccp4_aliases =  CCP4Modules.PROJECTSMANAGER().getProjectsList()
    #print 'CFileDialog.__init__', ccp4_dirs,ccp4_aliases
    #if len(ccp4_dirs)>0 or len(ccp4_aliases)>0:
      
    layout0 = QtGui.QHBoxLayout()
    self.projectCombo = QtGui.QComboBox()
    self.projectCombo.setEditable(False)
    self.loadProjectCombo()
    ccp4i_label1 = QtGui.QLabel()
    ccp4i_label1.setText("Look in ccp4 project:")
    ccp4i_label2 = QtGui.QLabel(" or ...")
           
    layout0.addWidget(ccp4i_label1)
    layout0.addWidget(self.projectCombo)
    layout0.addWidget(ccp4i_label2)
    layout0.addStretch()
    self.layout().addLayout(layout0)

    self.connect(self.projectCombo,QtCore.SIGNAL("activated(const QString&)"),self.projectComboChanged)
    self.connect(CCP4Modules.PROJECTSMANAGER(),QtCore.SIGNAL('projectsListChanged'),self.loadProjectCombo)
    
  def loadProjectCombo(self):
    self.projectCombo.clear()
    self.projectCombo.addItem('Full path..')
    ccp4_dirs,ccp4_aliases =  CCP4Modules.PROJECTSMANAGER().getProjectsList()
    for project in ccp4_dirs: self.projectCombo.addItem(project)
    
    
  def projectComboChanged(self,alias):
      path = CCP4Modules.PROJECTSMANAGER().getProjectDirectory(projectName=str(alias))
      #print "CFileBrowser.ccp4iDirectoryChanged",alias,path
      if path is not None: self.fileDialog.setDirectory(str(path))

  def drawDownload(self,modeList=[],projectId=None):
    #print 'CFileDialog1.drawDownload',modeList,projectId
    if modeList is None: return
    if not isinstance(modeList,list): modeList = [ modeList ]
    self.projectId = projectId
    self.downloadFrame = QtGui.QFrame(self)
    layout0 = QtGui.QHBoxLayout()
    self.downloadFrame.setLayout(layout0)
    layout0.setSpacing(1)
    layout0.setContentsMargins(0,0,0,0)
    self.downloadCombo =  QtGui.QComboBox()
    self.downloadCombo.setEditable(False)
    for mode in modeList:
      try:
        self.downloadCombo.addItem(self.DOWNLOAD_DEFINITIONS[mode]['label'],QtCore.QVariant(mode))
      except:
        pass
    if self.downloadCombo.count()<=0:
      self.downloadCombo.deleteLater()
      del self.downloadCombo
      return
    layout0.addWidget(self.downloadCombo)
    self.downloadCode =  QtGui.QLineEdit(self)
    self.downloadCode.setMinimumWidth(40)
    self.connect(self.downloadCode,QtCore.SIGNAL('returnPressed()'),self.handleDownload)
    layout0.addWidget(self.downloadCode)
    downloadButton = QtGui.QPushButton('Download',self)
    self.connect(downloadButton,QtCore.SIGNAL('released()'),self.handleDownload)
    viewButton = QtGui.QPushButton('View website',self)
    self.connect(viewButton,QtCore.SIGNAL('released()'),self.viewWebSite)
    if self.downloadOnlyMode:
      self.butFrame =  QtGui.QFrame(self)
      self.butFrame.setLayout(QtGui.QHBoxLayout())
      self.butFrame.layout().addWidget(downloadButton)
      self.butFrame.layout().addWidget(viewButton)
      self.layout().addWidget(self.butFrame)
    else:
      layout0.setStretchFactor(self.downloadCombo,3)
      layout0.addWidget(downloadButton)
      layout0.addWidget(viewButton)

    #self.layout().insertLayout(0,layout0)
    self.layout().insertWidget(0,self.downloadFrame)
    self.diagDone=False

  def drawDownloadProgress(self):
    if self.downloadProgressFrame is None:
      self.downloadProgressFrame = QtGui.QFrame(self)
      layout0 = QtGui.QHBoxLayout()
      self.downloadProgressFrame.setLayout(layout0)
      layout0.setSpacing(1)
      layout0.setContentsMargins(0,0,0,0)
      layout0.addWidget(QtGui.QLabel('Downloading:',self))
      self.downloadProgress = QtGui.QProgressBar(self.parent())
      self.downloadProgress.setMinimum(0)
      self.downloadProgress.setMaximum(100)
      layout0.addWidget(self.downloadProgress)
      interrupt = QtGui.QPushButton('Stop download',self)
      layout0.addWidget(interrupt)
      self.connect(interrupt,QtCore.SIGNAL('released()'),self.handleInterruptDownload)
      self.layout().insertWidget(0,self.downloadProgressFrame)
    else:
      self.downloadProgressFrame.show()
      self.downloadProgress.setValue(0)

    self.downloadFrame.hide()
    if self.downloadOnlyMode: self.butFrame.hide()

  def removeDownloadProgress(self):
    self.downloadProgressFrame.hide()
    self.downloadFrame.show()
    

  def downloadFileName(self,urlname,code=None,rename=None):
    import CCP4Utils
    if self.projectId is None:
      tmpDir = CCP4Utils.getTMP()
    else:
      tmpDir = os.path.join(CCP4Modules.PROJECTSMANAGER().getProjectDirectory(projectId=self.projectId),'CCP4_DOWNLOADED_FILES')
      if not os.path.exists(tmpDir):
        try:
          os.mkdir(tmpDir)
        except:
          tmpDir = CCP4Utils.getTMP()
    if code is not None and rename is not None:
      import re
      fileName = os.path.join(tmpDir,re.sub('CODE',code.lower(),rename))
    else:
      fileName = os.path.join(tmpDir,os.path.split(urlname)[1])
    #print 'downloadFileName urlname',urlname,fileName,os.path.exists(fileName)
    return fileName

  def handleDownload(self):
    mode = self.downloadCombo.itemData(self.downloadCombo.currentIndex()).toString().__str__()
    code = self.downloadCode.text().__str__()
    if len(code)<4:
      warning = QtGui.QMessageBox.warning(self,'Downloading data','Please enter code of at least 4 characters')
      return

    import re,functools
    urlname = re.sub('CODE13',code[1:3].lower(),self.DOWNLOAD_DEFINITIONS[mode]['url'])
    urlname = re.sub('CODE',code.lower(),urlname)
    rename = self.DOWNLOAD_DEFINITIONS[mode].get('rename',None)

    targetFile = self.downloadFileName(urlname,code=code,rename=rename)
    if os.path.exists(targetFile):
      question = QtGui.QMessageBox(self)
      question.setWindowTitle('Downloading data')
      question.setText('A file for '+code+' already exists.\nDo you want to use it or overwrite it?')
      question.addButton('Use existing file',QtGui.QMessageBox.YesRole)
      question.addButton('Delete file and re-download',QtGui.QMessageBox.NoRole)
      self.connect(question,QtCore.SIGNAL('buttonClicked(QAbstractButton*)'),functools.partial(self.handleQueryExistingFile,code,mode,targetFile))
      question.show()
      question.raise_()
      return

    #print 'handleDownload downloader',self.downloader
    if self.downloader is None:     
      self.drawDownloadProgress()
      import UtilityThread
      self.downloader =  CDownloader()
      self.connect(self.downloader,QtCore.SIGNAL('ProgressChanged'),self.handleProgress)
      self.connect(self.downloader,QtCore.SIGNAL('Finished'),functools.partial(self.handleDownloadFinished,code,mode,targetFile))
      self.connect(self.downloader,QtCore.SIGNAL('Error'),functools.partial(self.handleDownloadError,code))
      self.downloadThread = UtilityThread.UtilityThread(functools.partial(self.downloader.download,urlname))
      self.downloadThread.start()


  def handleInterruptDownload(self):
    #print 'handleInterruptDownload'
    self.downloader.interrupt_dl = True
    self.downloader = None
    self.downloadThread = None
    self.removeDownloadProgress()

  def handleQueryExistingFile(self,code,mode,targetFile,button):
    #print 'handleQueryExistingFile',button.text()
    if button.text().count('Delete'): 
      os.remove(targetFile)
      self.handleDownload()
    else:
      self.fileDialog.setDirectory(os.path.split(targetFile)[0])
      self.fileDialog.selectFile(targetFile)
      self.download = { 'code' : code, 'source' : mode, 'fileName' : targetFile }
    

  def handleDownloadError(self,code,message):
    self.downloader = None
    self.downloadThread = None
    self.removeDownloadProgress()
    #print 'handleDownloadError',code,message
    warning = QtGui.QMessageBox.warning(self,'Downloading data for '+code,message)

  def handleDownloadFinished(self,code,mode,targetFile,tempFile):
    print 'handleDownloadFinished',code,mode,targetFile,tempFile
    import shutil
    shutil.copyfile(tempFile,targetFile)
    self.downloader = None
    self.downloadThread = None
    self.removeDownloadProgress()
    self.download = { 'code' : code, 'source' : mode, 'fileName' : targetFile }
    if not self.downloadOnlyMode:
      self.fileDialog.setDirectory(os.path.split(targetFile)[0])
      self.fileDialog.selectFile(targetFile)
    else:
      # Beware signal from CFileDialog1 class when used in downloadOnlyMode 
      self.emit(QtCore.SIGNAL('selectDownloadedFile'),targetFile,self.download)

  def handleProgress(self,frac):
    try:
      self.downloadProgress.setValue(frac)
    except:
      #print 'handleProgress failed',frac
      pass
    
    
  def viewWebSite(self):
    mode = self.downloadCombo.itemData(self.downloadCombo.currentIndex()).toString().__str__()
    CCP4Modules.WEBBROWSER().loadPage(QtCore.QUrl('http://'+self.DOWNLOAD_DEFINITIONS[mode]['page']),newTab=True)
    
class IconProvider(QtGui.QFileIconProvider):
	def __init__(self):
		QtGui.QFileIconProvider.__init__(self)
		self._filters = {}
		self._icon_cache = {}

	def setIconForFilter(self,icon,filter):
		self._filters[icon] = filter

	def setIconsForFilters(self,filters):
		self._filters = filters

        def icon(self,fileInfo):
          #print 'CFileIconProvider.icon',fileInfo
          if isinstance(fileInfo,QtCore.QFileInfo):
            suffix = str(fileInfo.completeSuffix().toUtf8())
            #print 'CFileIconProvider',suffix
            if suffix == 'mtz':
              content = fileInfo.baseName().__str__().split(CCP4File.CDataFile.SEPARATOR)[-1]
              #print 'CFileIconProvider content',content
              mimeType=CCP4Modules.MIMETYPESHANDLER().formatFromFileExt(ext=suffix,contentLabel=content)
            else:
              mimeType=CCP4Modules.MIMETYPESHANDLER().formatFromFileExt(ext=suffix)
            #print 'CFileIconProvider.icon',suffix,mimeType
            if mimeType is not None:
              icon = CCP4Modules.MIMETYPESHANDLER().icon(mimeType)
              if icon is not None:
                #print 'CFileIconProvider providing',icon
                return icon
          return QtGui.QFileIconProvider.icon(self,fileInfo)

        '''
	def icon(self,info):
          #print 'IconProvider.icon',info.filePath(),self._filters
          try:
		if info and hasattr(info,'filePath'):
			for k in self._filters:
				for f in self._filters[k]:
					if str(info.filePath()).endswith(f):
						if not self._icon_cache.has_key(k):
							self._icon_cache[k] = QtGui.QIcon(k)
						return self._icon_cache[k]
          except:
            pass
	  return QtGui.QFileIconProvider.icon(self,info)
         '''

class ProxyModel(QtGui.QSortFilterProxyModel):
	def __init__(self,parent=None):
		QtGui.QSortFilterProxyModel.__init__(self,parent)

	def filterAcceptsRow(self, sourceRow, sourceParent):
		if sourceParent.row() == -1 or sourceParent.column():
			return True
		index0 = self.sourceModel().index(sourceRow, 0, sourceParent);
		if self.sourceModel().isDir(index0):
			return True
                
		for f in self.sourceModel().nameFilters():
                    if f == '*.*': return True
                    try:
			if str(self.sourceModel().fileName(index0)).endswith(str(f).lstrip('*')):
				return True
                    except:
                      pass
		return False
              
class CFileDialog0(QtGui.QFileDialog):
  def __init__(self,parent):
    #print 'CFileDialog0.__init__',parent
    QtGui.QFileDialog.__init__(self,parent)
    self.setSizeGripEnabled(0)
    
    pm = ProxyModel()
    self.setProxyModel(pm)
    
    iconProvider = IconProvider()
    iconProvider.setIconsForFilters(CCP4Modules.MIMETYPESHANDLER().getIconsForFileFilters())       
    self.setIconProvider(iconProvider)

    self.cleanupSidebar()

  def cleanupSidebar(self):
    '''Remove invalid directories from left side-bar'''
    # These can cause whole application to stall
    try:
      urlList = self.sidebarUrls()
    except:
      print 'Error cleaning up side bar - no urlList'
      return
    newUrlList = []
    for url in urlList:
      try:
        if os.path.exists(str(url.path())):
          newUrlList.append(url)
        else:
          print 'Removing non-existant directory from sidebar:',str(url.path())
      except:
          try:
            print 'Removing problem directory from side bar:',str(url.path())
          except:
            print 'Removing problem directory from side bar - could not print name'
    if len(newUrlList) != urlList:
      try:
        self.setSidebarUrls(newUrlList)
        print 'Done resetting side bar'
      except:
        print 'Error cleaning up side bar in setSidebarUrls'
  

  def saveButton(self):
    children = self.findChildren(QtGui.QPushButton,"")
    for child in children:
      if child.text() in [self.tr("&Save"),self.tr("&Choose"),self.tr("&Open")]:
        return child
    return None
    
class CDownloader(QtCore.QObject):
    def __init__(self):
       QtCore.QObject.__init__(self)
       self.interrupt_dl= False

    def download(self,url=None):
      #print 'CDownloader.download',url
      if not url:
        self.emit(QtCore.SIGNAL("Error"),'No file to download' )
        #self.emit(QtCore.SIGNAL("ProgressBarRangeChanged"),0,100)
        self.emit(QtCore.SIGNAL("ProgressChanged"),0)
        return
      
      import urllib2,tempfile,sys

      # Beware localFile is tuple of file handle and path name
      self.localFile = tempfile.mkstemp()
      
      try:
        # setup_proxies currently always returns None
        opener = setup_proxies()
        if opener:
      	  dl = opener.open(url)
        else:
      	  dl = urllib2.urlopen(url)
      except:       
        exc_type, exc_value,exc_tb = sys.exc_info()[:3]
        sys.stderr.write(str(exc_type)+'\n')
        sys.stderr.write(str(exc_value)+'\n')
        self.emit(QtCore.SIGNAL("Error"),'Error opening url '+ str(url)+'\nPlease check that you have internet connection.\nand that the file id is valid.\nAlso the data may not exist on the server.')
        return
      try:
      	info = dl.info()
      	contentLength = -1
      	for h in info.headers:
	      if h.find('Content-Length:')>-1:
		      cl = h.split(':')[1].strip()
		      try:
			      contentLength = int(cl)
                              self.emit(QtCore.SIGNAL("ProgressBarRangeChanged"),0,100)
		      except:
                              self.emit(QtCore.SIGNAL("ProgressBarRangeChanged"),0,0)
                              self.emit(QtCore.SIGNAL("ProgressChanged"),0)
			      contentLength = -1
		      break
	readBytes = 0
	buffer = ""
	read = dl.read(100)
	while len(read)>0 and not self.interrupt_dl:
		os.write(self.localFile[0],read)
		buffer = buffer + read
		readBytes = readBytes + len(read)
		pc =  int(float(readBytes)/contentLength * 100)
		if contentLength>-1:
        	        self.emit(QtCore.SIGNAL("ProgressChanged"),pc)
		read = dl.read(100)
      	dl.close()
        if not self.interrupt_dl:
	  fname = self.localFile[1]
          os.close(self.localFile[0])
          self.emit(QtCore.SIGNAL("ProgressBarRangeChanged"),0,100)
          self.emit(QtCore.SIGNAL("ProgressChanged"),0)
          #print "Emitting",finishedSignal,"from",QtCore.QThread.currentThread(); sys.stdout.flush()
          self.emit(QtCore.SIGNAL('Finished'),fname)
          # Just in case
          self.interrupt_dl = False
        self.interrupt_dl = False
      
      except:
        self.interrupt_dl = False
	print "CCP4FileBrowser.CDownloader Error getting",url
        exc_type, exc_value = sys.exc_info()[:2]
        print exc_type
        print exc_value
        os.close(self.localFile[0])
        self.emit(QtCore.SIGNAL("Error"),'Error getting file'+ str(exc_value) )
        #self.emit(QtCore.SIGNAL("ProgressBarRangeChanged"),0,100)
        self.emit(QtCore.SIGNAL("ProgressChanged"),0)
        

def setup_proxies():
  return None
  import urllib2
  from global_definitions import PM

  proxy_uri = PM('download_preferences').get('http_proxy')
  user =  PM('download_preferences').get('http_user')
  passwd =  PM('download_preferences').get('http_password')

  if proxy_uri == "":
    return None

  proxy = urllib2.ProxyHandler({'http': proxy_uri})

  proxy_auth_handler = urllib2.HTTPBasicAuthHandler()

  # No idea if this is correct
  if user != "":
    proxy_auth_handler.add_password(None, uri=proxy_uri, user=user, passwd=passwd)

  opener = urllib2.build_opener(proxy, proxy_auth_handler)
  return opener
