示例#1
0
class JObject:
    def __init__(self, visible=True):
        self._visible = visible
        self._color = QColor(255, 255, 255)
        self._background_color = QColor(0, 0, 0)

    def setVisibility(self, v):
        self._visible = v

    def getVisibility(self):
        return self._visible

    def setColor(self, color):
        self._color = color

    def getColor(self, color):
        return self._color

    def setOpenGlColor(self):
        glColor3f(self._color.red() / 255.0,
                  self._color.green() / 255.0,
                  self._color.blue() / 255.0)

    def setGlBackGroundColor(self):
        glColor3f(self._background_color.red() / 255.0,
                  self._background_color.green() / 255.0,
                  self._background_color.blue() / 255.0)

    def setGlColor(self):
        glColor3f(self._color.red() / 255.0,
                  self._color.green() / 255.0,
                  self._color.blue() / 255.0)
示例#2
0
文件: __init__.py 项目: nerdocs/MedUX
 def mergedColors(colorA: QColor, colorB: QColor, factor=50):
     """
     Creates a merged new QColor of colorA and colorB and returns it
     """
     maxFactor = 100
     tmp = QColor(colorA)
     tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor)
     tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor)
     tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor)
     return tmp
示例#3
0
 def refresh(self):
     tmp = self.strip.state()
     for i in xrange(len(self.buttons)):
         c = QColor(int(tmp[i*3+0]),int(tmp[i*3+1]),int(tmp[i*3+2]))
         pal = self.buttons[i][0].palette()
         pal.setBrush( QPalette.Button, QColor(c.red(),c.green(),c.blue()))
         self.buttons[i][0].setPalette(pal)
         self.buttons[i][1] = c
示例#4
0
    def _update_colors(self):
        op = self.topLevelOperatorView.opCarving
        ctable = self._doneSegmentationLayer.colorTable

        for name, label in self._shownObjects3D.iteritems():
            color = QColor(ctable[op.MST.value.object_names[name]])
            color = (color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0)
            self._renderMgr.setColor(label, color)
示例#5
0
 def testSetColorForClass(self):
     """
     Test that clicking the CANVAS sets the current class
     color if the layer is a vector layer.
     """
     self.prepareTestCanvas()
     #self.bucketFill.setColorForClass(
     #                        QPoint(50, 15), QtCore.Qt.LeftButton)
     myColor = QColor(CANVAS.canvasPixmap().toImage().pixel(50, 15))
     # Just for if you want to see what it has rendered
     CANVAS.saveAsImage('test.png')
     # expected R: 182 G: 109 B: 194
     myExpectedColor = QColor(182, 109, 194)
     myMessage = (('Unexpected color\n Received R: %i G: %i B: %i '
                   '\n Expected: R: %i G: %i B: %i') %
                  (myColor.red(), myColor.green(), myColor.blue(),
                   myExpectedColor.red(), myExpectedColor.green(),
                   myExpectedColor.blue()))
     assert myColor == myExpectedColor, myMessage
示例#6
0
    def __init__(self, points, rgb, alpha):

        self.points = points
        colour = QColor(rgb)
        self.red = colour.red()
        self.green = colour.green()
        self.blue = colour.blue()
        colour.setAlphaF(alpha)
        self.alpha = alpha
        self.rgba = colour.rgb()
        self.projected = []
示例#7
0
    def _update_colors(self):
        op = self.topLevelOperatorView
        ctable = self._doneSegmentationLayer.colorTable

        for name, label in self._shownObjects3D.iteritems():
            color = QColor(ctable[op.MST.value.object_names[name]])
            color = (color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0)
            self._renderMgr.setColor(label, color)

        if self._showSegmentationIn3D and self._segmentation_3d_label is not None:
            self._renderMgr.setColor(self._segmentation_3d_label, (0.0, 1.0, 0.0)) # Green
示例#8
0
    def _update_colors(self):
        op = self.topLevelOperatorView
        ctable = self._doneSegmentationLayer.colorTable

        for name, label in self._shownObjects3D.iteritems():
            color = QColor(ctable[op.MST.value.object_names[name]])
            color = (color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0)
            self._renderMgr.setColor(label, color)

        if self._showSegmentationIn3D and self._segmentation_3d_label is not None:
            self._renderMgr.setColor(self._segmentation_3d_label, (0.0, 1.0, 0.0)) # Green
示例#9
0
    def render_color_scribble(self):
        r = []
        g = []
        b = []
        for i in range(8):
            for j in range(8):
                color = QColor(self.scribble_area.image.pixel(j, i))
                r.append(color.red())
                g.append(color.green())
                b.append(color.blue())

        self.set_rgb(r, g, b)
示例#10
0
def calculate_px_rgb(sub_image, xy_length):
    """
    I hate that this function uses a double for loop
    Any way to just map a full QImage to numpy array???
    """
    px_tot = np.zeros(3)
    for x in xrange(xy_length):
        for y in xrange(xy_length):
            color = QColor(sub_image.pixel(x, y))
            px_tot += (color.red(), color.green(), color.blue())
    avg_rgb = (px_tot / float(sub_image.width() * sub_image.height())).astype(np.int16)
    return avg_rgb[0], avg_rgb[1], avg_rgb[2]
示例#11
0
 def _set_background_color(self):
     myColor = QColor("#F2EFE9")
     # Write it to the project (will still need to be saved!)
     QgsProject.instance().writeEntry("Gui", "/CanvasColorRedPart",
                                      myColor.red())
     QgsProject.instance().writeEntry("Gui", "/CanvasColorGreenPart",
                                      myColor.green())
     QgsProject.instance().writeEntry("Gui", "/CanvasColorBluePart",
                                      myColor.blue())
     # And apply for the current session
     self.iface.mapCanvas().setCanvasColor(myColor)
     self.iface.mapCanvas().refresh()
 def testSetColorForClass(self):
     """
     Test that clicking the CANVAS sets the current class
     color if the layer is a vector layer.
     """
     self.prepareTestCanvas()
     #self.bucketFill.setColorForClass(
     #                        QPoint(50, 15), QtCore.Qt.LeftButton)
     myColor = QColor(CANVAS.canvasPixmap().toImage().pixel(50, 15))
     # Just for if you want to see what it has rendered
     CANVAS.saveAsImage('test.png')
     # expected R: 182 G: 109 B: 194
     myExpectedColor = QColor(182, 109, 194)
     myMessage = (('Unexpected color\n Received R: %i G: %i B: %i '
                 '\n Expected: R: %i G: %i B: %i') %
                   (myColor.red(),
                    myColor.green(),
                    myColor.blue(),
                    myExpectedColor.red(),
                    myExpectedColor.green(),
                    myExpectedColor.blue()))
     assert myColor == myExpectedColor, myMessage
示例#13
0
def get_pixel_value(pixels, x, y):
    if ascii_mode_enabled:
        color = "MNHQ$OC?7>!:-;. "
    else:
        color = "" * 16
    rgba = QColor(pixels.pixel(x, y))
    rgb = rgba.red(), rgba.green(), rgba.blue()
    index = int(sum(rgb) / 3.0 / 256.0 * 16)
    pair = curses.color_pair(index + 10)
    if ascii_mode_enabled:
        pair = 1

    try:
        return color[index], pair
    except IndexError:
        return " ", pair
示例#14
0
def get_pixel_value(pixels, x, y):
    if ascii_mode_enabled:
        color = "MNHQ$OC?7>!:-;. "
    else:
        color = "" * 16
    rgba = QColor(pixels.pixel(x, y))
    rgb = rgba.red(), rgba.green(), rgba.blue()
    index = int(sum(rgb) / 3.0 / 256.0 * 16)
    pair = curses.color_pair(index + 10)
    if ascii_mode_enabled:
        pair = 1

    try:
        return color[index], pair
    except IndexError:
        return " ", pair
示例#15
0
文件: theme.py 项目: kurokid/Ubezee
    def setTheme(self, color):
        c = QColor()
        c.setNamedColor(color)
        c.setRed(self.qMin(c.red() + 40, 255))
        c.setGreen(self.qMin(c.green() + 40, 255))
        c.setBlue(self.qMin(c.blue() + 40, 255))
        self.myTheme[0] = color
        self.myTheme[1] = c.name()

        try:
            f = open(COLOR_PATH, "w")
            for item in self.myTheme:
                f.write("%s\n" % item)
            f.close()
        except IOError:
            self.createConfig()
示例#16
0
    def hsl_changed(self, *args):
        if self.changing:
            return

        h, s, l = self.spin_h.value(), self.spin_s.value(), self.spin_l.value()
        hsl = QColor()
        hsl.setHsl(h, s, l)
        r, g, b = hsl.red(), hsl.green(), hsl.blue()

        self.changing = True
        self.spin_r.setValue(r)
        self.spin_g.setValue(g)
        self.spin_b.setValue(b)
        self.changing = False

        self.rgb_led.set_rgb_value(r, g, b)
        self.label_color.setStyleSheet('QLabel {{ background: #{:02x}{:02x}{:02x} }}'.format(r, g, b))
示例#17
0
    def hsl_changed(self, *args):
        if self.changing:
            return

        h, s, l = self.spin_h.value(), self.spin_s.value(), self.spin_l.value()
        hsl = QColor()
        hsl.setHsl(h, s, l)
        r, g, b = hsl.red(), hsl.green(), hsl.blue()

        self.changing = True
        self.spin_r.setValue(r)
        self.spin_g.setValue(g)
        self.spin_b.setValue(b)
        self.changing = False

        self.rgb_led_button.set_color(r, g, b)
        self.label_color.setStyleSheet(
            'QLabel {{ background: #{:02x}{:02x}{:02x} }}'.format(r, g, b))
def font_bmp_to_alpha(filename):
  
  image = QImage(filename)
  image = image.convertToFormat(QImage.Format_ARGB32_Premultiplied)
  
  # Because the game uses 8bit grayscale bitmaps for its fonts with white as
  # fully visible and black as fully transparent, I'm using a naive technique
  # that averages the RGB value of a pixel and sets that as its alpha value.
  # I'm sure this will do fun stuff to other images, but it does the job
  # for the game's fonts, and that's all that really matters. ヽ(´ー`)ノ
  for i in range(image.width()):
    for j in range(image.height()):
      color = QColor(image.pixel(i, j))
      alpha = (color.red() + color.green() + color.blue()) / 3
      color.setAlpha(alpha)
      image.setPixel(i, j, color.rgba())
  
  return image
def font_bmp_to_alpha(filename):
  
  image = QImage(filename)
  image = image.convertToFormat(QImage.Format_ARGB32_Premultiplied)
  
  # Because the game uses 8bit grayscale bitmaps for its fonts with white as
  # fully visible and black as fully transparent, I'm using a naive technique
  # that averages the RGB value of a pixel and sets that as its alpha value.
  # I'm sure this will do fun stuff to other images, but it does the job
  # for the game's fonts, and that's all that really matters. ヽ(´ー`)ノ
  for i in range(image.width()):
    for j in range(image.height()):
      color = QColor(image.pixel(i, j))
      alpha = (color.red() + color.green() + color.blue()) / 3
      color.setAlpha(alpha)
      image.setPixel(i, j, color.rgba())
  
  return image
示例#20
0
    def convertImagetoText(self):
        if str(self.image_file_name).endswith("txt") or str(self.image_file_name).endswith("TXT"):
          return self.image_file_name

        else:
            out_file_name = os.getcwd() + "/Output/temp_image.txt"
            out_file = open(out_file_name, "w")

            separator = '	'

            image = QtGui.QImage(self.image_file_name)

            x_pixels = image.width()
            z_pixels = image.height()

            for z_index in range (0, z_pixels):

                row = ""

                for x_index in range (0, x_pixels):
                    color = QColor(image.pixel(x_index, z_index))

                    red = color.red()
                    blue = color.blue()
                    green = color.green()

                    grey = (red*11+green*16+blue*5)/32

                    if x_index == x_pixels - 1:
                        row += str(int(grey))
                    else:
                        row += str(int(grey)) + separator

                out_file.write(row + "\r")

            out_file.flush()
            out_file.close()

        return out_file_name
示例#21
0
    def applyLegend(self, levels, colHEX_RGB):

        nLevels = len(levels)-1

        self.ui.tableWidget.setRowCount(nLevels)
        
        for row in range(nLevels):
            item1 = QtGui.QTableWidgetItem()
            item1.setText(str(levels[row]))
            self.ui.tableWidget.setItem(row, 0, item1)
            
            item2 = QtGui.QTableWidgetItem()
            item2.setText(str(levels[row+1]))
            self.ui.tableWidget.setItem(row, 1, item2)
            
            col = colors.hex2color(colHEX_RGB[row])
            colPy = QColor(int(col[0]*255),int(col[1]*255),int(col[2]*255))
            item3 = QtGui.QTableWidgetItem()
            item3.setBackground(colPy)
            item3.setFlags(QtCore.Qt.ItemIsEnabled)
            item3.setText(str(colPy.red()) + ", " + str(colPy.green()) + ", " + str(colPy.blue()))
            self.ui.tableWidget.setItem(row, 2, item3)
示例#22
0
 def color(cls, mscolor, opacity=100):
     n = len(mscolor)
     a = int(round(opacity * 2.55))
     color_ = QColor("red")  #color de error
     if isinstance(mscolor, list):
         if n == 3:
             color_ = QColor(mscolor[0], mscolor[1], mscolor[2], a)
     elif isinstance(mscolor, (str, unicode)):
         match = cls.REGEX_ATTR.search(mscolor)
         if mscolor[:1] == "#":
             print("#", n)
             r = int(mscolor[1:3], 16)
             g = int(mscolor[3:5], 16)
             b = int(mscolor[5:7], 16)
             if n == 7:
                 color_ = QColor(r, g, b, a)
             elif n == 9:
                 a2 = int(mscolor[7:9], 16)
                 #unificar "a" con opacity y alpha del string
                 #es el promedio, o % de la que ya tiene
                 a = int(round((a + a2) / 2))
                 #a = int(a2 * opacity * 1.0 / 100)
                 color_ = QColor(r, g, b, a)
         elif match:
             #Color es definido por atributo
             return (match.group(1), True)
         else:
             if mscolor in QColor.colorNames():
                 color_ = QColor(mscolor)
                 color_.setAlpha(a)
     r = color_.red()
     g = color_.green()
     b = color_.blue()
     a = color_.alpha()
     qcolor_ = "{},{},{},{}".format(r, g, b, a)
     return (qcolor_, False, r, g, b, a)
示例#23
0
class arcPoint():
	global currentColor
	def __init__(self, x, y=0, z=0, color=None):
		if x.__class__.__name__ == 'arcPoint':
			self.x = x.x
			self.y = x.y
			self.z = x.z
			self.color = QColor(x.color.red(), x.color.green(), x.color.blue())
		else:
			self.x = x
			self.y = y
			self.z = z
			if color:
				self.color = QColor(color.red(), color.green(), color.blue())
			else:
				self.color = QColor(currentColor.red(), currentColor.green(), currentColor.blue())
	
	def __sub__(self, p):
		return arcPoint(self.x - p.x, self.y - p.y, self.z - p.z, QColor(self.color.red(), self.color.green(), self.color.blue()))
	
	def __add__(self, p):
		return arcPoint(self.x + p.x, self.y + p.y, self.z + p.z, QColor(self.color.red(), self.color.green(), self.color.blue()))
	
	def __eq__(self, p):
		return self.x == p.x and self.y == p.y and self.z == p.z
	
	def __ne__(self, p):
		return not self.__eq__(p)
	
	def __str__(self):
		return '<' + str(self.x) + ',' + str(self.y) + ',' + str(self.z) + '>'
		
	def __repr__(self):
		return '<' + str(self.x) + ',' + str(self.y) + ',' + str(self.z) + '>'
	
	def __mul__(self, k):
		return arcPoint(self.x*k, self.y*k, self.z*k, QColor(self.color.red(), self.color.green(), self.color.blue()))
	
	def __rmul__(self, k):
		return arcPoint(self.x*k, self.y*k, self.z*k, QColor(self.color.red(), self.color.green(), self.color.blue()))
		
	
	def dotProduct(self, p):
		return p.x*self.x + p.y*self.y + p.z*self.z
	
	def vectorProduct(self, p):
		newPoint = arcPoint(self.x, self.y, self.z)
		
		newPoint.x = self.y*p.z - p.y*self.z
		if newPoint.x == -0.0:
			newPoint.x = 0.0
		newPoint.y = self.z*p.x - p.z*self.x
		if newPoint.y == -0.0:
			newPoint.y = 0.0
		newPoint.z = self.x*p.y - p.x*self.y
		if newPoint.z == -0.0:
			newPoint.z = 0.0
		
		return newPoint
	
	def multMatrix(self, matrix):
		newPoint = arcMultiplyMatrices(matrix, [[self.x], [self.y], [self.z], [1]])
		self.x = newPoint[0][0]
		self.y = newPoint[1][0]
		self.z = newPoint[2][0]
	
	def normalize(self):
		norm = sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
		if norm > 0:
			self.x = self.x/norm
			self.y = self.y/norm
			self.z = self.z/norm
		return self
	
	def getNormal(self):
		norm = sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
		p = arcPoint(self.x, self.y, self.z, self.color)
		if norm > 0:
			p.x = p.x/norm
			p.y = p.y/norm
			p.z = p.z/norm
		
		return p
示例#24
0
class SearchInFiles(foundations.ui.common.QWidgetFactory(uiFile=UI_FILE)):
	"""
	Defines search and replace in files dialog used by the **ScriptEditor** Component.
	"""

	def __init__(self, parent, *args, **kwargs):
		"""
		Initializes the class.

		:param parent: Object parent.
		:type parent: QObject
		:param \*args: Arguments.
		:type \*args: \*
		:param \*\*kwargs: Keywords arguments.
		:type \*\*kwargs: \*\*
		"""

		LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))

		super(SearchInFiles, self).__init__(parent, *args, **kwargs)

		# --- Setting class attributes. ---
		self.__container = self.__scriptEditor = parent

		self.__filesCache = foundations.cache.Cache()

		self.__searchPatternsModel = None
		self.__replaceWithPatternsModel = None

		self.__model = None
		self.__view = None
		self.__delegate = None

		self.__locations = OrderedDict([("Add Directory ...", "directory"),
								("Add File ...", "file"),
								("Add Opened Files", "editors"),
								("Add Include Filter", "includeFilter"),
								("Add Exclude Filter", "excludeFilter")])
		self.__locationsMenu = None

		self.__defaultFilterIn = "*.txt"
		self.__filtersInFormat = "{0}"
		self.__defaultFilterOut = "*.txt"
		self.__filtersOutFormat = "!{0}"
		self.__defaultTarget = "Opened Files"
		self.__targetsFormat = "<{0}>"

		self.__defaultLineNumberWidth = 6
		self.__defaultLineColor = QColor(144, 144, 144)

		self.__ignoreHiddenFiles = True

		self.__searchWorkerThread = None

		SearchInFiles.__initializeUi(self)

	#******************************************************************************************************************
	#***	Attributes properties.
	#******************************************************************************************************************
	@property
	def container(self):
		"""
		Property for **self.__container** attribute.

		:return: self.__container.
		:rtype: QObject
		"""

		return self.__container

	@container.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def container(self, value):
		"""
		Setter for **self.__container** attribute.

		:param value: Attribute value.
		:type value: QObject
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "container"))

	@container.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def container(self):
		"""
		Deleter for **self.__container** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "container"))

	@property
	def scriptEditor(self):
		"""
		Property for **self.__scriptEditor** attribute.

		:return: self.__scriptEditor.
		:rtype: QWidget
		"""

		return self.__scriptEditor

	@scriptEditor.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def scriptEditor(self, value):
		"""
		Setter for **self.__scriptEditor** attribute.

		:param value: Attribute value.
		:type value: QWidget
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "scriptEditor"))

	@scriptEditor.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def scriptEditor(self):
		"""
		Deleter for **self.__scriptEditor** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "scriptEditor"))

	@property
	def filesCache(self):
		"""
		Property for **self.__filesCache** attribute.

		:return: self.__filesCache.
		:rtype: Cache
		"""

		return self.__filesCache

	@filesCache.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def filesCache(self, value):
		"""
		Setter for **self.__filesCache** attribute.

		:param value: Attribute value.
		:type value: Cache
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "filesCache"))

	@filesCache.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def filesCache(self):
		"""
		Deleter for **self.__filesCache** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "filesCache"))

	@property
	def searchPatternsModel(self):
		"""
		Property for **self.__searchPatternsModel** attribute.

		:return: self.__searchPatternsModel.
		:rtype: PatternsModel
		"""

		return self.__searchPatternsModel

	@searchPatternsModel.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def searchPatternsModel(self, value):
		"""
		Setter for **self.__searchPatternsModel** attribute.

		:param value: Attribute value.
		:type value: PatternsModel
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "searchPatternsModel"))

	@searchPatternsModel.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def searchPatternsModel(self):
		"""
		Deleter for **self.__searchPatternsModel** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "searchPatternsModel"))

	@property
	def replaceWithPatternsModel(self):
		"""
		Property for **self.__replaceWithPatternsModel** attribute.

		:return: self.__replaceWithPatternsModel.
		:rtype: PatternsModel
		"""

		return self.__replaceWithPatternsModel

	@replaceWithPatternsModel.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def replaceWithPatternsModel(self, value):
		"""
		Setter for **self.__replaceWithPatternsModel** attribute.

		:param value: Attribute value.
		:type value: PatternsModel
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "replaceWithPatternsModel"))

	@replaceWithPatternsModel.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def replaceWithPatternsModel(self):
		"""
		Deleter for **self.__replaceWithPatternsModel** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "replaceWithPatternsModel"))

	@property
	def model(self):
		"""
		Property for **self.__model** attribute.

		:return: self.__model.
		:rtype: SearchResultsModel
		"""

		return self.__model

	@model.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def model(self, value):
		"""
		Setter for **self.__model** attribute.

		:param value: Attribute value.
		:type value: SearchResultsModel
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "model"))

	@model.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def model(self):
		"""
		Deleter for **self.__model** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "model"))

	@property
	def view(self):
		"""
		Property for **self.__view** attribute.

		:return: self.__view.
		:rtype: QWidget
		"""

		return self.__view

	@view.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def view(self, value):
		"""
		Setter for **self.__view** attribute.

		:param value: Attribute value.
		:type value: QWidget
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "view"))

	@view.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def view(self):
		"""
		Deleter for **self.__view** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "view"))

	@property
	def delegate(self):
		"""
		Property for **self.__delegate** attribute.

		:return: self.__delegate.
		:rtype: QItemDelegate
		"""

		return self.__delegate

	@delegate.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def delegate(self, value):
		"""
		Setter for **self.__delegate** attribute.

		:param value: Attribute value.
		:type value: QItemDelegate
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "delegate"))

	@delegate.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def delegate(self):
		"""
		Deleter for **self.__delegate** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "delegate"))

	@property
	def locations(self):
		"""
		Property for **self.__locations** attribute.

		:return: self.__locations.
		:rtype: OrderedDict
		"""

		return self.__locations

	@locations.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def locations(self, value):
		"""
		Setter for **self.__locations** attribute.

		:param value: Attribute value.
		:type value: OrderedDict
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "locations"))

	@locations.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def locations(self):
		"""
		Deleter for **self.__locations** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "locations"))

	@property
	def locationsMenu(self):
		"""
		Property for **self.__locationsMenu** attribute.

		:return: self.__locationsMenu.
		:rtype: QMenu
		"""

		return self.__locationsMenu

	@locationsMenu.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def locationsMenu(self, value):
		"""
		Setter for **self.__locationsMenu** attribute.

		:param value: Attribute value.
		:type value: QMenu
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "locationsMenu"))

	@locationsMenu.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def locationsMenu(self):
		"""
		Deleter for **self.__locationsMenu** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "locationsMenu"))

	@property
	def defaultFilterIn(self):
		"""
		Property for **self.__defaultFilterIn** attribute.

		:return: self.__defaultFilterIn.
		:rtype: unicode
		"""

		return self.__defaultFilterIn

	@defaultFilterIn.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def defaultFilterIn(self, value):
		"""
		Setter for **self.__defaultFilterIn** attribute.

		:param value: Attribute value.
		:type value: unicode
		"""

		if value is not None:
			assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
			"defaultFilterIn", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("defaultFilterIn", value)
		self.__defaultFilterIn = value

	@defaultFilterIn.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def defaultFilterIn(self):
		"""
		Deleter for **self.__defaultFilterIn** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultFilterIn"))
	@property
	def filtersInFormat(self):
		"""
		Property for **self.__filtersInFormat** attribute.

		:return: self.__filtersInFormat.
		:rtype: unicode
		"""

		return self.__filtersInFormat

	@filtersInFormat.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def filtersInFormat(self, value):
		"""
		Setter for **self.__filtersInFormat** attribute.

		:param value: Attribute value.
		:type value: unicode
		"""

		if value is not None:
			assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
			"filtersInFormat", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("filtersInFormat", value)
		self.__filtersInFormat = value

	@filtersInFormat.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def filtersInFormat(self):
		"""
		Deleter for **self.__filtersInFormat** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "filtersInFormat"))

	@property
	def defaultFilterOut(self):
		"""
		Property for **self.__defaultFilterOut** attribute.

		:return: self.__defaultFilterOut.
		:rtype: unicode
		"""

		return self.__defaultFilterOut

	@defaultFilterOut.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def defaultFilterOut(self, value):
		"""
		Setter for **self.__defaultFilterOut** attribute.

		:param value: Attribute value.
		:type value: unicode
		"""

		if value is not None:
			assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
			"defaultFilterOut", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("defaultFilterOut", value)
		self.__defaultFilterOut = value

	@defaultFilterOut.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def defaultFilterOut(self):
		"""
		Deleter for **self.__defaultFilterOut** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultFilterOut"))
	@property
	def filtersOutFormat(self):
		"""
		Property for **self.__filtersOutFormat** attribute.

		:return: self.__filtersOutFormat.
		:rtype: unicode
		"""

		return self.__filtersOutFormat

	@filtersOutFormat.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def filtersOutFormat(self, value):
		"""
		Setter for **self.__filtersOutFormat** attribute.

		:param value: Attribute value.
		:type value: unicode
		"""

		if value is not None:
			assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
			"filtersOutFormat", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("filtersOutFormat", value)
		self.__filtersOutFormat = value

	@filtersOutFormat.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def filtersOutFormat(self):
		"""
		Deleter for **self.__filtersOutFormat** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "filtersOutFormat"))

	@property
	def defaultTarget(self):
		"""
		Property for **self.__defaultTarget** attribute.

		:return: self.__defaultTarget.
		:rtype: unicode
		"""

		return self.__defaultTarget

	@defaultTarget.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def defaultTarget(self, value):
		"""
		Setter for **self.__defaultTarget** attribute.

		:param value: Attribute value.
		:type value: unicode
		"""

		if value is not None:
			assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
			"defaultTarget", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("defaultTarget", value)
		self.__defaultTarget = value

	@defaultTarget.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def defaultTarget(self):
		"""
		Deleter for **self.__defaultTarget** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultTarget"))
	@property
	def targetsFormat(self):
		"""
		Property for **self.__targetsFormat** attribute.

		:return: self.__targetsFormat.
		:rtype: unicode
		"""

		return self.__targetsFormat

	@targetsFormat.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def targetsFormat(self, value):
		"""
		Setter for **self.__targetsFormat** attribute.

		:param value: Attribute value.
		:type value: unicode
		"""

		if value is not None:
			assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
			"targetsFormat", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("targetsFormat", value)
		self.__targetsFormat = value

	@targetsFormat.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def targetsFormat(self):
		"""
		Deleter for **self.__targetsFormat** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "targetsFormat"))

	@property
	def defaultLineNumberWidth(self):
		"""
		Property for **self.__defaultLineNumberWidth** attribute.

		:return: self.__defaultLineNumberWidth.
		:rtype: int
		"""

		return self.__defaultLineNumberWidth

	@defaultLineNumberWidth.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def defaultLineNumberWidth(self, value):
		"""
		Setter for **self.__defaultLineNumberWidth** attribute.

		:param value: Attribute value.
		:type value: int
		"""

		if value is not None:
			assert type(value) is int, "'{0}' attribute: '{1}' type is not 'int'!".format(
			"defaultLineNumberWidth", value)
			assert value > 0, "'{0}' attribute: '{1}' need to be exactly positive!".format("defaultLineNumberWidth", value)
		self.__defaultLineNumberWidth = value

	@defaultLineNumberWidth.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def defaultLineNumberWidth(self):
		"""
		Deleter for **self.__defaultLineNumberWidth** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultLineNumberWidth"))

	@property
	def defaultLineColor(self):
		"""
		Property for **self.__defaultLineColor** attribute.

		:return: self.__defaultLineColor.
		:rtype: QColor
		"""

		return self.__defaultLineColor

	@defaultLineColor.setter
	@foundations.exceptions.handleExceptions(AssertionError)
	def defaultLineColor(self, value):
		"""
		Setter for **self.__defaultLineColor** attribute.

		:param value: Attribute value.
		:type value: QColor
		"""

		if value is not None:
			assert type(value) is QColor, "'{0}' attribute: '{1}' type is not 'QColor'!".format("defaultLineColor", value)
		self.__defaultLineColor = value

	@defaultLineColor.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def defaultLineColor(self):
		"""
		Deleter for **self.__defaultLineColor** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultLineColor"))

	@property
	def ignoreHiddenFiles(self):
		"""
		Property for **self.__ignoreHiddenFiles** attribute.

		:return: self.__ignoreHiddenFiles.
		:rtype: bool
		"""

		return self.__ignoreHiddenFiles

	@ignoreHiddenFiles.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def ignoreHiddenFiles(self, value):
		"""
		Setter for **self.__ignoreHiddenFiles** attribute.

		:param value: Attribute value.
		:type value: bool
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "ignoreHiddenFiles"))

	@ignoreHiddenFiles.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def ignoreHiddenFiles(self):
		"""
		Deleter for **self.__ignoreHiddenFiles** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "ignoreHiddenFiles"))

	@property
	def searchWorkerThread(self):
		"""
		Property for **self.__searchWorkerThread** attribute.

		:return: self.__searchWorkerThread.
		:rtype: QThread
		"""

		return self.__searchWorkerThread

	@searchWorkerThread.setter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def searchWorkerThread(self, value):
		"""
		Setter for **self.__searchWorkerThread** attribute.

		:param value: Attribute value.
		:type value: QThread
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "searchWorkerThread"))

	@searchWorkerThread.deleter
	@foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
	def searchWorkerThread(self):
		"""
		Deleter for **self.__searchWorkerThread** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "searchWorkerThread"))

	#******************************************************************************************************************
	#***	Class methods
	#******************************************************************************************************************
	def show(self):
		"""
		Reimplements the :meth:`QWidget.show` method.
		"""

		selectedText = self.__container.getCurrentEditor().getSelectedText()
		selectedText and SearchAndReplace.insertPattern(selectedText, self.__searchPatternsModel)
		self.Search_comboBox.lineEdit().selectAll()
		self.Search_comboBox.setFocus()

		super(SearchInFiles, self).show()
		self.raise_()

	def closeEvent(self, event):
		"""
		Reimplements the :meth:`QWidget.closeEvent` method.

		:param event: QEvent.
		:type event: QEvent
		"""

		self.__interruptSearch()
		super(SearchInFiles, self).closeEvent(event)

	def __initializeUi(self):
		"""
		Initializes the Widget ui.
		"""

		umbra.ui.common.setWindowDefaultIcon(self)

		self.__model = SearchResultsModel(self)
		self.__delegate = RichText_QStyledItemDelegate(self)

		self.Search_Results_treeView.setParent(None)
		self.Search_Results_treeView = SearchResults_QTreeView(self,
															self.__model,
															message="No Search Result to view!")
		self.Search_Results_treeView.setItemDelegate(self.__delegate)
		self.Search_Results_treeView.setObjectName("Search_Results_treeView")
		self.Search_Results_frame_gridLayout.addWidget(self.Search_Results_treeView, 0, 0)
		self.__view = self.Search_Results_treeView
		self.__view.setContextMenuPolicy(Qt.ActionsContextMenu)
		self.__view_addActions()

		self.__searchPatternsModel = self.__container.searchAndReplace.searchPatternsModel
		self.Search_comboBox.setModel(self.__container.searchAndReplace.searchPatternsModel)
		self.Search_comboBox.setInsertPolicy(QComboBox.InsertAtTop)
		self.Search_comboBox.completer().setCaseSensitivity(Qt.CaseSensitive)

		self.__replaceWithPatternsModel = self.__container.searchAndReplace.replaceWithPatternsModel
		self.Replace_With_comboBox.setModel(self.__container.searchAndReplace.replaceWithPatternsModel)
		self.Replace_With_comboBox.setInsertPolicy(QComboBox.InsertAtTop)
		self.Replace_With_comboBox.completer().setCaseSensitivity(Qt.CaseSensitive)

		self.Where_lineEdit.setParent(None)
		self.Where_lineEdit = Search_QLineEdit(self)
		self.Where_lineEdit.setObjectName("Where_lineEdit")
		self.Where_frame_gridLayout.addWidget(self.Where_lineEdit, 0, 0)
		self.__locationsMenu = QMenu()
		for title, location in self.__locations.iteritems():
			self.__locationsMenu.addAction(self.__container.engine.actionsManager.registerAction(
			"Actions|Umbra|Components|factory.scriptEditor|Search In Files|{0}".format(title),
			text="{0}".format(title),
			slot=functools.partial(self.__addLocation, location)))
		self.Where_lineEdit.searchActiveLabel.setMenu(self.__locationsMenu)
		self.Where_lineEdit.setPlaceholderText("Use the magnifier to add locations!")

		self.installEventFilter(ValidationFilter(self))

		# Signals / Slots.
		self.__view.selectionModel().selectionChanged.connect(self.__view_selectionModel__selectionChanged)
		self.__view.doubleClicked.connect(self.__view__doubleClicked)
		self.__searchPatternsModel.patternInserted.connect(functools.partial(
		self.__patternsModel__patternInserted, self.Search_comboBox))
		self.__replaceWithPatternsModel.patternInserted.connect(functools.partial(
		self.__patternsModel__patternInserted, self.Replace_With_comboBox))
		self.Search_pushButton.clicked.connect(self.__Search_pushButton__clicked)
		self.Close_pushButton.clicked.connect(self.__Close_pushButton__clicked)

	def __view_addActions(self):
		"""
		Sets the View actions.
		"""

		self.__view.addAction(self.__container.engine.actionsManager.registerAction(
		"Actions|Umbra|Components|factory.scriptEditor|Search In Files|Replace All",
		slot=self.__view_replaceAllAction__triggered))
		self.__view.addAction(self.__container.engine.actionsManager.registerAction(
		"Actions|Umbra|Components|factory.scriptEditor|Search In Files|Replace Selected",
		slot=self.__view_replaceSelectedAction__triggered))
		separatorAction = QAction(self.__view)
		separatorAction.setSeparator(True)
		self.__view.addAction(separatorAction)
		self.__view.addAction(self.__container.engine.actionsManager.registerAction(
		"Actions|Umbra|Components|factory.scriptEditor|Search In Files|Save All",
		slot=self.__view_saveAllAction__triggered))
		self.__view.addAction(self.__container.engine.actionsManager.registerAction(
		"Actions|Umbra|Components|factory.scriptEditor|Search In Files|Save Selected",
		slot=self.__view_saveSelectedAction__triggered))

	def __view_replaceAllAction__triggered(self, checked):
		"""
		Defines the slot triggered by **'Actions|Umbra|Components|factory.scriptEditor|Search In Files|Replace All'** action.

		:param checked: Action checked state.
		:type checked: bool
		:return: Method success.
		:rtype: bool
		"""

		allNodes = filter(lambda x: x.family in ("SearchFile", "SearchOccurence"), self.__model.rootNode.children)
		if allNodes:
			return self.replace(allNodes)

	def __view_replaceSelectedAction__triggered(self, checked):
		"""
		Defines the slot triggered by **'Actions|Umbra|Components|factory.scriptEditor|Search In Files|Replace Selected'** action.

		:param checked: Action checked state.
		:type checked: bool
		:return: Method success.
		:rtype: bool
		"""

		selectedNodes = filter(lambda x: x.family in ("SearchFile", "SearchOccurence"), self.__view.getSelectedNodes())
		if selectedNodes:
			return self.replace(filter(lambda x: x.parent not in selectedNodes, selectedNodes))

	def __view_saveAllAction__triggered(self, checked):
		"""
		Defines the slot triggered by **'Actions|Umbra|Components|factory.scriptEditor|Search In Files|Save All'** action.

		:param checked: Action checked state.
		:type checked: bool
		:return: Method success.
		:rtype: bool
		"""

		allNodes = filter(lambda x: x.family is "ReplaceResult", self.__model.rootNode.children)
		if allNodes:
			return self.saveFiles(allNodes)

	def __view_saveSelectedAction__triggered(self, checked):
		"""
		Defines the slot triggered by **'Actions|Umbra|Components|factory.scriptEditor|Search In Files|Save Selected'** action.

		:param checked: Action checked state.
		:type checked: bool
		:return: Method success.
		:rtype: bool
		"""

		selectedNodes = filter(lambda x: x.family is "ReplaceResult", self.__view.getSelectedNodes())
		if selectedNodes:
			return self.saveFiles(selectedNodes)

	def __patternsModel__patternInserted(self, comboBox, index):
		"""
		Defines the slot triggered by a pattern when inserted into a patterns Model.

		:param comboBox: Pattern Model attached comboBox.
		:type comboBox: QComboBox
		:param index: Inserted pattern index.
		:type index: QModelIndex
		"""

		comboBox.setCurrentIndex(index.row())

	def __Search_pushButton__clicked(self, checked):
		"""
		Defines the slot triggered by **Search_pushButton** Widget when clicked.

		:param checked: Checked state.
		:type checked: bool
		"""

		self.search()

	def __Close_pushButton__clicked(self, checked):
		"""
		Defines the slot triggered by **Close_pushButton** Widget when clicked.

		:param checked: Checked state.
		:type checked: bool
		"""

		self.close()

	def __view__doubleClicked(self, index):
		"""
		Defines the slot triggered by a View when double clicked.

		:param index: Clicked item index.
		:type index: QModelIndex
		"""

		node = self.__model.getNode(index)

		if node.family == "SearchOccurence":
			file = node.parent.file
			occurence = node
		elif node.family in ("SearchFile", "ReplaceResult"):
			file = node.file
			occurence = None

		self.__highlightOccurence(file, occurence)

	def __view_selectionModel__selectionChanged(self, selectedItems, deselectedItems):
		"""
		Defines the slot triggered by the View **selectionModel** when selection changed.

		:param selectedItems: Selected items.
		:type selectedItems: QItemSelection
		:param deselectedItems: Deselected items.
		:type deselectedItems: QItemSelection
		"""

		indexes = selectedItems.indexes()
		if not indexes:
			return

		node = self.__model.getNode(indexes.pop())

		if node.family == "SearchOccurence":
			file = node.parent.file
			occurence = node
		elif node.family in ("SearchFile", "ReplaceResult"):
			file = node.file
			occurence = None

		if self.__container.getEditor(file):
			self.__highlightOccurence(file, occurence)

	def __searchWorkerThread__searchFinished(self, searchResults):
		"""
		Defines the slot triggered by :attr:`SearchInFiles.grepWorkerThread` attribute worker thread
		when the search is finished.

		:param searchResults: Search results.
		:type searchResults: list
		"""

		self.setSearchResults(searchResults)

		self.__container.engine.stopProcessing()
		metrics = self.__model.getMetrics()
		self.__container.engine.notificationsManager.notify(
		"{0} | '{1}' pattern occurence(s) found in '{2}' files!".format(self.__class__.__name__,
																	metrics["SearchOccurence"],
																	metrics["SearchFile"]))

	def __addLocation(self, type, *args):
		"""
		Defines the slot triggered by **Where_lineEdit** Widget when a context menu entry is clicked.

		:param type: Location type.
		:type type: unicode
		:param \*args: Arguments.
		:type \*args: \*
		"""

		if type == "directory":
			location = umbra.ui.common.storeLastBrowsedPath((QFileDialog.getExistingDirectory(self,
																						"Add Directory:",
																						RuntimeGlobals.lastBrowsedPath)))
		elif type == "file":
			location = umbra.ui.common.storeLastBrowsedPath((QFileDialog.getOpenFileName(self,
																						"Add File:",
																						RuntimeGlobals.lastBrowsedPath,
																						"All Files (*)")))
		elif type == "editors":
			location = self.__targetsFormat.format(self.__defaultTarget)
		elif type == "includeFilter":
			location = self.__filtersInFormat.format(self.__defaultFilterIn)
		elif type == "excludeFilter":
			location = self.__filtersOutFormat.format(self.__defaultFilterOut)

		location and self.Where_lineEdit.setText(", ".join(filter(bool, (foundations.strings.toString(
		self.Where_lineEdit.text()), location))))

	def __formatOccurence(self, occurence):
		"""
		Formats the given occurence and returns the matching rich html text.

		:param occurence: Occurence to format.
		:type occurence: Occurence
		:return: Rich text.
		:rtype: unicode
		"""

		color = "rgb({0}, {1}, {2})"
		spanFormat = "<span style=\"color: {0};\">{{0}}</span>".format(color.format(self.__defaultLineColor.red(),
																					self.__defaultLineColor.green(),
																					self.__defaultLineColor.blue()))
		line = foundations.strings.toString(occurence.text)
		start = spanFormat.format(line[:occurence.column])
		pattern = "<b>{0}</b>".format(line[occurence.column:occurence.column + occurence.length])
		end = spanFormat.format(line[occurence.column + occurence.length:])
		return "".join((start, pattern, end))

	def __formatReplaceMetrics(self, file, metrics):
		"""
		Formats the given replace metrics and returns the matching rich html text.

		:param file: File.
		:type file: unicode
		:param metrics: Replace metrics to format.
		:type metrics: unicode
		:return: Rich text.
		:rtype: unicode
		"""

		color = "rgb({0}, {1}, {2})"
		spanFormat = "<span style=\"color: {0};\">{{0}}</span>".format(color.format(self.__defaultLineColor.red(),
																					self.__defaultLineColor.green(),
																					self.__defaultLineColor.blue()))
		dirName, baseName = (os.path.dirname(file), os.path.basename(file))

		return "".join((spanFormat.format("'"),
						spanFormat.format(dirName),
						spanFormat.format(os.path.sep),
						baseName,
						spanFormat.format("' file: '"),
						foundations.strings.toString(metrics),
						spanFormat.format("' occurence(s) replaced!")))

	def __highlightOccurence(self, file, occurence):
		"""
		Highlights given file occurence.

		:param file: File containing the occurence.
		:type file: unicode
		:param occurence: Occurence to highlight.
		:type occurence: Occurence or SearchOccurenceNode
		"""

		if not self.__container.getEditor(file):
			cacheData = self.__filesCache.getContent(file)
			if cacheData:
				document = cacheData.document or self.__getDocument(cacheData.content)
				self.__container.loadDocument(document, file)
				self.__uncache(file)
			else:
				self.__container.loadFile(file)
		else:
			self.__container.setCurrentEditor(file)

		if not occurence:
			return

		cursor = self.__container.getCurrentEditor().textCursor()
		cursor.setPosition(occurence.position, QTextCursor.MoveAnchor)
		cursor.setPosition(occurence.position + occurence.length, QTextCursor.KeepAnchor)
		self.__container.getCurrentEditor().setTextCursor(cursor)

	def __getDocument(self, content):
		"""
		Returns a `QTextDocument <http://doc.qt.nokia.com/qtextdocument.html>`_ class instance
		with given content.

		:return: Document.
		:rtype: QTextDocument
		"""

		document = QTextDocument(QString(content))
		document.clearUndoRedoStacks()
		document.setModified(False)
		return document

	def __replaceWithinDocument(self, document, occurrences, replacementPattern):
		"""
		Replaces given pattern occurrences in given document using given settings.

		:param document: Document.
		:type document: QTextDocument
		:param replacementPattern: Replacement pattern.
		:type replacementPattern: unicode
		:return: Replaced occurrences count.
		:rtype: int
		"""

		cursor = QTextCursor(document)
		cursor.beginEditBlock()
		offset = count = 0
		for occurence in sorted(occurrences, key=lambda x: x.position):
			cursor.setPosition(offset + occurence.position, QTextCursor.MoveAnchor)
			cursor.setPosition(offset + occurence.position + occurence.length, QTextCursor.KeepAnchor)
			cursor.insertText(replacementPattern)
			offset += len(replacementPattern) - occurence.length
			count += 1
		cursor.endEditBlock()
		return count

	def __getSettings(self):
		"""
		Returns the current search and replace settings.

		:return: Settings.
		:rtype: dict
		"""

		return {"caseSensitive" : self.Case_Sensitive_checkBox.isChecked(),
				"wholeWord" : self.Whole_Word_checkBox.isChecked(),
				"regularExpressions" : self.Regular_Expressions_checkBox.isChecked()}

	def __interruptSearch(self):
		"""
		Interrupt the current search.
		"""

		if self.__searchWorkerThread:
			self.__searchWorkerThread.quit()
			self.__searchWorkerThread.wait()
			self.__container.engine.stopProcessing(warning=False)

	def __cache(self, file, content, document):
		"""
		Caches given file.

		:param file: File to cache.
		:type file: unicode
		:param content: File content.
		:type content: list
		:param document: File document.
		:type document: QTextDocument
		"""

		self.__filesCache.addContent(**{file : CacheData(content=content, document=document)})

	def __uncache(self, file):
		"""
		Uncaches given file.

		:param file: File to uncache.
		:type file: unicode
		"""

		if file in self.__filesCache:
			self.__filesCache.removeContent(file)

	def setSearchResults(self, searchResults):
		"""
		Sets the Model Nodes using given search results.

		:param searchResults: Search results.
		:type searchResults: list
		:return: Method success.
		:rtype: bool
		"""

		rootNode = umbra.ui.nodes.DefaultNode(name="InvisibleRootNode")
		for searchResult in searchResults:
			searchFileNode = SearchFileNode(name=searchResult.file,
											parent=rootNode)
			searchFileNode.update(searchResult)
			width = \
			max(self.__defaultLineNumberWidth,
			max([len(foundations.strings.toString(occurence.line)) for occurence in searchResult.occurrences]))
			for occurence in searchResult.occurrences:
				formatter = "{{0:>{0}}}".format(width)
				name = "{0}:{1}".format(formatter.format(occurence.line + 1).replace(" ", "&nbsp;"),
										self.__formatOccurence(occurence))
				searchOccurenceNode = SearchOccurenceNode(name=name,
														parent=searchFileNode)
				searchOccurenceNode.update(occurence)
		self.__model.initializeModel(rootNode)
		return True

	def setReplaceResults(self, replaceResults):
		"""
		Sets the Model Nodes using given replace results.

		:param replaceResults: Replace results.
		:type replaceResults: list
		:return: Method success.
		:rtype: bool
		"""

		rootNode = umbra.ui.nodes.DefaultNode(name="InvisibleRootNode")
		for file, metrics in sorted(replaceResults.iteritems()):
			replaceResultNode = ReplaceResultNode(name=self.__formatReplaceMetrics(file, metrics),
												parent=rootNode,
												file=file)
		self.__model.initializeModel(rootNode)
		return True

	def search(self):
		"""
		Searchs user defined locations for search pattern.

		:return: Method success.
		:rtype: bool
		"""

		self.__interruptSearch()

		searchPattern = self.Search_comboBox.currentText()
		replacementPattern = self.Replace_With_comboBox.currentText()
		if not searchPattern:
			return False

		SearchAndReplace.insertPattern(searchPattern, self.__searchPatternsModel)
		SearchAndReplace.insertPattern(replacementPattern, self.__replaceWithPatternsModel)

		location = umbra.ui.common.parseLocation(
		foundations.strings.toString(self.Where_lineEdit.text()) or \
		self.__targetsFormat.format(self.__defaultTarget))
		self.__ignoreHiddenFiles and location.filtersOut.append("\\\.|/\.")

		settings = self.__getSettings()

		self.__searchWorkerThread = Search_worker(self, searchPattern, location, settings)
		# Signals / Slots.
		self.__searchWorkerThread.searchFinished.connect(self.__searchWorkerThread__searchFinished)

		self.__container.engine.workerThreads.append(self.__searchWorkerThread)
		self.__container.engine.startProcessing("Searching In Files ...")
		self.__searchWorkerThread.start()
		return True

	def replace(self, nodes):
		"""
		Replaces user defined files search pattern occurrences with replacement pattern using given nodes.

		:param nodes: Nodes.
		:type nodes: list
		:return: Method success.
		:rtype: bool
		"""

		files = {}
		for node in nodes:
			if node.family == "SearchFile":
				files[node.file] = node.children
			elif node.family == "SearchOccurence":
				file = node.parent.file
				if not file in files:
					files[file] = []
				files[file].append(node)

		replacementPattern = self.Replace_With_comboBox.currentText()
		SearchAndReplace.insertPattern(replacementPattern, self.__replaceWithPatternsModel)

		replaceResults = {}
		for file, occurrences in files.iteritems():
			editor = self.__container.getEditor(file)
			if editor:
				document = editor.document()
			else:
				cacheData = self.__filesCache.getContent(file)
				if cacheData is None:
					LOGGER.warning(
					"!> {0} | '{1}' file doesn't exists in files cache!".format(self.__class__.__name__, file))
					continue

				content = self.__filesCache.getContent(file).content
				document = self.__getDocument(content)
				self.__cache(file, content, document)
			replaceResults[file] = self.__replaceWithinDocument(document, occurrences, replacementPattern)

		self.setReplaceResults(replaceResults)
		self.__container.engine.notificationsManager.notify(
		"{0} | '{1}' pattern occurence(s) replaced in '{2}' files!".format(self.__class__.__name__,
																	sum(replaceResults.values()),
																	len(replaceResults.keys())))

	def saveFiles(self, nodes):
		"""
		Saves user defined files using give nodes.

		:param nodes: Nodes.
		:type nodes: list
		:return: Method success.
		:rtype: bool
		"""

		metrics = {"Opened" : 0, "Cached" : 0}
		for node in nodes:
			file = node.file
			if self.__container.getEditor(file):
				if self.__container.saveFile(file):
					metrics["Opened"] += 1
					self.__uncache(file)
			else:
				cacheData = self.__filesCache.getContent(file)
				if cacheData is None:
					LOGGER.warning(
					"!> {0} | '{1}' file doesn't exists in files cache!".format(self.__class__.__name__, file))
					continue

				if cacheData.document:
					fileHandle = File(file)
					fileHandle.content = [cacheData.document.toPlainText().toUtf8()]
					if fileHandle.write():
						metrics["Cached"] += 1
						self.__uncache(file)
				else:
					LOGGER.warning(
					"!> {0} | '{1}' file document doesn't exists in files cache!".format(self.__class__.__name__, file))

		self.__container.engine.notificationsManager.notify(
		"{0} | '{1}' opened file(s) and '{2}' cached file(s) saved!".format(self.__class__.__name__,
																		metrics["Opened"],
																		metrics["Cached"]))
示例#25
0
    def __init__(self, iface, geometry, mntButton=False, zerosButton=False):
        """
        Constructor
        :param iface: interface
        :param width: dock widget geometry
        """
        QDockWidget.__init__(self)
        self.setWindowTitle(QCoreApplication.translate("VDLTools", "Profile Tool"))
        self.__iface = iface
        self.__geom = geometry
        self.__canvas = self.__iface.mapCanvas()
        self.__types = ['PDF', 'PNG']  # ], 'SVG', 'PS']
        self.__libs = []
        if Qwt5_loaded:
            self.__lib = 'Qwt5'
            self.__libs.append('Qwt5')
            if matplotlib_loaded:
                self.__libs.append('Matplotlib')
        elif matplotlib_loaded:
            self.__lib = 'Matplotlib'
            self.__libs.append('Matplotlib')
        else:
            self.__lib = None
            self.__iface.messageBar().pushMessage(
                QCoreApplication.translate("VDLTools", "No graph lib available (qwt5 or matplotlib)"),
                level=QgsMessageBar.CRITICAL, duration=0)

        self.__doTracking = False
        self.__vline = None

        self.__profiles = None
        self.__numLines = None
        self.__mntPoints = None

        self.__marker = None
        self.__tabmouseevent = None

        if self.__geom is not None:
            self.setGeometry(self.__geom)

        self.__contentWidget = QWidget()
        self.setWidget(self.__contentWidget)

        self.__boxLayout = QHBoxLayout()
        self.__contentWidget.setLayout(self.__boxLayout)

        self.__plotFrame = QFrame()
        self.__frameLayout = QHBoxLayout()
        self.__plotFrame.setLayout(self.__frameLayout)

        self.__printLayout = QHBoxLayout()
        self.__printLayout.addWidget(self.__plotFrame)

        self.__legendLayout = QVBoxLayout()
        self.__printLayout.addLayout(self.__legendLayout)

        self.__printWdg = QWidget()
        self.__printWdg.setLayout(self.__printLayout)

        self.__plotWdg = None
        self.__changePlotWidget()

        size = QSize(150, 20)

        self.__boxLayout.addWidget(self.__printWdg)

        self.__vertLayout = QVBoxLayout()

        self.__libCombo = QComboBox()
        self.__libCombo.setFixedSize(size)
        self.__libCombo.addItems(self.__libs)
        self.__vertLayout.addWidget(self.__libCombo)
        self.__libCombo.currentIndexChanged.connect(self.__setLib)

        if mntButton:
            self.__displayMnt = False
            self.__mntButton = QPushButton(QCoreApplication.translate("VDLTools", "Display MNT"))
            self.__mntButton.setFixedSize(size)
            self.__mntButton.clicked.connect(self.__mnt)
            self.__vertLayout.addWidget(self.__mntButton)

        if zerosButton:
            self.__displayZeros = False
            self.__zerosButton = QPushButton(QCoreApplication.translate("VDLTools", "Display Zeros"))
            self.__zerosButton.setFixedSize(size)
            self.__zerosButton.clicked.connect(self.__zeros)
            self.__vertLayout.addWidget(self.__zerosButton)
        else:
            self.__displayZeros = True

        self.__maxLabel = QLabel("y max")
        self.__maxLabel.setFixedSize(size)
        self.__vertLayout.addWidget(self.__maxLabel)
        self.__maxSpin = QSpinBox()
        self.__maxSpin.setFixedSize(size)
        self.__maxSpin.setRange(-10000, 10000)
        self.__maxSpin.valueChanged.connect(self.__reScalePlot)
        self.__vertLayout.addWidget(self.__maxSpin)
        self.__vertLayout.insertSpacing(10, 20)

        self.__minLabel = QLabel("y min")
        self.__minLabel.setFixedSize(size)
        self.__vertLayout.addWidget(self.__minLabel)
        self.__minSpin = QSpinBox()
        self.__minSpin.setFixedSize(size)
        self.__minSpin.setRange(-10000, 10000)
        self.__minSpin.valueChanged.connect(self.__reScalePlot)
        self.__vertLayout.addWidget(self.__minSpin)
        self.__vertLayout.insertSpacing(10, 40)

        self.__typeCombo = QComboBox()
        self.__typeCombo.setFixedSize(size)
        self.__typeCombo.addItems(self.__types)
        self.__vertLayout.addWidget(self.__typeCombo)
        self.__saveButton = QPushButton(QCoreApplication.translate("VDLTools", "Save"))
        self.__saveButton.setFixedSize(size)
        self.__saveButton.clicked.connect(self.__save)
        self.__vertLayout.addWidget(self.__saveButton)

        self.__boxLayout.addLayout(self.__vertLayout)

        self.__maxSpin.setEnabled(False)
        self.__minSpin.setEnabled(False)

        self.__colors = []
        for cn in QColor.colorNames():
            qc = QColor(cn)
            val = qc.red() + qc.green() + qc.blue()
            if 0 < val < 450:
                self.__colors.append(cn)
示例#26
0
class Bezier(JObject):
	def __init__(self):
		JObject.__init__(self)
		self._control_points = []
		self._qGray = QColor(100,100,100)
		self._qRed = QColor(245, 66, 78)

		p1 = JCircle(40)
		p1.setVisibility(False)
		p1.setColor(self._qGray)

		p2 = JCircle(40)
		p2.setVisibility(False)
		p2.setColor(self._qGray)

		p3 = JCircle(40)
		p3.setVisibility(False)
		p3.setColor(self._qGray)

		p4 = JCircle(40)
		p4.setVisibility(False)
		p4.setColor(self._qGray)


		self._control_points.append(p1)
		self._control_points.append(p2)
		self._control_points.append(p3)
		self._control_points.append(p4)

	# Trasla solo i due punti di controllo centrali
	def translate_2central_points(self, tx, ty):
		self._control_points[1].translate(tx, ty)
		self._control_points[2].translate(tx, ty)


	def get_selected(self, x, y):
		result = None

		if self._visible:
			for control_point in self._control_points:
				if control_point.isSelected(x, y):
					result = control_point
					break

		return result

	def paint(self, paintHidden=False):
		self.setOpenGlColor()
		if self.getVisibility() or paintHidden:
			points = []
			for control_point in self._control_points:
				points.append(control_point.getCenter())
				control_point.paint(paintHidden)

			if paintHidden:
				glColor3f(self._qGray.red()/255.0, self._qGray.green()/255.0, self._qGray.blue()/255.0 )
				# Visualizza le linee di controllo
				glBegin(GL_LINE_STRIP)
				for p in points:
					glVertex2f(p.getX(), p.getY())
				glEnd()

			glColor3f(self._qRed.red()/255.0, self._qRed.green()/255.0, self._qRed.blue()/255.0 )
			glBegin(GL_LINE_STRIP)

			for i in range(0, 100):
				t = i / 100.0
				# Formula parametrica della Curva di Bezier cubica
				p = points[0]*(1-t)**3 + points[1]*3*t*(1-t)**2 + points[2]*3*t**2*(1-t) + points[3]*t**3
				glVertex2f(p.getX(), p.getY())
			glEnd()
示例#27
0
    def typeChanged(self, index):
        """
            Type is changed, index is the new selected index
        """

        self.ui.view.clear()

        # If nothing is selected
        if index < 0:
            self.ui.title_label.setEnabled(False)
            self.ui.title.setEnabled(False)
            self.ui.title.setText('')
            self.ui.view_label.hide()
            self.ui.view.hide()
            self.ui.color_label.setEnabled(False)
            self.ui.color_button.setEnabled(False)
            self.ui.firewall.setEnabled(False)
            self.ui.firewall_label.setEnabled(False)
            self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
            self._set_args(False)
            return

        fragtypename = unicode(self.ui.type.itemData(index).toString())
        fragtype = frag_types[fragtypename]
        if not self.fragment or self.fragment.type != fragtypename:
#            self.window.user_settings.removeFragment(self.fragment)
            self.fragment = self.window.user_settings.createFragment(fragtypename, False)

        self.ui.title_label.setEnabled(True)
        self.ui.title.setEnabled(True)
        self.ui.title.setText(fragtype.title)
        self.ui.view_label.setEnabled(True)
        self.ui.view.setEnabled(True)
        self.ui.color_label.setEnabled(True)
        self.ui.color_button.setEnabled(True)
        self.ui.firewall.setEnabled(True)
        self.ui.firewall_label.setEnabled(True)

        # Add views related to this fragment type.
        for view in fragtype.views:
#            if not views_list.has_key(view):
#                continue
            if not isinstance(view, GraphicsView):
                continue
#            self.ui.view.addItem(views_list[view].name(), QVariant(view))
            self.ui.view.addItem(view.name(), QVariant(view))

        if len(fragtype.views) > 1:
            self.ui.view_label.show()
            self.ui.view.show()
        else:
            self.ui.view_label.hide()
            self.ui.view.hide()

        # Set the fragment background color
        color = QColor(self.fragment.background_color)
        self.ui.color.setStyleSheet('background-color: rgb(%d, %d, %d)' % (color.red(), color.green(), color.blue()))

        # Firewall
        i = self.ui.firewall.findData(QVariant(self.fragment.firewall))
        self.ui.firewall.setCurrentIndex(i)

        self._set_args()

        self.ui.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
示例#28
0
	def __drawAxes(self, painter):
		"""
		Pozor, tato metoda vracia nove velkosti X a Y pretoze pri kresleni osi
		sa rata aj s velkostou textu ktora je variabilna
		"""

		palette = QPalette()
		penColor = QColor(palette.color(QPalette.WindowText))
		ciara = QPen(penColor)
		pozadieBaseColor = QColor(palette.color(QPalette.Base))
		pozadieMixColor = QColor(90, 150, 250);
		red   = (pozadieBaseColor.red() * 4 + pozadieMixColor.red()) / 5
		green = (pozadieBaseColor.green() * 4 + pozadieMixColor.green()) / 5
		blue  = (pozadieBaseColor.blue() * 4 + pozadieMixColor.blue()) / 5
		pozadieColor = QColor(red, green, blue);
		pozadie = QBrush(pozadieColor)

		painter.setPen(ciara)
		painter.setBrush(pozadie)

		xVelkost = self.width() - (2 * self.__padding)
		yVelkost = self.height() - (2 * self.__padding)
		xOs = self.__calcAxesData(xVelkost, self.__xMedzery, self.__minDay, self.__maxDay)
		yOs = self.__calcAxesData(yVelkost, self.__yMedzery, self.__minPoints, self.__maxPoints)

		xText = self.__convertXData(xOs)
		yText = self.__convertYData(yOs)

		(xxText, xyText) = self.__calcMaxTextSize(self.font(), xText)
		(yxText, yyText) = self.__calcMaxTextSize(self.font(), yText)

		xVelkost = xVelkost - yxText
		yVelkost = yVelkost - xyText

		painter.translate(yxText + 5, 5)
		rect = QRect(0, 0, xVelkost, yVelkost)
		painter.drawRect(rect)

		penColor.setAlpha(60)
		painter.setPen(QPen(penColor))

		for hodnota in yOs:
			y = self.__getYCoord(yVelkost, hodnota)
			painter.drawLine(0, y, xVelkost, y)
		for hodnota in xOs:
			x = self.__getXCoord(xVelkost, hodnota)
			painter.drawLine(x, 0, x, yVelkost)

		painter.setPen(palette.color(QPalette.WindowText))

		for i in range(len(yText)):
			hodnota = yOs[i]
			text = yText[i]
			y = self.__getYCoord(yVelkost, hodnota)
			textRect = QRect(-yxText-3, y - yyText / 2, yxText, yyText)
			painter.drawText(textRect, Qt.AlignRight, text)
		for i in range(len(xText)):
			hodnota = xOs[i]
			text = xText[i]
			x = self.__getXCoord(xVelkost, hodnota)
			textRect = QRect(x - xxText / 2, yVelkost + xyText / 2, xxText, xyText)
			painter.drawText(textRect, Qt.AlignHCenter, text)
		return (xVelkost, yVelkost)
示例#29
0
    def __init__(self, iface):
        """
        Constructor
        :param iface: interface
        """
        QDockWidget.__init__(self)
        self.setWindowTitle(QCoreApplication.translate("VDLTools", "Profile Tool"))
        self.resize(1024, 400)
        self.__iface = iface
        self.__canvas = self.__iface.mapCanvas()
        self.__types = ['PDF', 'PNG']  # ], 'SVG', 'PS']
        self.__libs = []
        if Qwt5_loaded:
            self.__lib = 'Qwt5'
            self.__libs.append('Qwt5')
            if matplotlib_loaded:
                self.__libs.append('Matplotlib')
        elif matplotlib_loaded:
            self.__lib = 'Matplotlib'
            self.__libs.append('Matplotlib')
        else:
            self.__lib = None
            self.__iface.messageBar().pushMessage(
                QCoreApplication.translate("VDLTools", "No graph lib available (qwt5 or matplotlib)"),
                level=QgsMessageBar.CRITICAL, duration=0)

        self.__doTracking = False
        self.__vline = None

        self.__profiles = None
        self.__numLines = None
        self.__mntPoints = None

        self.__marker = None
        self.__tabmouseevent = None

        self.__contentWidget = QWidget()
        self.setWidget(self.__contentWidget)

        self.__boxLayout = QHBoxLayout()
        self.__contentWidget.setLayout(self.__boxLayout)

        self.__plotFrame = QFrame()
        self.__frameLayout = QHBoxLayout()
        self.__plotFrame.setLayout(self.__frameLayout)

        self.__printLayout = QHBoxLayout()
        self.__printLayout.addWidget(self.__plotFrame)

        self.__legendLayout = QVBoxLayout()
        self.__printLayout.addLayout(self.__legendLayout)

        self.__printWdg = QWidget()
        self.__printWdg.setLayout(self.__printLayout)

        self.__plotWdg = None
        self.__changePlotWidget()

        size = QSize(150, 20)

        self.__boxLayout.addWidget(self.__printWdg)

        self.__vertLayout = QVBoxLayout()

        self.__libCombo = QComboBox()
        self.__libCombo.setFixedSize(size)
        self.__libCombo.addItems(self.__libs)
        self.__vertLayout.addWidget(self.__libCombo)
        self.__libCombo.currentIndexChanged.connect(self.__setLib)

        self.__maxLabel = QLabel("y max")
        self.__maxLabel.setFixedSize(size)
        self.__vertLayout.addWidget(self.__maxLabel)
        self.__maxSpin = QSpinBox()
        self.__maxSpin.setFixedSize(size)
        self.__maxSpin.setRange(-10000, 10000)
        self.__maxSpin.valueChanged.connect(self.__reScalePlot)
        self.__vertLayout.addWidget(self.__maxSpin)
        self.__vertLayout.insertSpacing(10, 20)

        self.__minLabel = QLabel("y min")
        self.__minLabel.setFixedSize(size)
        self.__vertLayout.addWidget(self.__minLabel)
        self.__minSpin = QSpinBox()
        self.__minSpin.setFixedSize(size)
        self.__minSpin.setRange(-10000, 10000)
        self.__minSpin.valueChanged.connect(self.__reScalePlot)
        self.__vertLayout.addWidget(self.__minSpin)
        self.__vertLayout.insertSpacing(10, 40)

        self.__typeCombo = QComboBox()
        self.__typeCombo.setFixedSize(size)
        self.__typeCombo.addItems(self.__types)
        self.__vertLayout.addWidget(self.__typeCombo)
        self.__saveButton = QPushButton(QCoreApplication.translate("VDLTools", "Save"))
        self.__saveButton.setFixedSize(size)
        self.__saveButton.clicked.connect(self.__save)
        self.__vertLayout.addWidget(self.__saveButton)

        self.__boxLayout.addLayout(self.__vertLayout)

        self.__maxSpin.setEnabled(False)
        self.__minSpin.setEnabled(False)

        self.__colors = []
        for cn in QColor.colorNames():
            qc = QColor(cn)
            val = qc.red() + qc.green() + qc.blue()
            if 0 < val < 450:
                self.__colors.append(cn)
示例#30
0
    def attachCurves(self, names, settings, usedMnts):
        """
        To attach the curves for the layers to the profile
        :param names: layers names
        """
        if (self.__profiles is None) or (self.__profiles == 0):
            return

        self.__getLinearPoints()
        if usedMnts is not None and (usedMnts[0] or usedMnts[1] or usedMnts[2]):
            self.__getMnt(settings)

        c = 0

        if self.__mntPoints is not None:
                for p in range(len(self.__mntPoints[0])):
                    if usedMnts[p]:
                        legend = QLabel("<font color='" + self.__colors[c] + "'>" + self.__mntPoints[0][p]
                                        + "</font>")
                        self.__legendLayout.addWidget(legend)

                        if self.__lib == 'Qwt5':

                            xx = [list(g) for k, g in itertools.groupby(self.__mntPoints[1],
                                                                        lambda x: x is None) if not k]
                            yy = [list(g) for k, g in itertools.groupby(self.__mntPoints[2][p], lambda x: x is None)
                                  if not k]

                            for j in range(len(xx)):
                                curve = QwtPlotCurve(self.__mntPoints[0][p])
                                curve.setData(xx[j], yy[j])
                                curve.setPen(QPen(QColor(self.__colors[c]), 3))
                                curve.attach(self.__plotWdg)

                        elif self.__lib == 'Matplotlib':
                            qcol = QColor(self.__colors[c])
                            self.__plotWdg.figure.get_axes()[0].plot(self.__mntPoints[1], self.__mntPoints[2][p],
                                                                     gid=self.__mntPoints[0][p], linewidth=3)
                            tmp = self.__plotWdg.figure.get_axes()[0].get_lines()
                            for t in range(len(tmp)):
                                if self.__mntPoints[0][p] == tmp[t].get_gid():
                                    tmp[c].set_color((old_div(qcol.red(), 255.0), old_div(qcol.green(), 255.0),
                                                      old_div(qcol.blue(), 255.0), old_div(qcol.alpha(), 255.0)))
                                    self.__plotWdg.draw()
                                    break
                        c += 1

        if 'z' in self.__profiles[0]:
            for i in range(len(self.__profiles[0]['z'])):
                if i < self.__numLines:
                    v = 0
                else:
                    v = i - self.__numLines + 1
                name = names[v]
                xx = []
                yy = []
                for prof in self.__profiles:
                    xx.append(prof['l'])
                    yy.append(prof['z'][i])

                for j in range(len(yy)):
                    if yy[j] is None:
                        xx[j] = None

                if i == 0 or i > (self.__numLines-1):
                    legend = QLabel("<font color='" + self.__colors[c] + "'>" + name + "</font>")
                    self.__legendLayout.addWidget(legend)

                if self.__lib == 'Qwt5':

                    # Split xx and yy into single lines at None values
                    xx = [list(g) for k, g in itertools.groupby(xx, lambda x: x is None) if not k]
                    yy = [list(g) for k, g in itertools.groupby(yy, lambda x: x is None) if not k]

                    # Create & attach one QwtPlotCurve per one single line
                    for j in range(len(xx)):
                        curve = QwtPlotCurve(name)
                        curve.setData(xx[j], yy[j])
                        curve.setPen(QPen(QColor(self.__colors[c]), 3))
                        if i > (self.__numLines-1):
                            curve.setStyle(QwtPlotCurve.Dots)
                            pen = QPen(QColor(self.__colors[c]), 8)
                            pen.setCapStyle(Qt.RoundCap)
                            curve.setPen(pen)
                        curve.attach(self.__plotWdg)

                elif self.__lib == 'Matplotlib':
                    qcol = QColor(self.__colors[c])
                    if i < self.__numLines:
                        self.__plotWdg.figure.get_axes()[0].plot(xx, yy, gid=name, linewidth=3)
                    else:
                        self.__plotWdg.figure.get_axes()[0].plot(xx, yy, gid=name, linewidth=5, marker='o',
                                                                 linestyle='None')
                    tmp = self.__plotWdg.figure.get_axes()[0].get_lines()
                    for t in range(len(tmp)):
                        if name == tmp[t].get_gid():
                            tmp[c].set_color((old_div(qcol.red(), 255.0), old_div(qcol.green(), 255.0),
                                              old_div(qcol.blue(), 255.0), old_div(qcol.alpha(), 255.0)))
                            self.__plotWdg.draw()
                            break
                c += 1

        # scaling this
        try:
            self.__reScalePlot(None, True)
        except:
            self.__iface.messageBar().pushMessage(
                QCoreApplication.translate("VDLTools", "Rescale problem... (trace printed)"),
                level=QgsMessageBar.CRITICAL, duration=0)
            print(
                QCoreApplication.translate("VDLTools", "rescale problem : "), sys.exc_info()[0], traceback.format_exc())
        if self.__lib == 'Qwt5':
            self.__plotWdg.replot()
        elif self.__lib == 'Matplotlib':
            self.__plotWdg.figure.get_axes()[0].redraw_in_frame()
            self.__plotWdg.draw()
            self.__activateMouseTracking(True)
            self.__marker.show()
示例#31
0
    def attachCurves(self, names, settings, usedMnts):
        """
        To attach the curves for the layers to the profile
        :param names: layers names
        """
        if (self.__profiles is None) or (self.__profiles == 0):
            return

        self.__getLinearPoints()
        if usedMnts is not None and (usedMnts[0] or usedMnts[1] or usedMnts[2]):
            self.__getMnt(settings)

        c = 0

        if self.__mntPoints is not None:
                for p in range(len(self.__mntPoints[0])):
                    if usedMnts[p]:
                        legend = QLabel("<font color='" + self.__colors[c] + "'>" + self.__mntPoints[0][p]
                                        + "</font>")
                        self.__legendLayout.addWidget(legend)

                        if self.__lib == 'Qwt5':

                            xx = [list(g) for k, g in itertools.groupby(self.__mntPoints[1],
                                                                        lambda x: x is None) if not k]
                            yy = [list(g) for k, g in itertools.groupby(self.__mntPoints[2][p], lambda x: x is None)
                                  if not k]

                            for j in range(len(xx)):
                                curve = QwtPlotCurve(self.__mntPoints[0][p])
                                curve.setData(xx[j], yy[j])
                                curve.setPen(QPen(QColor(self.__colors[c]), 3))
                                curve.attach(self.__plotWdg)

                        elif self.__lib == 'Matplotlib':
                            qcol = QColor(self.__colors[c])
                            self.__plotWdg.figure.get_axes()[0].plot(self.__mntPoints[1], self.__mntPoints[2][p],
                                                                     gid=self.__mntPoints[0][p], linewidth=3)
                            tmp = self.__plotWdg.figure.get_axes()[0].get_lines()
                            for t in range(len(tmp)):
                                if self.__mntPoints[0][p] == tmp[t].get_gid():
                                    tmp[c].set_color((old_div(qcol.red(), 255.0), old_div(qcol.green(), 255.0),
                                                      old_div(qcol.blue(), 255.0), old_div(qcol.alpha(), 255.0)))
                                    self.__plotWdg.draw()
                                    break
                        c += 1

        if 'z' in self.__profiles[0]:
            for i in range(len(self.__profiles[0]['z'])):
                if i < self.__numLines:
                    v = 0
                else:
                    v = i - self.__numLines + 1
                name = names[v]
                xx = []
                yy = []
                for prof in self.__profiles:
                    xx.append(prof['l'])
                    yy.append(prof['z'][i])

                for j in range(len(yy)):
                    if yy[j] is None:
                        xx[j] = None

                if i == 0 or i > (self.__numLines-1):
                    legend = QLabel("<font color='" + self.__colors[c] + "'>" + name + "</font>")
                    self.__legendLayout.addWidget(legend)

                if self.__lib == 'Qwt5':

                    # Split xx and yy into single lines at None values
                    xx = [list(g) for k, g in itertools.groupby(xx, lambda x: x is None) if not k]
                    yy = [list(g) for k, g in itertools.groupby(yy, lambda x: x is None) if not k]

                    # Create & attach one QwtPlotCurve per one single line
                    for j in range(len(xx)):
                        curve = QwtPlotCurve(name)
                        curve.setData(xx[j], yy[j])
                        curve.setPen(QPen(QColor(self.__colors[c]), 3))
                        if i > (self.__numLines-1):
                            curve.setStyle(QwtPlotCurve.Dots)
                            pen = QPen(QColor(self.__colors[c]), 8)
                            pen.setCapStyle(Qt.RoundCap)
                            curve.setPen(pen)
                        curve.attach(self.__plotWdg)

                elif self.__lib == 'Matplotlib':
                    qcol = QColor(self.__colors[c])
                    if i < self.__numLines:
                        self.__plotWdg.figure.get_axes()[0].plot(xx, yy, gid=name, linewidth=3)
                    else:
                        self.__plotWdg.figure.get_axes()[0].plot(xx, yy, gid=name, linewidth=5, marker='o',
                                                                 linestyle='None')
                    tmp = self.__plotWdg.figure.get_axes()[0].get_lines()
                    for t in range(len(tmp)):
                        if name == tmp[t].get_gid():
                            tmp[c].set_color((old_div(qcol.red(), 255.0), old_div(qcol.green(), 255.0),
                                              old_div(qcol.blue(), 255.0), old_div(qcol.alpha(), 255.0)))
                            self.__plotWdg.draw()
                            break
                c += 1

        # scaling this
        try:
            self.__reScalePlot(None, True)
        except:
            self.__iface.messageBar().pushMessage(
                QCoreApplication.translate("VDLTools", "Rescale problem... (trace printed)"),
                level=QgsMessageBar.CRITICAL, duration=0)
            print(sys.exc_info()[0], traceback.format_exc())
        if self.__lib == 'Qwt5':
            self.__plotWdg.replot()
        elif self.__lib == 'Matplotlib':
            self.__plotWdg.figure.get_axes()[0].redraw_in_frame()
            self.__plotWdg.draw()
            self.__activateMouseTracking(True)
            self.__marker.show()
示例#32
0
class OIBlock(QWidget):
    border_color = QColor(137, 117, 89)
    padding = 0.05
    radius = 0.08

    def __init__(self, block, parent):
        QWidget.__init__(self, parent)
        self.__nodes = []
        self.__block = block
        self._resizable = True
        self.__block.repaint.connect(self.repaint)
        self._bg_color = QColor(159, 160, 144, 255)
        self._fg_color = QColor(255, 255, 255)
        self.setGeometry(block.get_geometry(Info.dpi))
        self.__action = Action.NONE
        self.__status = Mode.EDIT_LOGIC
        self.__corner_path = None
        self.__origin = None
        self.__translation = QPoint()
        if self._resizable:
            self.__init_corner()
        self.__init_nodes()
        self.__init_listeners()
        self.setMouseTracking(True)

    def __init_nodes(self):
        y = .45
        x = .01
        for k in self.__block.inputs:
            i = self.__block.inputs[k]
            n = OINode(QPointF(x, y), Alignment.Left, i)
            self.__nodes.append(n)
            y += 0.05 + n.size
        x = self.width() / Info.dpi - .12
        y = 0.45
        for k in self.__block.outputs:
            o = self.__block.outputs[k]
            n = OINode(QPointF(x, y), Alignment.Right, o)
            self.__nodes.append(n)
            y += .05 + n.size

    def __init_listeners(self):
        self.__block.selected.connect(self.select)
        self.__block.settings['Width'].value_update.connect(
            self.geometry_update)
        self.__block.settings['Height'].value_update.connect(
            self.geometry_update)
        self.__block.settings['X'].value_update.connect(self.geometry_update)
        self.__block.settings['Y'].value_update.connect(self.geometry_update)

    def select(self, val: bool):
        if val:
            effect = QGraphicsDropShadowEffect()
            effect.setBlurRadius(20)
            effect.setXOffset(0)
            effect.setYOffset(0)
            effect.setColor(QColor(0, 0, 0, 180))
            self.setGraphicsEffect(effect)
            self.raise_()
        else:
            eff = self.graphicsEffect()
            del eff
            self.setGraphicsEffect(None)

    def geometry_update(self):
        r = self.__block.get_geometry(Info.dpi)
        r.translate(self.__translation)
        self.setGeometry(r)
        self.__update_nodes()

    def __update_nodes(self):
        x = self.width() / Info.dpi - .12
        for n in self.__nodes:
            if n.alignment == Alignment.Right:
                y = n.pos.y()
                n.pos = QPointF(x, y)
        self.repaint()

    def selected(self):
        return self.__block.is_selected()

    def bg(self):
        return self._bg_color

    def title_bg(self):
        return self._bg_color.light(80)

    def block(self):
        return self.__block

    def _paint(self, p: QPainter):
        self._paint_bg(p)
        self._paint_title(p)
        p.setPen(QPen(self.pen().brush(), 0.01 * Info.dpi))
        self._paint_nodes(p)
        # self._paint_outs(p)
        # self._paint_content(p)

    def pen(self):
        p = QPen(
            OIBlock.border_color.lighter().lighter()
            if self.selected() else OIBlock.border_color, .02 * Info.dpi)
        return p

    def _paint_bg(self, p: QPainter):
        dpi = Info.dpi
        pen = self.pen()
        p.setRenderHint(QPainter.Antialiasing, True)
        p.setPen(pen)
        p.setBrush(self.bg())
        p.drawRoundedRect(OIBlock.padding * dpi, OIBlock.padding * dpi,
                          self.width() - 2 * OIBlock.padding * dpi,
                          self.height() - 2 * OIBlock.padding * dpi,
                          OIBlock.radius * dpi, OIBlock.radius * dpi)
        p.setBrush(self.title_bg())
        p.drawRoundedRect(OIBlock.padding * dpi, OIBlock.padding * dpi,
                          self.width() - 2 * OIBlock.padding * dpi,
                          .35 * dpi + OIBlock.padding * dpi,
                          OIBlock.radius * dpi, OIBlock.radius * dpi)
        p.setBrush(self.bg())
        p.setPen(QColor(0, 0, 0, 0))
        p.drawRect(0.01 * dpi + OIBlock.padding * dpi,
                   0.35 * dpi + OIBlock.padding * dpi,
                   self.width() - 0.02 * dpi - 2 * OIBlock.padding * dpi,
                   0.10 * dpi)
        p.setPen(pen)
        if self._resizable:
            if self.__corner_path is None:
                self.__init_corner()
            p.setBrush(pen.brush())
            p.drawPath(
                self.__corner_path.translated(self.width(), self.height()))

    def _paint_title(self, p: QPainter):
        dpi = Info.dpi
        p.drawLine(OIBlock.padding * dpi, 0.35 * dpi + OIBlock.padding * dpi,
                   self.width() - (0.01 + OIBlock.padding) * dpi,
                   0.35 * dpi + OIBlock.padding * dpi)
        p.setPen(self._fg_color)
        f = p.font()
        f.setPointSize(10)
        f.setBold(True)
        p.setFont(f)
        p.drawText(
            QRectF((0.04 + OIBlock.padding) * dpi,
                   (OIBlock.padding + .01) * dpi,
                   self.width() - .12 * dpi, .25 * dpi),
            str(self.__block.name()))
        f.setBold(False)
        f.setPointSize(8)
        p.setPen(
            QColor(self._fg_color.red(), self._fg_color.green(),
                   self._fg_color.blue(), 100))
        p.setFont(f)
        p.drawText(
            QRectF((.04 + OIBlock.padding) * dpi,
                   (.17 + OIBlock.padding) * dpi,
                   self.width() - .12 * dpi, .15 * dpi),
            str(self.__block.type_name()))

    def __init_corner(self):
        path = QPainterPath()
        dpi = Info.dpi
        path.moveTo(-OIBlock.padding * 1.2 * dpi,
                    (-.15 - OIBlock.padding * 1.2) * dpi)
        path.lineTo((-.15 - OIBlock.padding * 1.2) * dpi,
                    -OIBlock.padding * 1.2 * dpi)
        path.lineTo(-OIBlock.padding * 1.2 * dpi, -OIBlock.padding * 1.2 * dpi)
        path.closeSubpath()
        self.__corner_path = path

    def _paint_nodes(self, p: QPainter):
        for n in self.__nodes:
            n.paint(p)
        return

    def _paint_content(self, p: QPainter):
        # nothing to do
        return

    def paintEvent(self, e: QPaintEvent):
        if e.isAccepted():
            p = QPainter(self)
            self._paint(p)

    def _check_corner(self, pos):
        path = self.__corner_path.translated(self.width(), self.height())
        return path.contains(pos)

    def _check_action(self, action):
        if self.__action != Action.NONE and action != Action.NONE:
            return False
        return True

    def _check_nodes(self, p: QPoint):
        for n in self.__nodes:
            if n.contains(p):
                return n
        return None

    def mousePressEvent(self, e: QMouseEvent):
        self.__block.select()
        n = self._check_nodes(e.pos())
        if n is not None:
            print('Node found')
            return
        if e.button() == Qt.LeftButton:
            if self._resizable:
                if self._check_corner(e.pos()) and self._check_action(
                        Action.RESIZE):
                    self.__origin = e.pos()
                    self.__action = Action.RESIZE
                    self.setCursor(Qt.SizeFDiagCursor)
                    return
            if self._check_action(Action.DRAG):
                self.__origin = e.pos()
                self.__action = Action.DRAG
                self.setCursor(Qt.DragMoveCursor)

    def mouseMoveEvent(self, e: QMouseEvent):
        if self.__action == Action.DRAG:
            dx = e.x() - self.__origin.x()
            dy = e.y() - self.__origin.y()
            self.set_pos(self.x() + dx, self.y() + dy)
        elif self.__action == Action.RESIZE:
            self.set_size(e.x(), e.y())
        else:
            if self._resizable and self.__corner_path.translated(
                    self.width(), self.height()).contains(e.pos()):
                self.setCursor(Qt.SizeFDiagCursor)
            else:
                self.setCursor(Qt.ArrowCursor)

    def mouseReleaseEvent(self, e: QMouseEvent):
        self.__action = Action.NONE
        self.setCursor(Qt.ArrowCursor)

    def set_size(self, w, h):
        w1 = w / Info.dpi
        h1 = h / Info.dpi
        W = self.__block.settings['Width'].value()
        H = self.__block.settings['Height'].value()
        if w1 < W.min:
            w1 = W.min
        elif w1 > W.max:
            w1 = W.max
        if h1 < H.min:
            h1 = H.min
        elif h1 > H.max:
            h1 = H.max

        self.__block.set_setting('Width', w1)
        self.__block.set_setting('Height', h1)

    def set_pos(self, x, y):
        x = x - self.__translation.x()
        y = y - self.__translation.y()
        self.__block.set_setting('X', x / Info.dpi)
        self.__block.set_setting('Y', y / Info.dpi)

    def translate(self, p):
        self.__translation = p
        self.geometry_update()
示例#33
0
def traffic_overlay(waypoints, time, wait=5, debug=False):
    # sanity check
    if len(waypoints) < 2: raise ValueError

    # parse waypoints into origin, destination, and mid-waypoints
    origin = waypoints[0]
    destin = waypoints[-1]
    waypts = waypoints[1:-1]

    # build url
    url = "http://maps.googleapis.com/maps/api/directions/json?"
    f = {"origin" : origin, "destination" : destin, "waypoints" : "|".join(waypts), "sensor" : "false"}
    url += urllib.parse.urlencode(f)

    g = urllib.request.urlopen(url).read().decode()
    j = json.loads(g)
    #pprint.pprint(j)

    # error if not one route
    nroute = len(j['routes'])
    if nroute != 1: raise ValueError

    nleg = len(j['routes'][0]['legs'])
    # sanity check
    if nleg != len(waypoints)-1: raise ValueError

    coord = []
    for leg in j['routes'][0]['legs']:
        for s in leg['steps']:
            c = decode_polyline(s['polyline']['points'])
            # make sure we don't add the same point twice!
            if len(coord) > 0:
                if all([(coord[-1][i] - c[0][i]) < 1e-10 for i in range(2)]):
                    coord.extend(c[1:])
                else:
                    coord.extend(c)
            else:
                coord.extend(c)

    # temporary html file
    html_file = "_map.html"

    # find min/max lat/lng
    lats = [x[0] for x in coord]
    lngs = [x[1] for x in coord]
    img_size = (2048, 2048)
    _write_traffic_html((min(lats), max(lats)), (min(lngs), max(lngs)),
        html_file, width=2048, height=2048)

    # take screenshot
    S = WebScreenShot()
    image = S.capture(html_file, wait=wait)

    # bounds are returned in a cookie (ohh la la)
    cookie = S.get_cookies()
    bounds = json.loads(cookie[0])['k']

    # loop through polyline points and compute overlay value at each point
    image_size = [image.height(), image.width()]
    pplat = image_size[0]/(bounds['upper_right_lat']-bounds['lower_left_lat'])
    pplng = image_size[1]/(bounds['upper_right_lng']-bounds['lower_left_lng'])

    val = [0] * len(coord)
    for i, c in enumerate(coord):
        x = int((c[0] - bounds['lower_left_lng'])*pplng)
        y = int((bounds['upper_right_lat'] - c[1])*pplat)

        v = QColor(image.pixel(QPoint(x, y)))
        v_rgb = (v.red(), v.green(), v.blue())
        val[i] = color_to_value(v_rgb)

        # if debugging, change pixel color to black for each point sampled
        # and then save the image as _img.jpg
        if debug:
            image.setPixel(QPoint(x, y), 0)

    if debug:
        image.save("_img.jpg")

    print(coord)
示例#34
0
class OIBlock(QWidget):
    border_color = QColor(137, 117, 89)
    padding = 0.05
    radius = 0.08

    def __init__(self, block, parent):
        QWidget.__init__(self, parent)
        self.__nodes = []
        self.__block = block
        self._resizable = True
        self.__block.repaint.connect(self.repaint)
        self._bg_color = QColor(159, 160, 144, 255)
        self._fg_color = QColor(255, 255, 255)
        self.setGeometry(block.get_geometry(Info.dpi))
        self.__action = Action.NONE
        self.__status = Mode.EDIT_LOGIC
        self.__corner_path = None
        self.__origin = None
        self.__translation = QPoint()
        if self._resizable:
            self.__init_corner()
        self.__init_nodes()
        self.__init_listeners()
        self.setMouseTracking(True)

    def __init_nodes(self):
        y = .45
        x = .01
        for k in self.__block.inputs:
            i = self.__block.inputs[k]
            n = OINode(QPointF(x, y), Alignment.Left, i)
            self.__nodes.append(n)
            y += 0.05 + n.size
        x = self.width() / Info.dpi - .12
        y = 0.45
        for k in self.__block.outputs:
            o = self.__block.outputs[k]
            n = OINode(QPointF(x, y), Alignment.Right, o)
            self.__nodes.append(n)
            y += .05 + n.size

    def __init_listeners(self):
        self.__block.selected.connect(self.select)
        self.__block.settings['Width'].value_update.connect(self.geometry_update)
        self.__block.settings['Height'].value_update.connect(self.geometry_update)
        self.__block.settings['X'].value_update.connect(self.geometry_update)
        self.__block.settings['Y'].value_update.connect(self.geometry_update)

    def select(self, val: bool):
        if val:
            effect = QGraphicsDropShadowEffect()
            effect.setBlurRadius(20)
            effect.setXOffset(0)
            effect.setYOffset(0)
            effect.setColor(QColor(0, 0, 0, 180))
            self.setGraphicsEffect(effect)
            self.raise_()
        else:
            eff = self.graphicsEffect()
            del eff
            self.setGraphicsEffect(None)

    def geometry_update(self):
        r = self.__block.get_geometry(Info.dpi)
        r.translate(self.__translation)
        self.setGeometry(r)
        self.__update_nodes()

    def __update_nodes(self):
        x = self.width() / Info.dpi - .12
        for n in self.__nodes:
            if n.alignment == Alignment.Right:
                y = n.pos.y()
                n.pos = QPointF(x, y)
        self.repaint()

    def selected(self):
        return self.__block.is_selected()

    def bg(self):
        return self._bg_color

    def title_bg(self):
        return self._bg_color.light(80)

    def block(self):
        return self.__block

    def _paint(self, p: QPainter):
        self._paint_bg(p)
        self._paint_title(p)
        p.setPen(QPen(self.pen().brush(), 0.01 * Info.dpi))
        self._paint_nodes(p)
        # self._paint_outs(p)
        # self._paint_content(p)

    def pen(self):
        p = QPen(OIBlock.border_color.lighter().lighter() if self.selected() else OIBlock.border_color, .02 * Info.dpi)
        return p

    def _paint_bg(self, p: QPainter):
        dpi = Info.dpi
        pen = self.pen()
        p.setRenderHint(QPainter.Antialiasing, True)
        p.setPen(pen)
        p.setBrush(self.bg())
        p.drawRoundedRect(OIBlock.padding * dpi, OIBlock.padding * dpi, self.width() - 2 * OIBlock.padding * dpi,
                          self.height() - 2 * OIBlock.padding * dpi, OIBlock.radius * dpi, OIBlock.radius * dpi)
        p.setBrush(self.title_bg())
        p.drawRoundedRect(OIBlock.padding * dpi, OIBlock.padding * dpi, self.width() - 2 * OIBlock.padding * dpi,
                          .35 * dpi + OIBlock.padding * dpi, OIBlock.radius * dpi,
                          OIBlock.radius * dpi)
        p.setBrush(self.bg())
        p.setPen(QColor(0, 0, 0, 0))
        p.drawRect(0.01 * dpi + OIBlock.padding * dpi, 0.35 * dpi + OIBlock.padding * dpi,
                   self.width() - 0.02 * dpi - 2 * OIBlock.padding * dpi, 0.10 * dpi)
        p.setPen(pen)
        if self._resizable:
            if self.__corner_path is None:
                self.__init_corner()
            p.setBrush(pen.brush())
            p.drawPath(self.__corner_path.translated(self.width(), self.height()))

    def _paint_title(self, p: QPainter):
        dpi = Info.dpi
        p.drawLine(OIBlock.padding * dpi, 0.35 * dpi + OIBlock.padding * dpi,
                   self.width() - (0.01 + OIBlock.padding) * dpi,
                   0.35 * dpi + OIBlock.padding * dpi)
        p.setPen(self._fg_color)
        f = p.font()
        f.setPointSize(10)
        f.setBold(True)
        p.setFont(f)
        p.drawText(
            QRectF((0.04 + OIBlock.padding) * dpi, (OIBlock.padding + .01) * dpi, self.width() - .12 * dpi, .25 * dpi),
            str(self.__block.name()))
        f.setBold(False)
        f.setPointSize(8)
        p.setPen(QColor(self._fg_color.red(), self._fg_color.green(), self._fg_color.blue(), 100))
        p.setFont(f)
        p.drawText(
            QRectF((.04 + OIBlock.padding) * dpi, (.17 + OIBlock.padding) * dpi, self.width() - .12 * dpi, .15 * dpi),
            str(self.__block.type_name()))

    def __init_corner(self):
        path = QPainterPath()
        dpi = Info.dpi
        path.moveTo(-OIBlock.padding * 1.2 * dpi, (-.15 - OIBlock.padding * 1.2) * dpi)
        path.lineTo((-.15 - OIBlock.padding * 1.2) * dpi, -OIBlock.padding * 1.2 * dpi)
        path.lineTo(-OIBlock.padding * 1.2 * dpi, -OIBlock.padding * 1.2 * dpi)
        path.closeSubpath()
        self.__corner_path = path

    def _paint_nodes(self, p: QPainter):
        for n in self.__nodes:
            n.paint(p)
        return

    def _paint_content(self, p: QPainter):
        # nothing to do
        return

    def paintEvent(self, e: QPaintEvent):
        if e.isAccepted():
            p = QPainter(self)
            self._paint(p)

    def _check_corner(self, pos):
        path = self.__corner_path.translated(self.width(), self.height())
        return path.contains(pos)

    def _check_action(self, action):
        if self.__action != Action.NONE and action != Action.NONE:
            return False
        return True

    def _check_nodes(self, p:QPoint):
        for n in self.__nodes:
            if n.contains(p):
                return n
        return None

    def mousePressEvent(self, e: QMouseEvent):
        self.__block.select()
        n = self._check_nodes(e.pos())
        if n is not None:
            print('Node found')
            return
        if e.button() == Qt.LeftButton:
            if self._resizable:
                if self._check_corner(e.pos()) and self._check_action(Action.RESIZE):
                    self.__origin = e.pos()
                    self.__action = Action.RESIZE
                    self.setCursor(Qt.SizeFDiagCursor)
                    return
            if self._check_action(Action.DRAG):
                self.__origin = e.pos()
                self.__action = Action.DRAG
                self.setCursor(Qt.DragMoveCursor)

    def mouseMoveEvent(self, e: QMouseEvent):
        if self.__action == Action.DRAG:
            dx = e.x() - self.__origin.x()
            dy = e.y() - self.__origin.y()
            self.set_pos(self.x() + dx, self.y() + dy)
        elif self.__action == Action.RESIZE:
            self.set_size(e.x(), e.y())
        else:
            if self._resizable and self.__corner_path.translated(self.width(), self.height()).contains(e.pos()):
                self.setCursor(Qt.SizeFDiagCursor)
            else:
                self.setCursor(Qt.ArrowCursor)

    def mouseReleaseEvent(self, e: QMouseEvent):
        self.__action = Action.NONE
        self.setCursor(Qt.ArrowCursor)

    def set_size(self, w, h):
        w1 = w / Info.dpi
        h1 = h / Info.dpi
        W = self.__block.settings['Width'].value()
        H = self.__block.settings['Height'].value()
        if w1 < W.min:
            w1 = W.min
        elif w1 > W.max:
            w1 = W.max
        if h1 < H.min:
            h1 = H.min
        elif h1 > H.max:
            h1 = H.max

        self.__block.set_setting('Width', w1)
        self.__block.set_setting('Height', h1)

    def set_pos(self, x, y):
        x = x - self.__translation.x()
        y = y - self.__translation.y()
        self.__block.set_setting('X', x / Info.dpi)
        self.__block.set_setting('Y', y / Info.dpi)

    def translate(self, p):
        self.__translation = p
        self.geometry_update()