"""
     qtgui/mgPresentation.py: CCP4MG Molecular Graphics Program
     Copyright (C) 2001-2008 University of York, CCLRC
     Copyright (C) 2009-2011 University of York
     Copyright (C) 2012 STFC

     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.
"""
import sys
from PyQt4 import QtGui,QtCore
from global_definitions import *
import MGSimpleDialog,mgWidgets
import os

SNAPSHOT_SIZE = 150


#-------------------------------------------------------------------
def handlePresentation(mode='open_presentation'):
#-------------------------------------------------------------------
    import string
    mode,application= string.split(mode,'_')
    gui_open =  MAINWINDOW().findChild(guiOpenPresentation)
    if not gui_open:
      gui_open = guiOpenPresentation(parent=MAINWINDOW(),mode=mode,application=application)
      self.connect(gui_open,QtCore.SIGNAL('save'),self.openPresentation)
    rv = gui_open.exec_()

    
    if not rv:
      files = gui_open.filedialog.selectedFiles()
      #print 'handlePresentation files',files
      if files:
        openPresentation(str(file[0]),mode=mode,application=application)
    gui_open.close()
        
#-------------------------------------------------------------------
def openPresentation(file='',application='presentation',**kw):
#-------------------------------------------------------------------
    #print "openPresentation",file,application

    # Open the application (from python/ui)
    import presentation
    p = presentation.open_presentation(file)
    #print "openPresentation p,open guis",p,MAINWINDOW().findChildren(mgPresentation.mgPresentation)

    # Is there a gui to this presentation already open?
    if not p: return
      
    for gui in MAINWINDOW().findChildren(mgPresentation.mgPresentation):
      if gui.presentation == p:
        gui.show()
        return

    # Close the selection gui (do this before opening movie gui or mac puts movie
    # beneath main window
    for item in MAINWINDOW().findChildren(guiOpenPresentation):
      item.close()
       
    # Create gui for this presentation
    if application == 'movie':
      import movieGui
      gui = movieGui.movieGui(MAINWINDOW(),presentation=p)
    elif application == 'animation':
      import animationGui
      gui = animationGui.animationGui(MAINWINDOW(),presentation=p)
    else:
      gui = mgPresentation.mgPresentation(MAINWINDOW(),presentation=p)
          
    gui.show()
          

#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------
class guiOpenPresentation( QtGui.QDialog):
#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------


    def __init__(self,parent=None,mode='open',application='presentation'):
      QtGui.QDialog.__init__(parent)
      #self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
      self.setObjectName('dialogPresentation')
      self.setApp(application)
      layout = QtGui.QVBoxLayout()
       

      filedialog = mgWidgets.MGFileDialog(self)
      layout.addWidget(filedialog)
      self.filedialog = filedialog.getFileDialog()

      #print 'guiOpenPresentation',mode,application
      if mode == 'open':
        self.filedialog.setFileMode(self.filedialog.DirectoryOnly)
      else:
        self.filedialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)
      self.filedialog.setDirectory(proj_dir)
      children = self.filedialog.findChildren(QtGui.QPushButton,"")
      for child in children:
          if child.text() == self.tr("&Save"):
            child.setText(self.tr("&Create"))
            self.connect(child, QtCore.SIGNAL('pressed()'),self.saveFile)
    

      filter_list = [self.tr("Presentation directory (*.ccp4mg_presentation)")]
    
      self.filedialog.setNameFilters(filter_list)
          
      self.setLayout(layout)

#-------------------------------------------------------------------
    def setApp(self,application):
#-------------------------------------------------------------------
      self.setWindowTitle("Open "+application+" directory")
      self.application = application


#-------------------------------------------------------------------
    def saveFile(self):
#-------------------------------------------------------------------
      files = self.filedialog.selectedFiles()
      if files:
        self.emit(QtCore.SIGNAL('save'),str(files[0]))


# DO NOT SUBCLASS MGSimpleDialog - causes crash in Movie gui and subsequent runs of mg
# also crash.  Needed to reboot on OSX.   This probably to do with MovieGui
# having a toolbar

#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------
class mgPresentation(MGSimpleDialog.MGSimpleDockDialog):
#class mgPresentation(QtGui.QDialog):
#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------
  selectedColour = ''
  regularColour = ''
  frameMargin = 3
  frameBorder = 2
  frameWidth = 0
    
  def show(self):
    MGSimpleDialog.MGSimpleDockDialog.UnClose(self)
    #QtGui.QDialog.show(self)
    self.highlightSelectedFrames()

#-------------------------------------------------------------------
  def __init__(self,parent,presentation=None):
#-------------------------------------------------------------------
    MGSimpleDialog.MGSimpleDockDialog.__init__(self,parent)
    #QtGui.QDialog.__init__(self,parent)
    
    self.dockActions = True

    if sys.platform == "darwin":
      self.dockActions = True

    if not mgPresentation.frameWidth:
      mgPresentation.frameWidth = SNAPSHOT_SIZE + 2* mgPresentation.frameMargin+ 2* mgPresentation.frameBorder
      mgPresentation.regularColour = self.palette().color(QtGui.QPalette.Normal,QtGui.QPalette.Button)
      mgPresentation.selectedColour = QtCore.Qt.cyan

    self.block_update = 0
    self.presentation = presentation
    self.setWindowTitle(self.presentation.identifier)
    self.frameWidget = None    
    self.picDir = ''
    self.select_range = []
    self.selectedFrames = []
    self.lastRestoredFrame = ''
    self.pasteBuffer = ''
    
    self.frameUiHeight = self.getFrameUiHeight()
    self.draw()
    self.setMinimumWidth(3*mgPresentation.frameWidth)

    if self.presentation: self.loadPresentationFrames()
       
    self.body.layout().addWidget(self.blankFrame)
    self.setBodyWidth()

    # Set window height
    if self.dockActions or sys.platform == 'darwin':
      menu_height = 0
    else:
      menu_height = self.menubar.size().height()
    height =  mgPresentation.frameWidth+menu_height+self.scroll.horizontalScrollBar().size().height() +  self.frameUiHeight
    #self.setMinimumHeight(height)
    #self.setMaximumHeight(height)
    self.body.setMinimumHeight( mgPresentation.frameWidth + self.frameUiHeight)
    self.body.setMaximumHeight( mgPresentation.frameWidth + self.frameUiHeight)
    #self.dockWidget.setFloating(True)

    #self.checkStatusFiles()
    
#-------------------------------------------------------------------
  def checkStatusFiles(self):
#-------------------------------------------------------------------
    rv = self.presentation.check_status_files()
    if rv[0]==0:
      return
    elif rv[0]==1:
      QtGui.QMessageBox.warning(self,'Restoring movie status files ','Can not read status file for snapshot '+str(rv[1]))
      return
    elif rv[0]==2:
      import statusGui
      self.lostFilesGui = statusGui.lostFilesGui(self,lost=rv[1],defn=rv[2])
      rv = self.lostFilesGui.exec_()
      if rv == QtGui.QDialog.Accepted:
        objList,fileDefn = self.lostFilesGui.getFiles()
        rv = self.presentation.edit_status_data_files(objList,fileDefn)

#-------------------------------------------------------------------
  def getFrameUiHeight(self):
#-------------------------------------------------------------------
    ui = self.drawFrameGui(self,'')
    if ui:
      #print "getFrameUiHeight ui",ui,ui.height()
      ui.show()
      height = ui.height()
      ui.close()
    else:
      height = 0
    return height

#-------------------------------------------------------------------
  def drawMenu(self,menu_name):
#-------------------------------------------------------------------
    import guiUtils
    menuWidget = self.findChild(QtGui.QMenu,menu_name)
    if menuWidget:
      menuWidget.clear()
      menudef = self.getGuiDef(menu_name)
      guiUtils.populateMenu(self,menuWidget,self.getGuiDef(menu_name),default_icon='')
    else:
      print "ERROR in mgPresentation.drawMenu drawing",menu_name
      
#-------------------------------------------------------------------
  def draw(self):
#-------------------------------------------------------------------
    # Body in which sub-widgets will be drawn is in scroll area
    import guiUtils
    margin = 0

    if not self.dockActions:
      self.menubar = QtGui.QMenuBar(self)
      for menu_defn in self.getGuiDef('menus'):
        menu = self.menubar.addMenu(menu_defn[1])
        menu.setObjectName(menu_defn[0])
        if menu_defn.count('aboutToShow'):
          self.connect(menu,QtCore.SIGNAL("aboutToShow()"),guiUtils.partial(self.drawMenu,menu_defn[0]))
        else:
          self.drawMenu(menu_defn[0])
    
    self.scroll = QtGui.QScrollArea(self)
    self.scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
    margin = 2
    self.body =  QtGui.QWidget(self)
    body_layout = QtGui.QHBoxLayout()
    body_layout.setSpacing(margin)
    body_layout.setContentsMargins(margin,margin,margin,margin)
    self.body.setLayout(body_layout)   
    
    layout = QtGui.QVBoxLayout()
    layout.setSpacing(margin)
    layout.setContentsMargins(margin,margin,margin,margin)
    if not self.dockActions:
      layout.addWidget(self.menubar)
      layout.addWidget(self.scroll)
    else:
      mainLayout = QtGui.QHBoxLayout()
      mainLayout.setContentsMargins(0,0,0,0)
      mainLayout.addWidget(self.scroll,stretch=2)
      toolLayout = QtGui.QVBoxLayout()
      for menu_defn in self.getGuiDef('menus'):
        menu = QtGui.QMenu(menu_defn[1],self)
        tb = QtGui.QToolButton()
        tb.setPopupMode(QtGui.QToolButton.InstantPopup)
        tb.setText(menu_defn[1])
        menu.setObjectName(menu_defn[0])
        if menu_defn.count('aboutToShow'):
          self.connect(menu,QtCore.SIGNAL("aboutToShow()"),guiUtils.partial(self.drawMenu,menu_defn[0]))
        else:
          self.drawMenu(menu_defn[0])
        tb.setMenu(menu)
        tb.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Maximum)
        toolLayout.addWidget(tb)
      toolLayout.addStretch(2)
      mainLayout.addLayout(toolLayout)
      layout.addLayout(mainLayout)
    #layout.addWidget(self.body)
    self.setLayout(layout)

    self.blankFrame = presentationBlankWidget(self)

#-------------------------------------------------------------------
  def setPictureDirectory(self,dir):
#-------------------------------------------------------------------
    self.picDir = dir


#-------------------------------------------------------------------
  def loadPresentationFrames(self):
#-------------------------------------------------------------------
    if not self.presentation: return
    self.block_update = 1
    #print "loadPresentationFrames snapshot_list",self.presentation.snapshot_list
    for indx in self.presentation.snapshot_list:
      #file = self.presentation.snapshot_file(str(indx),'snapshot')
      #print "loadPresentationFrames",indx,file
      #if os.path.exists(file):
      self.addFrame(id=indx)

    pars = self.presentation.getparams()
    if pars.has_key('snapshot_details'): self.setParams(pars['snapshot_details'])
    self.block_update = 0
    
#-------------------------------------------------------------------
  def newFrame(self,id=''):
#-------------------------------------------------------------------
    # Create new snapshot and insert at current insert position
    if not id:
      try:
        id,backup = self.presentation.add_movie_snapshot()
      except:
        import exceptionHandler
        exceptionHandler.criticalExceptionHandler(self)
        return
    if id:
      indx = self.body.layout().indexOf(self.findChild(presentationBlankWidget,'insert_frame'))
      self.block_update = 1
      self.addFrame(index=indx,id=id)
      self.updateSnapshotList()
      self.block_update = 0
    else:
      QtGui.QMessageBox.critical(self,"Failed to add movie frame","Failed to add movie frame "+str(id))
      
#-------------------------------------------------------------------
  def addFrame(self,index=-1,picture_file='',id=''):
#-------------------------------------------------------------------
    # Create the options frame that goes below the picture

    frame = presentationFrameWidget(parent=self,id=id,picture_file=picture_file)
    if index>=0:
      self.body.layout().insertWidget(index,frame)
    else:
      self.body.layout().addWidget(frame)
    self.setBodyWidth()
    self.emit(QtCore.SIGNAL('frameAdded'))

#-------------------------------------------------------------------
  def paste(self,target):
#-------------------------------------------------------------------
    if not self.pasteBuffer: return
    if not os.path.exists(self.presentation.snapshot_file(self.pasteBuffer,'snapshot')) or not os.path.exists(self.presentation.snapshot_file(self.pasteBuffer,'status')):
      return

    #print "mgPresentation.paste",self.pasteBuffer,self.presentation.snapshot_list
    rv = self.presentation.makeCopy(self.pasteBuffer)
    if rv[0]:
      MGGUI().WarningMessage(rv[1])
      return

    #print "mgPresentation.paste",rv
    self.newFrame(id=rv[1])
      
#-------------------------------------------------------------------
  def setBodyWidth(self):
#-------------------------------------------------------------------
    nFrames = self.body.layout().count()
    #print "setBodyWidth",nFrames
    self.body.setMinimumWidth( mgPresentation.frameWidth * nFrames )
    self.body.setMaximumWidth( mgPresentation.frameWidth * nFrames )
    self.body.updateGeometry()
    self.scroll.setWidget(self.body)


#-------------------------------------------------------------------
  def setPasteBuffer(self,id):
#-------------------------------------------------------------------
    self.pasteBuffer = str(id)

#-------------------------------------------------------------------
  def deleteFrame(self,id):
#-------------------------------------------------------------------
    id = str(id)
    #print "mgPresentation.deleteFrame id",id
    self.setPasteBuffer(id)
    widget = self.findChild(presentationFrameWidget,id)
    self.body.layout().removeWidget(widget)
    widget.close()
    self.setBodyWidth()
    self.updateSnapshotList()
    self.emit(QtCore.SIGNAL('frameDeleted'))

#-------------------------------------------------------------------
  def deleteAllFrames(self):
#-------------------------------------------------------------------
    self.setPasteBuffer(0)
    self.presentation.apply('delete_all')
    widget_list = self.findChildren(presentationFrameWidget)
    for widget in widget_list:
      self.body.layout().removeWidget(widget)
      widget.close()
    self.setBodyWidth()
    self.updateSnapshotList()
    self.emit(QtCore.SIGNAL('frameDeleted'))

#-------------------------------------------------------------------
  def numberOfFrames(self,selected=0):
#-------------------------------------------------------------------
    frames = self.body.findChildren(presentationFrameWidget)
    if selected:
      # Return the number of currently selected frames
      ns = 0
      for f in frames:
        if f.selected: ns = ns + 1
      if ns:
        return ns
      else:
        return len(frames)
    else:
      return len(frames)

    
#-------------------------------------------------------------------
  def getGuiDef(self,name='',pickevent=None):
#-------------------------------------------------------------------
      if name == 'menus':
        return [['Action','&Action'],['Edit','&Edit'],['Help','&Help']]
      elif name == 'Action':
        return ['next','previous','close']
      elif name == 'Help':
        return ['help']
      elif name == 'Edit':
        return ['package']
     
#-------------------------------------------------------------------
  def getActionDef(self,name,**info):
#-------------------------------------------------------------------
    #print 'mgpresentation getActionDef',name
    import guiUtils
    if name == 'close':
      return dict ( 
        text = self.tr('Close presentation'),
        tip = self.tr('Close this presentation saving current status'),
        slot = self.Close  )
    
    if name == 'next':
      return dict ( 
        text = self.tr('&Next'),
        tip = self.tr('Restore the status from the next frame'),
        slot = self.restoreStatus )
    
    if name == 'previous':
      return dict ( 
        text = self.tr('&Previous'),
        tip = self.tr('Restore the status from the previous frame'),
        slot = guiUtils.partial(self.restoreStatus,-1)  )

    
    if name == 'help':
      return dict ( 
        text = self.tr('&Help'),
        tip = self.tr('Help on CCP4mg Presentations'),
        slot = self.help  )

    if name == 'package':
      return dict ( 
        text = self.tr('Package presentation'),
        tip = self.tr('Make compressed file of presentation and data files'),
        slot = self.packagePresentation )
 

    return {}

  def help(self):
    
    HELPBROWSER().loadMgHelp('presentation.html')

#-------------------------------------------------------------------
  def addMenu(self,menu):
#-------------------------------------------------------------------
    self.menubar.addMenu(menu)

#----------------------------------------------------------------
  def setInsertPosition(self,position=-1,id='',increment=0):
#----------------------------------------------------------------
    '''
    Reset position of the blank/insert frame
    Input is either new position or the id a frame that
    the blank frame should be placed before or after (increment = 0 or 1)
    '''
    #print "mgPresentation.setInsertPosition",id,increment
    if position<0:
      # Assume position is relative to a frame called id
      #try:
      position = self.body.layout().indexOf(self.findChild(presentationFrameWidget,str(id))) + increment
      #except:
      #  pass
    if position>=0:
      current = self.body.layout().indexOf(self.blankFrame)
      #print "mgPresentation.setInsertPosition",current,position
      if current == position:
        return
      if current < position:
        position = position-1

      self.body.layout().removeWidget(self.blankFrame)
      self.body.layout().insertWidget(position,self.blankFrame)


#-------------------------------------------------------------------
  def getParams(self,keyList=[],index=''):
#-------------------------------------------------------------------
    import mgWidgets
    params = {}
    if index:
      frameList = [self.findChild(presentationFrameWidget,index)]
    else:
      frameList = self.body.findChildren(presentationFrameWidget)
    #print "mgPresentation.getParams frameList",frameList
    for frame in frameList:
      id = str(frame.objectName())
      params[id] = {}
      for key in keyList:
        widget = frame.findChild(QtGui.QWidget,key)
        value = ''
        if widget:
          if isinstance(widget,QtGui.QComboBox):
            value = str(widget.itemData(widget.currentIndex()).toString())
            if not value: value = str(widget.currentText())
          elif isinstance(widget,QtGui.QLabel):
            value = str(widget.text())
          elif isinstance(widget,QtGui.QLineEdit):
            value = str(widget.text())
          elif isinstance(widget,QtGui.QAbstractButton):
            value = int(widget.isChecked())
          elif isinstance(widget,mgWidgets.mgSelectionCombo):
            value = str(widget.text())
          elif isinstance(widget,mgWidgets.mgColourCombo):
            value = str(widget.get_colour())
          elif isinstance(widget,mgWidgets.mgAtomPicker):
            value = str(widget.selection())
          elif isinstance(widget,QtGui.QDoubleSpinBox):
            value = float(widget.value())
          elif isinstance(widget,QtGui.QSpinBox):
            value = int(widget.value())
          elif isinstance(widget,mgWidgets.mgSlider):
            value = float(widget.value())
              
          if value: params[id][key]= value

    #print "mgPresentation.getParams",params
    return params

      
#----------------------------------------------------------------
  def setParams(self,params={},**kw):
#----------------------------------------------------------------
    import mgWidgets
    # Beware - do not assume that all items in params are
    # in our widget
    params.update(kw)
    idList = params.keys()

    #print "mgPresentation.setParams",params,idList

    blank_incr = 0
    for id in idList:
      frame = self.body.findChild(presentationFrameWidget,id)
      if frame:
        for key,value in params[id].items():
          widget = frame.findChild(QtGui.QWidget,key)
          if widget:
            if isinstance(widget,QtGui.QComboBox):
              ic = widget.findText(QtCore.QString(value))
              if ic < 0:
                ic = widget.findData(QtCore.QVariant(value))
              if ic>=0: widget.setCurrentIndex(ic)
            elif isinstance(widget,QtGui.QLineEdit):
              widget.setText(str(value))
            elif isinstance(widget,QtGui.QLabel):
              widget.setText(str(value))
            elif isinstance(widget,QtGui.QAbstractButton):
              widget.setChecked(value)
            elif isinstance(widget,mgWidgets.mgSelectionCombo):
              widget.setText(params[key][jj])
            elif isinstance(widget,mgWidgets.mgColourCombo):
              widget.set_colour(value)
            elif isinstance(widget,mgWidgets.mgAtomPicker):
              widget.setSelection(atomName=value)
            elif isinstance(widget,QtGui.QDoubleSpinBox):
              widget.setValue(float(value))
            elif isinstance(widget,QtGui.QSpinBox):
              widget.setValue(int(value))
            elif isinstance(widget,mgWidgets.mgSlider):
              widget.setValue(float(value))



#-------------------------------------------------------------------
  def snapshotList(self):
#-------------------------------------------------------------------
    snapshot_list=[]
    for indx in range(0,self.body.layout().count()):
      id = str(self.body.layout().itemAt(indx).widget().objectName())
      if id != 'insert_frame':  snapshot_list.append(id)
    #print "mgPresentation.updateSnapshotList snapshot_list",snapshot_list
    return snapshot_list
  
#-------------------------------------------------------------------
  def updateSnapshotList(self):
#-------------------------------------------------------------------   
    self.presentation.set_snapshot_list(self.snapshotList())
    self.presentation.pickle_movie()

#-------------------------------------------------------------------
  def drawFrameGui(self,frame=None,id=''):
#-------------------------------------------------------------------
    # This method needs to be reimplemented in sub-class to
    # draw gui beneath frame pictures
    #print "mgPresentation.drawFrameGui",id
    return None

#-------------------------------------------------------------------
  def updateFrameGui(self,frame=None,id='',**kw):
#-------------------------------------------------------------------
    # This method needs to be reimplemented in sub-class to
    # do any update on gui beneath frame pictures
    #print "mgPresentation.updateFrameGui",id
    pass
    
#-----------------------------------------------------------------------
  def selectFrames ( self, action ='', id = '',xx='' ):
#-----------------------------------------------------------------------

    #print "select action,id",action,id

    if action == 'shift-press':
      self.select_range = [id,id]
      
    if action == 'shift-release':
      # xx is shift release position releative to body of mgPresentation widget
      # from this figure out which frame the cursor was in
      indx = xx/mgPresentation.frameWidth
      id1 = str(self.body.layout().itemAt(indx).widget().objectName())
      #print "mgpresentation.selectFrames shift-release indx,id1",indx,id1
      if id1 == 'insert_frame': return
      
      self.select_range = [id,id1]
        
    elif action == 'single-click':
      if len(self.select_range) == 2 and self.select_range[0] == id and  self.select_range[1] == id:
        self.select_range = []
        self.selectedFrames =[]
      else:
        self.select_range = [id,id]
   
    elif action == 'undo':
      self.select_range = []
      self.selectedFrames =[]
      
    # Ensure the select_range is OK
    if len(self.select_range) > 1:
      snapshot_list = self.snapshotList()
      if not snapshot_list.count(self.select_range[0]) or not snapshot_list.count(self.select_range[1]):
        self.select_range = []
      else:
        l1 = snapshot_list.index(self.select_range[0])
        l2 = snapshot_list.index(self.select_range[1])
        if l1>l2:
          self.select_range=[self.select_range[1],self.select_range[0]]
          self.selectedFrames = snapshot_list[l2:l1+1]
        else:
          self.selectedFrames = snapshot_list[l1:l2+1]
      self.presentation.apply(select=self.select_range)
    else:
      self.presentation.apply(action='undo_selection')
      
    self.highlightSelectedFrames()
    
#-----------------------------------------------------------------------
  def highlightSelectedFrames(self):
#-----------------------------------------------------------------------
    for indx in range(0,self.body.layout().count()):
      widget = self.body.layout().itemAt(indx).widget()
      id = str(widget.objectName())
      if id == 'insert_frame':
        pass
      elif self.selectedFrames.count(id):
        sheet = 'presentationFrameWidget { border: 4px solid green;}'
	widget.setStyleSheet(sheet)
        if widget.ui:
           sheet = 'presentationFrameWidget { border: 4px solid red;}'
	   widget.ui.setStyleSheet(sheet)
      else:
        sheet = 'presentationFrameWidget { border: 4px solid red;}'
	widget.setStyleSheet(sheet)

#-----------------------------------------------------------------------
  def restoreStatus(self,increment=1,action='restore',id=''):
#-----------------------------------------------------------------------
    if not id:
      #Get the next/previous frame
      snapshot_list = self.snapshotList()
      if not snapshot_list: return
      if not self.lastRestoredFrame or not snapshot_list.count(self.lastRestoredFrame):
        ii = 0
      else:
        ii = snapshot_list.index(self.lastRestoredFrame) + increment
        if ii>len(snapshot_list)-1:
          ii = 0
        elif ii<0:
          ii = len(snapshot_list)-1
      id = snapshot_list[ii]

    # Don't prevent restoring the same frame - user may have changed status
    # by some other means
    #elif id == self.lastRestoredFrame:
    #  return

    #print 'mgPresentation.restoreStatus',action,id
    rv = self.presentation.restore_status(action=action,id=id)
    if rv[0]:
      MGGUI().WarningMessage(rv[1])
    else:
      self.lastRestoredFrame = id
      import rebuild
      rebuild.UpdateDisplay()
      MAINWINDOW().updateGLWindows()      
      DISPLAYTABLE().update()

#-----------------------------------------------------------------------
  def wheelEvent(self,event):
#-----------------------------------------------------------------------
    delta = event.delta()
    bar = self.scroll.horizontalScrollBar()
    #print "mgpresentation.wheelEvent",delta,bar,bar.value()
    if delta<0:
      bar.setValue(bar.value()+20)
    else:
      bar.setValue(bar.value()-20)
    event.accept()

#-----------------------------------------------------------------------
  def loadSnapshot(self,target):
#-----------------------------------------------------------------------
    pass

#-----------------------------------------------------------------------
  def packagePresentation(self):
#-----------------------------------------------------------------------
    print 'packagePresentation'
    rv = self.presentation.do_backup_data_files(compress=1)
    if rv[0]:
      QtGui.QMessageBox.warning(self,'Package presentation ',rv[1])
    else:
      QtGui.QMessageBox.information(self,'Package presentation ',rv[1])
     
  
#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------
class presentationFrameWidget(QtGui.QFrame):
#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------

#-------------------------------------------------------------------
  def __init__(self,parent,id='',picture_file=''):
#-------------------------------------------------------------------
    QtGui.QFrame.__init__(self,parent)
    self.presentationGui = parent
    self.setObjectName(id)
    #self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    self.selected = 0
    self.setFrameStyle(QtGui.QFrame.Box)
    self.setLineWidth(mgPresentation.frameBorder)
    layout = QtGui.QVBoxLayout()
    margin = mgPresentation.frameMargin
    layout.setContentsMargins(margin,margin,margin,margin)
    layout.setSpacing(0)

    self.picFrame = presentationPictureWidget(str(self.objectName()),self)
    layout.addWidget(self.picFrame)
    self.loadImage()

    #self.label = QtGui.QLabel(str(self.objectName()),self.picFrame)


    # Add the gui beneath each frame picture
    #
    self.ui = self.presentationGui.drawFrameGui(frame=self,id=id)
    if self.ui: layout.addWidget(self.ui)
    self.setMaximumWidth(mgPresentation.frameWidth)
    self.setMinimumWidth(mgPresentation.frameWidth)

    layout.addStretch()
    self.setLayout(layout)
    self.show()
    # 
    if self.ui: self.presentationGui.updateFrameGui(id=id)


#-------------------------------------------------------------------
  def sizeHint(self):
#-------------------------------------------------------------------
    h = mgPresentation.frameWidth
    if self.ui: h = h + self.ui.size().height()
    #print "presentationFrameWidget.sizeHint",h
    return QtCore.QSize(mgPresentation.frameWidth,h)

  
#-------------------------------------------------------------------
  def loadImage(self,picture_file=''):
#-------------------------------------------------------------------
    if not picture_file:
      picfile = self.presentationGui.presentation.snapshot_file(str(self.objectName()),'snapshot')
    #elif self.presentationGui.picDir:
    #  picfile = os.path.join(self.presentationGui.picDir,picture_file)
    #  if not os.path.exists(picfile): picfile = picture_file
    else:
      picfile = picture_file
    #print "presentationFrameWidget.loadImage picfile",picfile,os.path.exists(picfile)
    if os.path.exists(picfile):
      pixmap = QtGui.QPixmap(picfile)
      self.picFrame.setPixmap(pixmap)
    #layout.addWidget(self.picFrame)


#-------------------------------------------------------------------
  def contextMenuEvent(self,event):
#-------------------------------------------------------------------
    #print "presentationFrameWidget.contextMenuEvent"
    if not hasattr(self,'context_menu'):     
      self.context_menu=QtGui.QMenu(self)
      import guiUtils
      guiUtils.populateMenu(self,self.context_menu,[[self.tr('Restore..'),'restore','restore_display','restore_view'],'replace','cut','copy','sep',[self.tr('Set insert..'),'insert_before','insert_after']],default_icon='')
    self.context_menu.popup(self.mapToGlobal(QtCore.QPoint(event.pos())))
    self.context_menu.exec_()
    event.accept()

#-------------------------------------------------------------------
  def getActionDef(self,name,**info):
#-------------------------------------------------------------------
    import guiUtils
    if name == 'restore':
      return dict ( 
        text = self.tr('Display and view'),
        tip = self.tr('Restore the display and view shown in this frame'),
        slot = guiUtils.partial(self.handleAction,name))
    if name == 'restore_display':
      return dict ( 
        text = self.tr('Display'),
        tip = self.tr('Restore the display shown in this frame'),
        slot = guiUtils.partial(self.handleAction,name))
    if name == 'restore_view':
      return dict ( 
        text = self.tr('View'),
        tip = self.tr('Restore the view shown in this frame'),
        slot = guiUtils.partial(self.handleAction,name))
    if name == 'replace':
      return dict ( 
        text = self.tr('Replace'),
        tip = self.tr('Replace this frame with the current status'),
        slot = guiUtils.partial(self.handleAction,name))
    if name == 'insert_before':
      return dict ( 
        text = self.tr('Before this frame'),
        tip = self.tr('Set the insert frame before this frame'),
        slot = guiUtils.partial(self.handleAction,name))
    if name == 'insert_after':
      return dict ( 
        text = self.tr('After this frame'),
        tip = self.tr('Set the insert frame after this frame'),
        slot = guiUtils.partial(self.handleAction,name))
    if name == 'cut':
      return dict ( 
        text = self.tr('Cut'),
        tip = self.tr('Remove this frame'),
        slot = guiUtils.partial(self.presentationGui.deleteFrame,self.objectName()))
    if name == 'copy':
      return dict ( 
        text = self.tr('Copy'),
        tip = self.tr('Copy this frame'),
        slot = guiUtils.partial(self.presentationGui.setPasteBuffer,self.objectName()))



#-------------------------------------------------------------------
  def handleAction(self,action=''):
#-------------------------------------------------------------------
    #print "presentationFrameWidget.handleAction",action
    if action == 'insert_before':
      self.presentationGui.setInsertPosition(id=self.objectName(),increment=0)
    elif action == 'insert_after':
      self.presentationGui.setInsertPosition(id=self.objectName(),increment=1)
    elif action[0:4]=='rest':
      self.presentationGui.restoreStatus(action=action,id=str(self.objectName()))
    elif action == 'replace':
      self.presentationGui.presentation.add_movie_snapshot(index=str(self.objectName()),save_changes='replaced')
      self.loadImage()
      
#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------
class presentationBlankWidget(QtGui.QFrame):
#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------

#-------------------------------------------------------------------
  def __init__(self,parent):
#-------------------------------------------------------------------
    QtGui.QFrame.__init__(self,parent)
    self.presentationGui = parent
    self.setFrameStyle(QtGui.QFrame.Box)
    self.setObjectName('insert_frame')
    layout = QtGui.QVBoxLayout()
    margin = mgPresentation.frameMargin
    layout.setContentsMargins(margin,margin,margin,margin)
    layout.setSpacing(10)
    label =  QtGui.QLabel(self.tr('Save snapshot here'),self)
    layout.addStretch()
    layout.addWidget(label)
    layout.addStretch()
    
    
    self.setLayout(layout)
    self.setMaximumWidth(mgPresentation.frameWidth)
    self.setMinimumWidth(mgPresentation.frameWidth)
    self.setMaximumHeight(mgPresentation.frameWidth+self.presentationGui.frameUiHeight)
    self.setMinimumHeight(mgPresentation.frameWidth+self.presentationGui.frameUiHeight)

    self.show()

    
#-------------------------------------------------------------------
  def contextMenuEvent(self,event):
#-------------------------------------------------------------------
    #print "presentationBlankWidget.contextMenuEvent"
    if not hasattr(self,'context_menu'):  self.context_menu=QtGui.QMenu(self)

    self.context_menu.clear()
    import guiUtils
    guiUtils.populateMenu(self,self.context_menu,['save_status','paste','load_snapshot'],default_icon='')
    self.context_menu.popup(self.mapToGlobal(QtCore.QPoint(event.pos())))
    self.context_menu.exec_()
    event.accept()

     
#-------------------------------------------------------------------
  def getActionDef(self,name,**info):
#-------------------------------------------------------------------
    import guiUtils
    if name == 'save_status':
      return dict ( 
        text = self.tr('Save current view/display'),
        tip = self.tr('Save snapshot of current view/display here'),
        slot = self.presentationGui.newFrame
        )
    if name == 'paste':
      def e(): return (self.presentationGui.pasteBuffer!='')
      return dict ( 
        text = self.tr('Paste'),
        tip = self.tr('Paste the saved snapshot'),
        slot = guiUtils.partial(self.presentationGui.paste,-1),
        enabled = e
        )
    if name == 'load_snapshot':
      return dict ( 
        text = self.tr('Load snapshot file'),
        tip = self.tr('Load from '),
        slot = guiUtils.partial(self.presentationGui.loadSnapshot,-1),
        enabled = 0
        )
   
#-------------------------------------------------------------------
  def mouseDoubleClickEvent(self, event):
#-------------------------------------------------------------------
    self.presentationGui.newFrame()
    event.accept()
    

      
#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------
class presentationPictureWidget(QtGui.QLabel):
#-------------------------------------------------------------------
#-------------------------------------------------------------------
#-------------------------------------------------------------------

#-------------------------------------------------------------------
  def __init__(self,text,parent):
#-------------------------------------------------------------------
    QtGui.QLabel.__init__(self,parent)
    self.setMargin(mgPresentation.frameBorder)
    self.label = QtGui.QLabel(text,self)
  
#-------------------------------------------------------------------
  def mouseDoubleClickEvent(self, event):
#-------------------------------------------------------------------
    self.parent().handleAction('restore')
    event.accept()
    
#-------------------------------------------------------------------
  def mousePressEvent(self, event):
#-------------------------------------------------------------------
    #print "presentationPictureWidget.mousePressEvent"
    # Accept shift-left-mouse
    if event.buttons()&QtCore.Qt.LeftButton and event.modifiers()&QtCore.Qt.ShiftModifier:
      self.parent().presentationGui.selectFrames('shift-press',str(self.parent().objectName()))
      event.accept()
    else:
      event.ignore()

#-------------------------------------------------------------------
  def mouseReleaseEvent(self, event):
#-------------------------------------------------------------------
    #print "presentationPictureWidget.mouseReleaseEvent shift", event.button(),event.modifiers()&QtCore.Qt.ShiftModifier
    
    if event.button()==QtCore.Qt.LeftButton:
      if event.modifiers()&QtCore.Qt.ShiftModifier:
        # Find position of cursor wrt the mgPresentation body widget
        # From the selectFrames method can figure which frame the mouse
        # release event occured in 
        pos = self.parent().mapToParent(self.mapToParent(event.pos()))
        #print "pos",pos.x(),pos.y()
        self.parent().presentationGui.selectFrames('shift-release',id=str(self.parent().objectName()),xx=pos.x())
        event.accept()
      else:
        self.parent().presentationGui.selectFrames('single-click',str(self.parent().objectName()))
        event.accept()
    else:
      event.ignore()

def test():
  app =  QtGui.QApplication(sys.argv)
  main = QtGui.QMainWindow()
  mv = presentationDialog(main)
  mv.setPictureDirectory('/home/lizp/ccp4mg_tutorial/tt.ccp4mg_presentation')
  mv.addFrame(-1,'snapshot_00001.ppm')
  mv.addFrame(-1,'snapshot_00002.ppm')
  mv.show()

  
  app.exec_()


