"""
     qtgui/ColourBrowser.py: CCP4MG Molecular Graphics Program
     Copyright (C) 2001-2008 University of York, CCLRC
     Copyright (C) 2009-2010 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.
"""
"""
*Prototype* Colour Browser
"""
from PyQt4 import QtCore, QtGui, QtOpenGL
import MGSimpleDialog,guiUtils
import os
import sys
from MGSimpleWidgets import InteractiveLabel

default_colours = [
               ['black',0,0,0],
               ['red',255,0,0],
               ['green',0,255,0],
               ['blue',0,0,255],
               ['yellow',255,255,0],
               ['magenta',255,0,255],
               ['cyan',0,255,255],
               ['white',255,255,255]]


class colourlist:
  def __init__(self,items=[]):
    self.items = []
    for item in items:
      self.add_colour(item[0],item[1:4])

  def set_colour(self,index=-1,name='',rgb=[]):
    if index>=0 and index<len(self.items):
      self.items[index] = [name,rgb[0],rgb[1],rgb[2]]
        
  def add_colour(self,name='',rgb=[]):
    ii = self.index(name)
    if ii<0:
      self.items.append([name,rgb[0],rgb[1],rgb[2]])
    else:
      for jj in range(0,3):
        self.items[ii][jj+1] = rgb[jj]
        
  def has_colour(self,col):
    for item in self.items:
      if item[0] == col: return 1
    return 0

  def has_rgb(self,r,g,b):
    for item in self.items:
      if item[1] == r and item[2] == g and item[3] == b:
        return 1
    return 0

  def get_name_for_rgb(self,r,g,b):
    for item in self.items:
      if item[1] == r and item[2] == g and item[3] == b:
        return item[0]
    return ''

  def index(self,col):
    ii = -1
    for item in self.items:
      ii = ii + 1
      if item[0] == col: return ii
    return -1


  def len(self):
    return len(self.items)
    '''
    count = 0
    for item in self.items:
      if item[0] != None: count = count + 1
    return count
    '''

  def get_rgb(self,ii=-1,name=''):
    if name:
      ii = self.index(name)
    if ii >= 0  and ii < len(self.items):
      return self.items[ii][1:4]
    else:
      return [0,0,0]
    
  def get_colour(self,ii):  
    if ii < len(self.items):
      return self.items[ii][0]
    else:
      return ['white']

  def rename(self,old,new):
    ii = self.index(old)
    if ii>=0:
      self.items[ii][0] = new

  def delete(self,index=-1,name=''):
    if index<0: index = self.index(name)
    if index>=0:
      self.items.pop(index)
      return 0
    else:
      return 1
    #if ii>=0: self.items[ii][0] = None

class ClickLabel(QtGui.QLabel):
	def __init__(self,parent=None,editable=0,dummy=0):
		QtGui.QLabel.__init__(self,parent)

	def mousePressEvent(self, event):
		self.emit(QtCore.SIGNAL("MousePressed"),(event,self))

class ColourLabel(QtGui.QLabel):
    def __init__(self,parent=None,editable=0,dummy=0):
        QtGui.QLabel.__init__(self,parent)
        self.colour = QtGui.QColor()
        self.editable = editable
        if not dummy:
          self.setFrameStyle(QtGui.QFrame.Panel)
          self.setFrameShadow(QtGui.QFrame.Raised)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setLineWidth(2)
        self.setMaximumHeight(15)

    def mouseDoubleClickEvent(self, event):
        self.emit(QtCore.SIGNAL("MouseDoubleClick"),(event,self))

    def mousePressEvent(self, event):
      if event.button() == QtCore.Qt.LeftButton:
        self.emit(QtCore.SIGNAL("LeftMousePressed"),self)
      elif event.button() == QtCore.Qt.RightButton and self.editable:
        self.menu = QtGui.QMenu(self.tr('Context'),self)
        remove = QtGui.QAction("Delete colour",self)
        self.menu.addAction(remove)
        edit = QtGui.QAction("Change colour",self)
        self.menu.addAction(edit)
        self.menu.popup(event.globalPos())
        self.connect(remove,QtCore.SIGNAL('triggered()'),guiUtils.partial(self.handleMenu,'delete'))
        self.connect(edit,QtCore.SIGNAL('triggered()'),guiUtils.partial(self.handleMenu,'edit'))
      else:
        self.emit(QtCore.SIGNAL("MousePressed"),self)

    def handleMenu(self,mode):
      self.emit(QtCore.SIGNAL(mode),self)
          
    def mouseMoveEvent(self, event):
        self.emit(QtCore.SIGNAL("MouseMoved"),(event,self))

    def sizeHint(self):
	return QtCore.QSize(20,10)

    def getColour(self):
        return self.colour
      
    def setColour(self, colour):
        self.colour = colour
        self.setAutoFillBackground(True)
	palette = QtGui.QPalette(colour)
        self.setPalette(palette)
	"""
        pixmap = QtGui.QPixmap(20,10)
        pixmap.fill(colour)
        self.setPixmap(pixmap)
	"""

class HSVRGBWidget(QtGui.QWidget):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        hsv_rgb_layout = QtGui.QGridLayout()
        hue = QtGui.QLabel()
        hue.setText("Hue:")
        sat = QtGui.QLabel()
        sat.setText("Sat:")
        val = QtGui.QLabel()
        val.setText("Val:")
        red = QtGui.QLabel()
        red.setText("Red:")
        green = QtGui.QLabel()
        green.setText("Green:")
        blue = QtGui.QLabel()
        blue.setText("Blue:")
        hsv_rgb_layout.addWidget(hue,0,0,QtCore.Qt.AlignRight)
        hsv_rgb_layout.addWidget(sat,1,0,QtCore.Qt.AlignRight)
        hsv_rgb_layout.addWidget(val,2,0,QtCore.Qt.AlignRight)
        hsv_rgb_layout.addWidget(red,0,2,QtCore.Qt.AlignRight)
        hsv_rgb_layout.addWidget(green,1,2,QtCore.Qt.AlignRight)
        hsv_rgb_layout.addWidget(blue,2,2,QtCore.Qt.AlignRight)
        self.hue_spin = QtGui.QSpinBox()
        self.hue_spin.setMaximum(359)
        hsv_rgb_layout.addWidget(self.hue_spin,0,1)
        self.sat_spin = QtGui.QSpinBox()
        self.sat_spin.setMaximum(255)
        hsv_rgb_layout.addWidget(self.sat_spin,1,1)
        self.val_spin = QtGui.QSpinBox()
        self.val_spin.setMaximum(255)
        hsv_rgb_layout.addWidget(self.val_spin,2,1)
        self.red_spin = QtGui.QSpinBox()
        self.red_spin.setMaximum(255)
        hsv_rgb_layout.addWidget(self.red_spin,0,3)
        self.green_spin = QtGui.QSpinBox()
        self.green_spin.setMaximum(255)
        hsv_rgb_layout.addWidget(self.green_spin,1,3)
        self.blue_spin = QtGui.QSpinBox()
        self.blue_spin.setMaximum(255)
        hsv_rgb_layout.addWidget(self.blue_spin,2,3)
        self.setLayout(hsv_rgb_layout)

        #self.doSlots()
        self.connect(self.hue_spin,QtCore.SIGNAL("valueChanged(int)"),self.HSVChanged)
        self.connect(self.sat_spin,QtCore.SIGNAL("valueChanged(int)"),self.HSVChanged)
        self.connect(self.val_spin,QtCore.SIGNAL("valueChanged(int)"),self.HSVChanged)
        self.connect(self.red_spin,QtCore.SIGNAL("valueChanged(int)"),self.RGBChanged)
        self.connect(self.green_spin,QtCore.SIGNAL("valueChanged(int)"),self.RGBChanged)
        self.connect(self.blue_spin,QtCore.SIGNAL("valueChanged(int)"),self.RGBChanged)

    def setColour(self,color):
        self.undoSlots()
	try:
        	self.red_spin.setValue(color.red())
        	self.green_spin.setValue(color.green())
        	self.blue_spin.setValue(color.blue())
        	self.hue_spin.setValue(color.hue())
        	self.sat_spin.setValue(color.saturation())
        	self.val_spin.setValue(color.value())
	except:
		pass
        self.doSlots()
        
    def doSlots(self):
        self.hue_spin.blockSignals(False)
        self.sat_spin.blockSignals(False)
        self.val_spin.blockSignals(False)
        self.red_spin.blockSignals(False)
        self.green_spin.blockSignals(False)
        self.blue_spin.blockSignals(False)

    def undoSlots(self):
        self.hue_spin.blockSignals(True)
        self.sat_spin.blockSignals(True)
        self.val_spin.blockSignals(True)
        self.red_spin.blockSignals(True)
        self.green_spin.blockSignals(True)
        self.blue_spin.blockSignals(True)

    def HSVChanged(self,value):
        h,s,v = self.hue_spin.value(),self.sat_spin.value(),self.val_spin.value()
        color = QtGui.QColor.fromHsv(h,s,v)
        self.undoSlots()
	try:
        	self.red_spin.setValue(color.red())
        	self.green_spin.setValue(color.green())
        	self.blue_spin.setValue(color.blue())
	except:
		pass
        self.doSlots()
        self.emit(QtCore.SIGNAL("colourChanged"),color)

    def RGBChanged(self,value):
        r,g,b = self.red_spin.value(),self.green_spin.value(),self.blue_spin.value()
        color = QtGui.QColor(r,g,b)
        self.undoSlots()
	try:
        	hue = color.hue()
        	if hue == -1: hue = 255
        	self.hue_spin.setValue(hue)
        	self.sat_spin.setValue(color.saturation())
        	self.val_spin.setValue(color.value())
	except:
		pass
        self.doSlots()
        self.emit(QtCore.SIGNAL("colourChanged"),color)

class HSVPictureWidget(QtGui.QWidget):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        layout_top_right = QtGui.QHBoxLayout()
        self.hsv_pixmap_cursor_x = 0
        self.hsv_pixmap_cursor_y = 0
        self.colour_widget = InteractiveLabel()
        self.connect(self.colour_widget,QtCore.SIGNAL("MouseMoved"),self.HSVWidgetMoved)
        self.connect(self.colour_widget,QtCore.SIGNAL("MousePressed"),self.HSVWidgetMoved)
        self.colour_widget.setAlignment(QtCore.Qt.AlignTop)
        import os
        my_dir = os.path.dirname(__file__)
        self.hsv_pixmap = QtGui.QPixmap(os.path.join(my_dir,"hsv.png"))
        self.hsv_pixmap = self.hsv_pixmap.scaledToHeight(200)
        self.paint_pixmap = QtGui.QPixmap(self.hsv_pixmap.width(),self.hsv_pixmap.height())
        self.hsv_painter = QtGui.QPainter()
        self.rePaintHSVWidget(255)
        self.value_slider = QtGui.QSlider()
        self.value_slider.setMaximum(255)
        self.value_slider.setValue(255)
        self.connect(self.value_slider,QtCore.SIGNAL("valueChanged(int)"),self.sliderChanged)
        layout_top_right.addWidget(self.colour_widget,QtCore.Qt.AlignTop)
        layout_top_right.addWidget(self.value_slider)
        self.setLayout(layout_top_right)

    def setColour(self,color):
        self.hsv_pixmap_cursor_y = ((255-color.saturation())*self.hsv_pixmap.height()/256.)
        sat = 255-int(self.hsv_pixmap_cursor_y*256./self.hsv_pixmap.height())
        value = color.value()
        self.hsv_pixmap_cursor_x = color.hue()*self.hsv_pixmap.width()/360.
        self.value_slider.setValue(value)
        self.rePaintHSVWidget(value)

    def HSVWidgetMoved(self,event=None):
        if event: 
          x = min(event.pos().x(), self.hsv_pixmap.width())
          x = max(x,0)
          y = min(event.pos().y(), self.hsv_pixmap.height())
          y = max(y,0)
          self.hsv_pixmap_cursor_x = x
          self.hsv_pixmap_cursor_y = y
        self.rePaintHSVWidget(self.value_slider.value())

        hue = min(self.hsv_pixmap_cursor_x*360./self.hsv_pixmap.width(),359)
        sat = 255-(self.hsv_pixmap_cursor_y*255./self.hsv_pixmap.height())
        val = self.value_slider.value()
        self.emit(QtCore.SIGNAL("colourChanged"),QtGui.QColor.fromHsv(hue,sat,val))

    def sliderChanged(self,value=0):
        hue = min(self.hsv_pixmap_cursor_x*360./self.hsv_pixmap.width(),359)
        sat = 255-(self.hsv_pixmap_cursor_y*255./self.hsv_pixmap.height())
        val = value
        self.emit(QtCore.SIGNAL("colourChanged"),QtGui.QColor.fromHsv(hue,sat,val))

    def rePaintHSVWidget(self,value=0):
        #self.paint_pixmap.fill(QtGui.QColor(value,value,value))
        self.paint_pixmap.fill(QtGui.QColor(255,255,255))
        self.hsv_painter.begin(self.paint_pixmap)
        self.hsv_painter.drawPixmap(0,0,self.hsv_pixmap)
        brush = QtGui.QBrush(QtGui.QColor(255,255,255,255))
        rect = QtCore.QRect(self.hsv_pixmap_cursor_x-1,self.hsv_pixmap_cursor_y-10,3,20)
        self.hsv_painter.fillRect(rect,brush)
        rect = QtCore.QRect(self.hsv_pixmap_cursor_x-10,self.hsv_pixmap_cursor_y-1,20,3)
        self.hsv_painter.fillRect(rect,brush)
        brush = QtGui.QBrush(QtGui.QColor(0,0,0,255))
        rect = QtCore.QRect(self.hsv_pixmap_cursor_x,self.hsv_pixmap_cursor_y-10,1,20)
        self.hsv_painter.fillRect(rect,brush)
        rect = QtCore.QRect(self.hsv_pixmap_cursor_x-10,self.hsv_pixmap_cursor_y,20,1)
        self.hsv_painter.fillRect(rect,brush)
        self.hsv_painter.end()
        self.colour_widget.setPixmap(self.paint_pixmap)
        #self.colour_widget.setFixedSize(self.paint_pixmap.size())


#class ColourBrowser(MGSimpleDialog.MGSimpleDockDialog):
class ColourBrowser(QtGui.QDialog):

    #extra_custom_col = colourlist()
    new_name_number = -1
    
    def setShowPicture(self,colour=None,name=''):
        #print "setShowPicture",name
        if not colour:
          self.colour_name,r,g,b = self.initial_selected_colour
          self.selected_colour_pixmap.fill(QtGui.QColor(r,g,b))
          self.colour = QtGui.QColor(r,g,b)
        else:
          self.selected_colour_pixmap.fill(colour)
          self.colour = colour
          if name:
            self.colour_name = name
            self.setNameEditable()
        self.selected_painter.begin(self.show_pixmap)
        self.selected_painter.drawPixmap(0,0,self.selected_colour_pixmap)
        self.selected_painter.end()
        self.selected_colour_label.setPixmap(self.selected_colour_pixmap)
        self.selected_colour_label.setToolTip(self.colour_name)
        self.selected_colour_name.setText(self.colour_name)


    def setNameEditable(self,args=[]):
      if self.tab.currentIndex() == 0:
        self.selected_colour_name.setReadOnly(1)
      else:
        self.selected_colour_name.setReadOnly(0)

    def handleColourNameEdit(self,new_name):
      new_name = str(new_name)
      if self.standard_col.has_colour(new_name): return
      #print 'handleColourNameEdit',new_name 
      self.emit(QtCore.SIGNAL("colourNameEdit(PyQt_PyObject)"),[self.colour_name,new_name])
      # Update the local colour list - can only be custom colours that are changed
      self.custom_col.rename(self.colour_name,new_name)
      self.colour_name = new_name

    def HSVPictureChanged(self,colour):
        self.hsv_rgb_widget.blockSignals(True)
	try:
        	self.hsv_rgb_widget.setColour(colour)
        	colname = ('#'+
			    ("%2s" % hex(colour.red()).split('x')[1]).replace(' ','0')
			  + ("%2s" % hex(colour.green()).split('x')[1]).replace(' ','0')
			  + ("%2s" % hex(colour.blue()).split('x')[1]).replace(' ','0')
			  ).upper()
        	self.setShowPicture(colour,colname)
	except:
		pass
        self.hsv_rgb_widget.blockSignals(False)

    def HSVRGBChanged(self,colour):
        self.hsv_picture_widget.blockSignals(True)
	try:
        	self.hsv_picture_widget.setColour(colour)
        	colname = ('#'+
			    ("%2s" % hex(colour.red()).split('x')[1]).replace(' ','0')
			  + ("%2s" % hex(colour.green()).split('x')[1]).replace(' ','0')
			  + ("%2s" % hex(colour.blue()).split('x')[1]).replace(' ','0')
			  ).upper()
        	self.setShowPicture(colour,colname)
	except:
		pass
        self.hsv_picture_widget.blockSignals(False)

    def getColour(self):
        return self.colour
      
    def getColourName(self):
        return self.colour_name


    def setColour(self,colour,name='',index=-1):
        #print "setColour",name
        self.hsv_picture_widget.setColour(colour)
        self.hsv_rgb_widget.setColour(colour)
	if hasattr(colour,"red") and callable(colour.red) and hasattr(colour,"green") and callable(colour.green) and hasattr(colour,"blue") and callable(colour.blue):
		r,g,b = colour.red(),colour.green(),colour.blue()
		if self.custom_col.has_rgb(r,g,b):
			name = self.custom_col.get_name_for_rgb(r,g,b)
		elif self.standard_col.has_rgb(r,g,b):
			name = self.standard_col.get_name_for_rgb(r,g,b)
		else:
			name = ('#'+
			    ("%2s" % hex(colour.red()).split('x')[1]).replace(' ','0')
			  + ("%2s" % hex(colour.green()).split('x')[1]).replace(' ','0')
			  + ("%2s" % hex(colour.blue()).split('x')[1]).replace(' ','0')
			).upper()
        self.setShowPicture(colour,name)
        self.editLabel=-1

    def __init__(self,parent=None,standard_colours = [], custom_colours=[],new_name_number=-1,selected_colour=''):
        #MGSimpleDialog.MGSimpleDockDialog.__init__(self,parent,defaultDockArea=QtCore.Qt.NoDockWidgetArea)
        QtGui.QDialog.__init__(self,parent)
        self.menu = 'Windows'
        ColourBrowser.new_name_number = max(new_name_number,ColourBrowser.new_name_number)
        self.editOn = 0
        self.colour_name = ''
        
        self.draw()

        if standard_colours:
          self.standard_col = colourlist(standard_colours)
        else:
          self.standard_col = colourlist(default_colours)
        self.custom_col = colourlist(custom_colours)
        self.addColours(self.standard_col,self.grid_top_left,editable=0)
        self.addColours(self.custom_col,self.grid_bottom_left,editable=1)
        #self.addExtraCustomColours(self.extra_custom_col)

        if selected_colour and (self.standard_col.has_colour(selected_colour) or self.custom_col.has_colour(selected_colour)):
          self.initial_selected_colour = [selected_colour]
          if self.standard_col.has_colour(selected_colour):
           self.initial_selected_colour.extend(self.standard_col.get_rgb(name=selected_colour))
          elif self.custom_col.has_colour(selected_colour):
           self.initial_selected_colour.extend(self.custom_col.get_rgb(name=selected_colour))
        else:
          self.initial_selected_colour = ['cyan',0,255,255]
        #print "initial_selected_colour",self.initial_selected_colour
        self.setColour(QtGui.QColor(self.initial_selected_colour[1],self.initial_selected_colour[2],self.initial_selected_colour[3]),self.initial_selected_colour[0])
        self.setShowPicture()


    def updateCustomColours(self, custom_colours=[]):
      self.custom_col = colourlist(custom_colours)
      self.addColours(self.custom_col,self.grid_bottom_left,editable=1)

    def draw(self):
        self.orig_width = self.size().width()
        self.expanded_first_show = True;
        self.setWindowTitle(self.tr("Colour Browser"))
        self.fullScreenLabel = ClickLabel()

        self.colour = QtGui.QColor()
        self.columns_in_tables = 8

        layout = QtGui.QVBoxLayout()
        layout_left = QtGui.QVBoxLayout()
        layout_right = QtGui.QVBoxLayout()
        
        self.layout_top_left = QtGui.QVBoxLayout()
        self.label_top_left = QtGui.QLabel()
        self.label_top_left.setText(self.tr("Basic colours"))
        self.grid_top_left = QtGui.QGridLayout()

        self.layout_bottom_left = QtGui.QVBoxLayout()
        self.label_bottom_left = QtGui.QLabel()
        self.label_bottom_left.setText(self.tr("Custom colours"))
        self.grid_bottom_left = QtGui.QGridLayout()

        self.dialog_buttons = QtGui.QDialogButtonBox()
        ok_button = self.dialog_buttons.addButton(QtGui.QDialogButtonBox.Ok)
        apply_button = self.dialog_buttons.addButton(QtGui.QDialogButtonBox.Apply)
        cancel_button = self.dialog_buttons.addButton(QtGui.QDialogButtonBox.Cancel)
        clear_button = self.dialog_buttons.addButton('Clear',QtGui.QDialogButtonBox.ResetRole)
        clear_button.setToolTip('Clear all custom colours')
        self.connect(cancel_button,QtCore.SIGNAL('clicked()'),self.hide)
        self.connect(ok_button,QtCore.SIGNAL('clicked()'),self.ApplyAndClose)
        self.connect(apply_button,QtCore.SIGNAL('clicked()'),self.Apply)
        self.connect(clear_button,QtCore.SIGNAL('clicked()'),self.Clear)

        self.hsv_picture_widget = HSVPictureWidget()

        self.layout_bottom_right = QtGui.QHBoxLayout()
        self.selected_colour_label = QtGui.QLabel()

        self.selected_colour_pixmap = QtGui.QPixmap(50,15)
        self.show_pixmap = QtGui.QPixmap(50,15)
        self.selected_painter = QtGui.QPainter()
        self.selected_colour_label.setFrameStyle(QtGui.QFrame.Panel)
        self.selected_colour_label.setFrameShadow(QtGui.QFrame.Sunken)
        self.selected_colour_label.setLineWidth(2)
        self.selected_colour_label.setFixedWidth(54)


        self.connect(self.hsv_picture_widget,QtCore.SIGNAL("colourChanged"),self.HSVPictureChanged)


        self.hsv_rgb_widget = HSVRGBWidget()
        self.connect(self.hsv_rgb_widget,QtCore.SIGNAL("colourChanged"),self.HSVRGBChanged)


        self.custom_colour_button = QtGui.QPushButton(self.tr("Save colour"))
        self.connect(self.custom_colour_button,QtCore.SIGNAL("clicked(bool)"),self.addCustomColour)

        
        self.layout_top_left.addWidget(self.label_top_left) 

        sa2 = QtGui.QScrollArea()
        sa = QtGui.QScrollArea()
        #sa.setFixedHeight(125)
        #sa2.setFixedHeight(125)

        sa.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        sa2.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        widget_top_left = QtGui.QWidget()
        widget_top_left.setLayout(self.grid_top_left)
        sa2.setWidget(widget_top_left)
        sa2.setWidgetResizable(True)
        self.layout_top_left.addWidget(sa2)

        self.layout_bottom_left.addWidget(self.label_bottom_left) 
        widget_bottom_left = QtGui.QWidget()
        widget_bottom_left.setLayout(self.grid_bottom_left)
        sa.setWidget(widget_bottom_left)
        sa.setWidgetResizable(True)
        self.layout_bottom_left.addWidget(sa)

        self.layout_bottom_right.addWidget(self.hsv_rgb_widget)
        layout_left.addLayout(self.layout_top_left)
        layout_left.addLayout(self.layout_bottom_left)
        #layout_left.addStretch(1)
        layout_right.addWidget(self.hsv_picture_widget)
        layout_right.addLayout(self.layout_bottom_right)

        grab_button = QtGui.QPushButton(self.tr("Grab colour from screen"))
        self.connect(grab_button,QtCore.SIGNAL("clicked(bool)"),self.Grab)
        layout_right.addWidget(grab_button)

        layout_right.addWidget(self.custom_colour_button)

        self.widget_left = QtGui.QWidget()
        self.widget_left.setLayout(layout_left)
        self.widget_right = QtGui.QWidget()
        self.widget_right.setLayout(layout_right)

        self.tab = QtGui.QTabWidget(self)
	layout.addWidget(self.tab)

        self.tab.addTab(self.widget_left,"Main colours")
        self.tab.addTab(self.widget_right,"Create colours")
        self.connect(self.tab,QtCore.SIGNAL('currentChanged(int)'),self.setNameEditable)

        selected_colour_layout = QtGui.QHBoxLayout()
        selected_colour_layout.addWidget(QtGui.QLabel(self.tr("Selected colour")))
        selected_colour_layout.addWidget(self.selected_colour_label)
        self.selected_colour_name = QtGui.QLineEdit(self)
        #self.connect( self.selected_colour_name, QtCore.SIGNAL('textEdited(const QString)'),self.handleColourNameEdit)
        selected_colour_layout.addWidget( self.selected_colour_name)
	layout.addLayout(selected_colour_layout)
        layout.addWidget(self.dialog_buttons)

        self.setLayout(layout)
        #self.setFixedHeight(550)

        #layout = QtGui.QVBoxLayout()
        selected_colour_layout.setContentsMargins(0,0,0,0)
        layout_right.setContentsMargins(0,0,0,0)
        left,right,top,bottom = layout_right.getContentsMargins()
        self.layout_bottom_right.setContentsMargins(left,0,right,0)
        left,right,top,bottom = self.hsv_rgb_widget.layout().getContentsMargins()
        self.hsv_rgb_widget.layout().setContentsMargins(left,0,right,0)
        left,right,top,bottom = self.hsv_rgb_widget.layout().getContentsMargins()
        #self.hsv_picture_widget.layout().setContentsMargins(0,0,0,0)
        #layout_left.setContentsMargins(0,0,0,0)
        #self.grid_top_left.setContentsMargins(0,0,0,0)
        #self.grid_bottom_left.setContentsMargins(0,0,0,0)
        #self.layout_top_left.setContentsMargins(0,0,0,0)
        #self.layout_bottom_left.setContentsMargins(0,0,0,0)
        self.grid_top_left.setSpacing(2)
        self.grid_bottom_left.setSpacing(2)
        self.grid_top_left.setContentsMargins(4,4,4,4)
        self.grid_bottom_left.setContentsMargins(4,4,4,4)

        self.setSizeGripEnabled(0)

    def ApplyAndClose(self):
        self.Apply()
        self.hide()

    def Apply(self):
        self.addCustomColour()
        col = self.getColourName()
        self.emit(QtCore.SIGNAL("ColourSelected"),col)

    def Clear(self):
      self.custom_col = colourlist([])
      self.addColours(self.custom_col,self.grid_bottom_left,editable=1)
      self.emit(QtCore.SIGNAL("clearCustomColours"))
      
    def addCustomColour(self,checked=False):
        if self.custom_col.len()<self.columns_in_tables:
           if hasattr(self,'custom_spacer'):
             self.grid_bottom_left.removeItem(self.custom_spacer)
        col = self.getColour()
        if self.custom_col.has_rgb(col.red(),col.green(),col.blue()): return
        colname = str(self.selected_colour_name.text())
        if self.standard_col.has_colour(colname):return
        if not colname:
          if ColourBrowser.new_name_number>=0:
            colname = 'user_'+str(ColourBrowser.new_name_number)
            ColourBrowser.new_name_number=ColourBrowser.new_name_number+1
          else:
            colname = 'Custom '+('#'+
			    ("%2s" % hex(col.red()).split('x')[1]).replace(' ','0')
			  + ("%2s" % hex(col.green()).split('x')[1]).replace(' ','0')
			  + ("%2s" % hex(col.blue()).split('x')[1]).replace(' ','0')
			  ).upper()
        if self.editLabel >=0:
          self.custom_col.set_colour(self.editLabel,name=colname,rgb=[col.red(),col.green(),col.blue()])
        else:
	  self.custom_col.add_colour(name=colname,rgb=[col.red(),col.green(),col.blue()])
        self.emit(QtCore.SIGNAL("newColour"),[colname,col.red(),col.green(),col.blue()])

	self.addColours(self.custom_col,self.grid_bottom_left,editable=1)
       
        # Recolour the selected colour square to ensure that it now has a toopTip name
        self.setShowPicture(col,colname)
        
    def Grab(self):
        app = QtGui.QApplication.instance()
        pixmap = QtGui.QPixmap.grabWindow(app.desktop().winId())
        try:
          self.fullScreenLabel.setPixmap(pixmap)
          self.fullScreenLabel.setWindowFlags(QtCore.Qt.Window)
          self.fullScreenLabel.setWindowState(QtCore.Qt.WindowFullScreen)
          self.fullScreenLabel.show()
          self.fullScreenLabel.raise_()
          self.fullScreenLabel.setWindowState(QtCore.Qt.WindowFullScreen)
          self.connect(self.fullScreenLabel,QtCore.SIGNAL("MousePressed"),self.handleFullScreenClick)
          self.fullScreenLabel.setCursor(QtCore.Qt.CrossCursor)
        except:
          self.fullScreenLabel.close()

    def handleFullScreenClick(self,args):
        try:
          event = args[0]
          label = args[1]
          x,y = event.pos().x(), event.pos().y()
          if x>0 and x<label.pixmap().width() and y>0 and y<label.pixmap().height():
            colour = QtGui.QColor(label.pixmap().toImage().pixel(x,y))
            self.setColour(colour)
        except:
          pass
        self.fullScreenLabel.close()

    def unSinkColourLabels(self):
        for i in range(self.grid_bottom_left.count()):
          if self.grid_bottom_left.itemAt(i).widget(): self.grid_bottom_left.itemAt(i).widget().setFrameShadow(QtGui.QFrame.Raised)
        for i in range(self.grid_top_left.count()):
          if self.grid_top_left.itemAt(i).widget(): self.grid_top_left.itemAt(i).widget().setFrameShadow(QtGui.QFrame.Raised)

    def colourTableClicked(self,label):
        #print "colourTableClicked",args
        self.unSinkColourLabels()
        label.setFrameShadow(QtGui.QFrame.Sunken)
        self.setColour(label.getColour(),str(label.toolTip()))

    def colourTableDoubleClicked(self,args):
        self.unSinkColourLabels()
        colour = args[1].getColour()
        label = args[1]
        label.setFrameShadow(QtGui.QFrame.Sunken)
        self.setColour(colour,str(label.toolTip()))
        #print "emitting", colour.red(), colour.green(), colour.blue()
        self.emit(QtCore.SIGNAL("ColourChanged"),colour)

    def addColours(self,colours,layout,editable=0):
        widget = layout.parentWidget()
	# Remove all current ColourLabel
        children = widget.findChildren(ColourLabel)
        for child in children:
	  layout.removeWidget(child)
	  child.close()
	
        for i in range(0,colours.len()):
           row,col = i/self.columns_in_tables, i%self.columns_in_tables
           label = ColourLabel(editable=editable)
           label.setToolTip(colours.get_colour(i))
           label.setObjectName(str(i))
           r,g,b = colours.get_rgb(i)
           label.setColour( QtGui.QColor(r,g,b))
           layout.addWidget(label,row,col)
           self.connect(label,QtCore.SIGNAL("LeftMousePressed"),self.colourTableClicked)
           self.connect(label,QtCore.SIGNAL("delete"),self.deleteColour)
           self.connect(label,QtCore.SIGNAL("edit"),self.editColour)
           self.connect(label,QtCore.SIGNAL("MouseDoubleClick"),self.colourTableDoubleClicked)
        if layout.count()<self.columns_in_tables:
		for isp in range(self.columns_in_tables-colours.len()):
			label = ColourLabel(dummy=1)
                        layout.addWidget(label,0,self.columns_in_tables-isp-1)
                        
        row = colours.len()/self.columns_in_tables
        layout.setRowStretch(row,0)
        layout.setRowStretch(row+1,1)

    def deleteColour(self,label=None):
      colname = label.toolTip()
      idx = self.custom_col.index(colname)
      #print 'deleteColour',colname,idx
      if idx>=0:
        rv = self.custom_col.delete(idx)
        if not rv:
          self.emit(QtCore.SIGNAL("deleteColour"),colname)

          self.addColours(self.custom_col,self.grid_bottom_left,editable=1)

    def editColour(self,label=None):
      #print 'editColour',label.toolTip()
      self.colourTableClicked(label)
      self.tab.setCurrentIndex(1)
      self.editLabel = int(label.objectName())
      #print 'editColour editLabel',self.editLabel
