<commit_before>from header import *

from Thought import *

from Sidebar import *

from Link import *

from ColourScheme import *

class Sheet:

	cursorPos=(0,0) #need to track cursor position for dragging
	dragInit=(0,0)
	pausePanning = False

	# store indices of thoughts to link
	linkA, linkB = -1,-1
	linkImportance=-1

	# zoom factor
	zoomFac = 1.05
	curZoom= 1.0

	# turn on/off animations
	fastGraphics = False

	holding=False

	def __init__(self, root, canvas, fileName):
		self.root=root
		self.canvas=canvas

		self.cs=ColourScheme()

		self.thoughts = []
		self.links = []

		self.canvas.bind("<Double-Button-1>",self.addAtCoord)
		self.canvas.bind('<Button-1>', self.startDrag)
		self.canvas.bind('<B1-Motion>', self.onDrag)
		self.canvas.bind('<ButtonRelease-1>', self.endThoughtDrag)
		self.root.bind('<Control-Key-s>', self.saveData)

		self.canvas.bind('<4>', lambda event : self.zoom('in', event))
		self.canvas.bind('<5>', lambda event : self.zoom('out', event))

		self.canvas.configure(bg=g.toHex(self.cs.background))

		self.curIndex=0 #keep track of index most recently assigned (first thought=1)

		self.fileName=fileName

		self.imageList=[]

		self.initDrawing()

		self.root.update()

		self.resize()

		self.loadFile()

		#self.sidebar._lift()

	def initDrawing(self):
		global DIR
		# draw the save button

		self.saveIcon, self.imageList = g.loadImage(fileName=DIR+"/icons/save.png", size=(20,20),
				imageList=self.imageList, root=self.root, background=g.toHex(self.cs.background))
		self.saveIcon.bind("<Button-1>", self.handleSavePress)

		# create sidebar
		#self.sidebar = Sidebar(self.root)

		return

	def startDrag(self, event):
		self.dragInit = (event.x, event.y)
		self.cursorPos = (event.x, event.y)

	def endThoughtDrag(self, event):
		self.pausePanning = False
		self.root.update()

	def onDrag(self, event):
		if not self.pausePanning:
			# shift all objects on canvas
			delta = (event.x - self.cursorPos[0], event.y - self.cursorPos[1])

			self.cursorPos = (event.x, event.y)

			for t in self.thoughts:
				t.moveByPix((delta[0],delta[1]))
			for l in self.links:
				l.updateLine()

	def zoom(self, direction="in", event=[]):

		if direction == "in":
			self.curZoom *= self.zoomFac
		else:
			self.curZoom /= self.zoomFac

		#print "zooming ", direction, self.curZoom

		location=(event.x, event.y)

		for t in self.thoughts:
			# change size of t
			t.zoom(direction, location)

		for l in self.links:
			l.updateLine()
			l.zoom(direction)

	def loadFile(self):
		data = jsonLoad(self.fileName)

		if data == {}:
			return

		self.curZoom = data['zoom']

		geom = data['root_geometry']
		#geom = geom.split('+')[0]+'+0+0'
		#self.root.geometry(geom)

		geomD = geom.replace('+', ' ').replace('x', ' ').split()
		geomD = [int(d) for d in geomD]
		geomD2 = [geomD[0], geomD[1], g.WIDTH/2 - geomD[0]/2, g.HEIGHT/2 - geomD[1]/2]
		geom = '%sx%s+%s+%s'%tuple(geomD2)
		self.root.geometry(geom)

		self.root.update()
		self.resize()

		for t in data['thoughts']:
			self.addThought(coords=t['pixLoc'], data=t)

		for l in data['links']:
			self.linkA = l['tA']
			self.linkB = l['tB']
			self.linkImportance = l['importance']
			self.addLink()

	def saveData(self, event=[]):
		#print "saving..."
		pixelX=self.root.winfo_width()
		pixelY=self.root.winfo_height()

		oX = self.root.winfo_rootx()
		oY = self.root.winfo_rooty()
		data = {}
		data['root_geometry'] = self.root.winfo_geometry() #[pixelX, pixelY, oX, oY]

		#"1097x499+94+212"

		data['thoughts'] = []

		data['zoom'] = self.curZoom

		for t in self.thoughts:

			tData={}
			#tData['index'] = t.index
			tData['pixLoc'] = t.pixLoc
			tData['radius'] = t.r
			tData['text'] = t.getText()
			tData['fontSize'] = t.fontSize

			data['thoughts'].append(tData)

		data['links'] = []
		for l in self.links:

			lData={}
			#need to add 1 since index assignments for thoughts starts at 1
			#   instead of 0
			lData['tA'] = self.thoughts.index(l.tA)+1
			lData['tB'] = self.thoughts.index(l.tB)+1
			lData['importance'] = l.importance

			data['links'].append(lData)

			#l.grow()

		jsonSave(data=data, fileName=self.fileName, indent=True, sort=False, oneLine=False)

		self.pulse()

		return

	def groupShift(self, node, delta, shiftType=0, level=0):

		'''
		if length(delta) >= 0.004:
			shiftType=1
			#print
		else:
			shiftType=0
			#print 1
		'''
		#print length(delta)

		if shiftType == 0:
			damp=1.0
			delta2 = [v*damp for v in list(delta)]

			for l in self.links:
				#if not l.isImportant(): continue

				if l.isImportant() and node == l.tA and not l.tB.groupShifted:
					# then shift l.tB

					#damp=1.0 - clamp(self.nodeDist(node, l.tB)/200.0)
					#delta2 = [v*damp for v in list(delta)]

					l.tB.moveBy(delta2)
					l.tB.groupShifted=True
					#if level < 1:
					self.groupShift(l.tB, delta2, shiftType, level=level+1)
					#else:
					#	self.groupShift(l.tB, delta2, shiftType=1, level=level+1)

				'''
				elif l.isImportant() and node == l.tB and not l.tA.groupShifted:
					# then shift l.tA

					#damp=1.0 - clamp(self.nodeDist(node, l.tA)/200.0)
					#delta2 = [v*damp for v in list(delta)]

					l.tA.moveBy(delta2)
					l.tA.groupShifted=True
					#if level < 1:
					self.groupShift(l.tA, delta2, shiftType, level=level+1)
					#else:
					#	self.groupShift(l.tA, delta2, shiftType=1, level=level+1)
				'''

				l.updateLine()

		elif shiftType==1:
			for t in self.thoughts:

				if not t.groupShifted:

					distance = max(self.nodeDist(node, t),0.1)

					direction = getDir(node.pixLoc, t.pixLoc)

					cs = cosSim(normalize(delta), direction)

					d2 = max(distance - (node.z_r+t.z_r)*1.25, 1.0)

					if cs>=0.3 and d2<5:

						t.moveBy(delta)
						t.groupShifted=True
						self.groupShift(t, delta, shiftType)

			for l in self.links:
				l.updateLine()

		elif shiftType==2:
			for t in self.thoughts:

				if not t.groupShifted:

					distance = max(self.nodeDist(node, t),0.1)/self.curZoom

					direction = getDir(node.pixLoc, t.pixLoc)

					cs = cosSim(normalize(delta), direction)

					d2 = max(distance - (node.r+t.r)*1.25, 1.0)

					if cs>=0.3 and d2<100:

						damp=1.0 - clamp(d2/400.0)
						delta2 = [v*damp for v in list(delta)]

						t.moveBy(delta2)
						t.groupShifted=True
						self.groupShift(t, delta2, shiftType)

			for l in self.links:
				l.updateLine()

	def nodeDist(self, tA, tB):
		return dist(tA.pixLoc, tB.pixLoc)

	def resetGroupShift(self):
		for t in self.thoughts:
			t.groupShifted=False

	def resize(self, event=[]):
		pixelX=self.root.winfo_width()
		pixelY=self.root.winfo_height()

		canvasW = pixelX
		canvasH = pixelY-0

		self.canvas.place(x=0, y=0, width=canvasW, height=canvasH)

		self.saveIcon.place(x=0, y=pixelY-30, width=30, height=30)

		#self.sidebar.resize()

	def addThought(self, coords, data={}):

		self.thoughts.append(Thought(self, coords, data))

		#self.saveData()

	def addAtCoord(self, event):

		if self.pausePanning: return

		#print "click:", event.x, event.y
		self.addThought((event.x, event.y))

	def removeThought(self, index):

		# remove any links connected to that thought

		T = self.getThought(index)

		n = len(self.links)
		for i in range(n):
			l = self.links[n - i - 1]
			if l.tA == T or l.tB == T:
				#print "removing"
				l.remove()
				#self.removeLink(l.tA, l.tB)

		self.thoughts.remove(T)

		self.root.update()

		#self.saveData()

	def removeLink(self, tA, tB):
		# remove link associated with tA and tB

		for l in self.links:
			if l.tA == tA and l.tB==tB:
				self.links.remove(l)

				break

	def getNewIndex(self):
		self.curIndex += 1
		return self.curIndex

	def handleSavePress(self, event):
		self.saveData()

	def addLink(self):
		tA = self.linkA
		tB = self.linkB

		if tA == -1 or tB == -1:
			print "ERROR: a link end not assigned"

		if tA != tB and not self.hasLink(tA, tB):
			self.links.append(Link(self, self.getThought(tA), self.getThought(tB), importance=self.linkImportance))

			#print "Creating a link!"

		# set circle colour back to white
		TA = self.getThought(tA)
		TA.canvas.itemconfig(TA.smallCircleIndex, fill=g.toHex(self.cs.smallCircle))

		# reset link assignments
		self.resetLinkData()

		self.lowerLinks()

	def getThought(self, index):
		for t in self.thoughts:
			if t.index == index:
				return t

	def updateNodeEdges(self, node):
		for l in self.links:

			if node == l.tA or node == l.tB:

				l.updateLine()

	def hasLink(self, tA, tB):

		TA = self.getThought(tA)
		TB = self.getThought(tB)

		for l in self.links:

			if (l.tA == TA and l.tB==TB) or (l.tA == TB and l.tB==TA):
				return True
		return False

	def resetLinkData(self):
		self.linkA = -1
		self.linkB = -1
		self.linkImportance=-1

	def lowerLinks(self):
		# make sure all the softer links are lower than the white ones

		for l in self.links:
			l._adjust_layers(readjust=True)

		for t in self.thoughts:
			t.lowerShadows()

	def pulse(self, stage=0):

		#try:

		total_stages=20

		f = 1.0*stage/total_stages

		if stage<=total_stages:
			bkgColour = g.shadeN([self.cs.background, self.cs.backgroundPulse, self.cs.background], [0,0.5,1], f)

			self.canvas.configure(bg=g.toHex(bkgColour))

		if stage < total_stages:
			t = threading.Timer(0.01, self.pulse, [stage+1])
			t.daemon = True
			t.start()
		#except:
		#	pass<commit_msg>removed refs to sidebar in Sheet.py<commit_after>from header import *

from Thought import *

from Link import *

from ColourScheme import *

class Sheet:

	cursorPos=(0,0) #need to track cursor position for dragging
	dragInit=(0,0)
	pausePanning = False

	# store indices of thoughts to link
	linkA, linkB = -1,-1
	linkImportance=-1

	# zoom factor
	zoomFac = 1.05
	curZoom= 1.0

	# turn on/off animations
	fastGraphics = False

	holding=False

	def __init__(self, root, canvas, fileName):
		self.root=root
		self.canvas=canvas

		self.cs=ColourScheme()

		self.thoughts = []
		self.links = []

		self.canvas.bind("<Double-Button-1>",self.addAtCoord)
		self.canvas.bind('<Button-1>', self.startDrag)
		self.canvas.bind('<B1-Motion>', self.onDrag)
		self.canvas.bind('<ButtonRelease-1>', self.endThoughtDrag)
		self.root.bind('<Control-Key-s>', self.saveData)

		self.canvas.bind('<4>', lambda event : self.zoom('in', event))
		self.canvas.bind('<5>', lambda event : self.zoom('out', event))

		self.canvas.configure(bg=g.toHex(self.cs.background))

		self.curIndex=0 #keep track of index most recently assigned (first thought=1)

		self.fileName=fileName

		self.imageList=[]

		self.initDrawing()

		self.root.update()

		self.resize()

		self.loadFile()

	def initDrawing(self):
		global DIR
		# draw the save button

		self.saveIcon, self.imageList = g.loadImage(fileName=DIR+"/icons/save.png", size=(20,20),
				imageList=self.imageList, root=self.root, background=g.toHex(self.cs.background))
		self.saveIcon.bind("<Button-1>", self.handleSavePress)

		return

	def startDrag(self, event):
		self.dragInit = (event.x, event.y)
		self.cursorPos = (event.x, event.y)

	def endThoughtDrag(self, event):
		self.pausePanning = False
		self.root.update()

	def onDrag(self, event):
		if not self.pausePanning:
			# shift all objects on canvas
			delta = (event.x - self.cursorPos[0], event.y - self.cursorPos[1])

			self.cursorPos = (event.x, event.y)

			for t in self.thoughts:
				t.moveByPix((delta[0],delta[1]))
			for l in self.links:
				l.updateLine()

	def zoom(self, direction="in", event=[]):

		if direction == "in":
			self.curZoom *= self.zoomFac
		else:
			self.curZoom /= self.zoomFac

		#print "zooming ", direction, self.curZoom

		location=(event.x, event.y)

		for t in self.thoughts:
			# change size of t
			t.zoom(direction, location)

		for l in self.links:
			l.updateLine()
			l.zoom(direction)

	def loadFile(self):
		data = jsonLoad(self.fileName)

		if data == {}:
			return

		self.curZoom = data['zoom']

		geom = data['root_geometry']
		#geom = geom.split('+')[0]+'+0+0'
		#self.root.geometry(geom)

		geomD = geom.replace('+', ' ').replace('x', ' ').split()
		geomD = [int(d) for d in geomD]
		geomD2 = [geomD[0], geomD[1], g.WIDTH/2 - geomD[0]/2, g.HEIGHT/2 - geomD[1]/2]
		geom = '%sx%s+%s+%s'%tuple(geomD2)
		self.root.geometry(geom)

		self.root.update()
		self.resize()

		for t in data['thoughts']:
			self.addThought(coords=t['pixLoc'], data=t)

		for l in data['links']:
			self.linkA = l['tA']
			self.linkB = l['tB']
			self.linkImportance = l['importance']
			self.addLink()

	def saveData(self, event=[]):
		#print "saving..."
		pixelX=self.root.winfo_width()
		pixelY=self.root.winfo_height()

		oX = self.root.winfo_rootx()
		oY = self.root.winfo_rooty()
		data = {}
		data['root_geometry'] = self.root.winfo_geometry() #[pixelX, pixelY, oX, oY]

		#"1097x499+94+212"

		data['thoughts'] = []

		data['zoom'] = self.curZoom

		for t in self.thoughts:

			tData={}
			#tData['index'] = t.index
			tData['pixLoc'] = t.pixLoc
			tData['radius'] = t.r
			tData['text'] = t.getText()
			tData['fontSize'] = t.fontSize

			data['thoughts'].append(tData)

		data['links'] = []
		for l in self.links:

			lData={}
			#need to add 1 since index assignments for thoughts starts at 1
			#   instead of 0
			lData['tA'] = self.thoughts.index(l.tA)+1
			lData['tB'] = self.thoughts.index(l.tB)+1
			lData['importance'] = l.importance

			data['links'].append(lData)

			#l.grow()

		jsonSave(data=data, fileName=self.fileName, indent=True, sort=False, oneLine=False)

		self.pulse()

		return

	def groupShift(self, node, delta, shiftType=0, level=0):

		'''
		if length(delta) >= 0.004:
			shiftType=1
			#print
		else:
			shiftType=0
			#print 1
		'''
		#print length(delta)

		if shiftType == 0:
			damp=1.0
			delta2 = [v*damp for v in list(delta)]

			for l in self.links:
				#if not l.isImportant(): continue

				if l.isImportant() and node == l.tA and not l.tB.groupShifted:
					# then shift l.tB

					#damp=1.0 - clamp(self.nodeDist(node, l.tB)/200.0)
					#delta2 = [v*damp for v in list(delta)]

					l.tB.moveBy(delta2)
					l.tB.groupShifted=True
					#if level < 1:
					self.groupShift(l.tB, delta2, shiftType, level=level+1)
					#else:
					#	self.groupShift(l.tB, delta2, shiftType=1, level=level+1)

				'''
				elif l.isImportant() and node == l.tB and not l.tA.groupShifted:
					# then shift l.tA

					#damp=1.0 - clamp(self.nodeDist(node, l.tA)/200.0)
					#delta2 = [v*damp for v in list(delta)]

					l.tA.moveBy(delta2)
					l.tA.groupShifted=True
					#if level < 1:
					self.groupShift(l.tA, delta2, shiftType, level=level+1)
					#else:
					#	self.groupShift(l.tA, delta2, shiftType=1, level=level+1)
				'''

				l.updateLine()

		elif shiftType==1:
			for t in self.thoughts:

				if not t.groupShifted:

					distance = max(self.nodeDist(node, t),0.1)

					direction = getDir(node.pixLoc, t.pixLoc)

					cs = cosSim(normalize(delta), direction)

					d2 = max(distance - (node.z_r+t.z_r)*1.25, 1.0)

					if cs>=0.3 and d2<5:

						t.moveBy(delta)
						t.groupShifted=True
						self.groupShift(t, delta, shiftType)

			for l in self.links:
				l.updateLine()

		elif shiftType==2:
			for t in self.thoughts:

				if not t.groupShifted:

					distance = max(self.nodeDist(node, t),0.1)/self.curZoom

					direction = getDir(node.pixLoc, t.pixLoc)

					cs = cosSim(normalize(delta), direction)

					d2 = max(distance - (node.r+t.r)*1.25, 1.0)

					if cs>=0.3 and d2<100:

						damp=1.0 - clamp(d2/400.0)
						delta2 = [v*damp for v in list(delta)]

						t.moveBy(delta2)
						t.groupShifted=True
						self.groupShift(t, delta2, shiftType)

			for l in self.links:
				l.updateLine()

	def nodeDist(self, tA, tB):
		return dist(tA.pixLoc, tB.pixLoc)

	def resetGroupShift(self):
		for t in self.thoughts:
			t.groupShifted=False

	def resize(self, event=[]):
		pixelX=self.root.winfo_width()
		pixelY=self.root.winfo_height()

		canvasW = pixelX
		canvasH = pixelY-0

		self.canvas.place(x=0, y=0, width=canvasW, height=canvasH)

		self.saveIcon.place(x=0, y=pixelY-30, width=30, height=30)

	def addThought(self, coords, data={}):

		self.thoughts.append(Thought(self, coords, data))

		#self.saveData()

	def addAtCoord(self, event):

		if self.pausePanning: return

		#print "click:", event.x, event.y
		self.addThought((event.x, event.y))

	def removeThought(self, index):

		# remove any links connected to that thought

		T = self.getThought(index)

		n = len(self.links)
		for i in range(n):
			l = self.links[n - i - 1]
			if l.tA == T or l.tB == T:
				#print "removing"
				l.remove()
				#self.removeLink(l.tA, l.tB)

		self.thoughts.remove(T)

		self.root.update()

		#self.saveData()

	def removeLink(self, tA, tB):
		# remove link associated with tA and tB

		for l in self.links:
			if l.tA == tA and l.tB==tB:
				self.links.remove(l)

				break

	def getNewIndex(self):
		self.curIndex += 1
		return self.curIndex

	def handleSavePress(self, event):
		self.saveData()

	def addLink(self):
		tA = self.linkA
		tB = self.linkB

		if tA == -1 or tB == -1:
			print "ERROR: a link end not assigned"

		if tA != tB and not self.hasLink(tA, tB):
			self.links.append(Link(self, self.getThought(tA), self.getThought(tB), importance=self.linkImportance))

			#print "Creating a link!"

		# set circle colour back to white
		TA = self.getThought(tA)
		TA.canvas.itemconfig(TA.smallCircleIndex, fill=g.toHex(self.cs.smallCircle))

		# reset link assignments
		self.resetLinkData()

		self.lowerLinks()

	def getThought(self, index):
		for t in self.thoughts:
			if t.index == index:
				return t

	def updateNodeEdges(self, node):
		for l in self.links:

			if node == l.tA or node == l.tB:

				l.updateLine()

	def hasLink(self, tA, tB):

		TA = self.getThought(tA)
		TB = self.getThought(tB)

		for l in self.links:

			if (l.tA == TA and l.tB==TB) or (l.tA == TB and l.tB==TA):
				return True
		return False

	def resetLinkData(self):
		self.linkA = -1
		self.linkB = -1
		self.linkImportance=-1

	def lowerLinks(self):
		# make sure all the softer links are lower than the white ones

		for l in self.links:
			l._adjust_layers(readjust=True)

		for t in self.thoughts:
			t.lowerShadows()

	def pulse(self, stage=0):

		#try:

		total_stages=20

		f = 1.0*stage/total_stages

		if stage<=total_stages:
			bkgColour = g.shadeN([self.cs.background, self.cs.backgroundPulse, self.cs.background], [0,0.5,1], f)

			self.canvas.configure(bg=g.toHex(bkgColour))

		if stage < total_stages:
			t = threading.Timer(0.01, self.pulse, [stage+1])
			t.daemon = True
			t.start()
		#except:
		#	pass<|endoftext|>


<commit_before>import sublime, sublime_plugin
import urllib, tarfile, os
from subprocess import call
from os import listdir
from os.path import join, exists
from random import choice

try:
    import winsound
except Exception:
    pass

from .libs.decorators import thread

SETTING_NAME = "Sound.sublime-settings"
BASE_SOUNDSET_URL = "https://github.com/airtoxin/Sublime-SoundSets/blob/master/{0}.tar.gz?raw=true"

class EventSound(sublime_plugin.EventListener):
    def __init__(self, *args, **kwargs):
        super(EventSound, self).__init__(*args, **kwargs)
        self.play = getattr(self, sublime.platform() + "_play")

    @thread
    def osx_play(self, event_name):
        self.on_play_flag = False
        dir_path = join(
            sublime.packages_path(),
            "Sound",
            "sounds",
            sublime.load_settings(SETTING_NAME).get("soundset"),
            event_name
        )
        if exists(dir_path):
            sound_files = [f for f in listdir(dir_path) if f.endswith(".wav") ]
            if not len(sound_files) == 0:
                volume = self.get_volume()
                call(["afplay", "-v", str(volume / 100), join(dir_path, choice(sound_files))])

    @thread
    def windows_play(self, event_name):
        self.on_play_flag = False
        dir_path = join(sublime.packages_path(), "Sound", "sounds", event_name)
        if exists(dir_path):
            sound_files = [f for f in listdir(dir_path) if f.endswith(".wav") ]
            if not len(sound_files) == 0:
                winsound.PlaySound(join(dir_path, choice(sound_files)), winsound.SND_FILENAME | winsound.SND_ASYNC)

    @thread
    def linux_play(self, event_name):
        self.on_play_flag = False
        dir_path = join(sublime.packages_path(), "Sound", "sounds", event_name)
        if exists(dir_path):
            sound_files = [f for f in listdir(dir_path) if f.endswith(".wav") ]
            if not len(sound_files) == 0:
                call(["aplay", join(dir_path, choice(sound_files))])

    def on_new_async(self, view):
        # Called when a new buffer is created. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_new"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_clone_async(self, view):
        # Called when a view is cloned from an existing one. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_clone"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_load_async(self, view):
        # Called when the file is finished loading. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_load"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_close(self, view):
        # Called when a view is closed (note, there may still be other views into the same buffer).
        self.throttle(
            lambda: self.play("on_close"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_pre_save_async(self, view):
        # Called after a view has been saved. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_save"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_modified_async(self, view):
        # Called after changes have been made to a view. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_modify"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def throttle(self, func, time):
        # Creates a function that, when executed, will only call the func function at most once per every time milliseconds.
        if not hasattr(self, "on_play_flag"): self.on_play_flag = False
        if self.on_play_flag: return
        self.on_play_flag = True
        sublime.set_timeout(func, time)

    def get_volume(self):
        volume = sublime.load_settings(SETTING_NAME).get("volume")
        return min(100, max(0, volume))

class InstallSoundsetCommand(sublime_plugin.ApplicationCommand):
    def run(self):
        def on_done(name):
            extract_name = join(sublime.packages_path(), "Sound", "sounds")
            tarfile_name = join(extract_name, name + ".tar.gz")
            status_key = "SOUND"
            try:
                urllib.request.urlretrieve(
                   BASE_SOUNDSET_URL.format(name),
                   tarfile_name
                )
                tarfile.open(tarfile_name, "r").extractall(extract_name)
                os.remove(tarfile_name)
            except:
                sublime.active_window().active_view().set_status(
                    status_key,
                    "Soundset Install Failed: " + name
                )
                sublime.set_timeout(
                    lambda: sublime.active_window().active_view().erase_status(status_key),
                    3000
                )
        def on_change(change):
            pass
        def on_cancel():
            pass

        sublime.active_window().show_input_panel(
            "Input soundset_name",
            "",
            on_done,
            on_change,
            on_cancel
        )

class ChangeSoundsetCommand(sublime_plugin.ApplicationCommand):
    def run(self):
        soundsets = [s for s in os.listdir(join(sublime.packages_path(), "Sound", "sounds")) if not s.startswith(".")]
        def on_done(i):
            if i == -1: return
            self.change_setting(soundsets[i])

        sublime.active_window().show_quick_panel(
            soundsets,
            on_done
        )

    def change_setting(self, soundset_name):
        sublime.load_settings(SETTING_NAME).set("soundset", soundset_name)
        sublime.save_settings(SETTING_NAME)

class ToggleSoundCommand(sublime_plugin.ApplicationCommand):
    def run(self):
        current_volume = sublime.load_settings(SETTING_NAME).get("volume")
        sublime.load_settings(SETTING_NAME).set("volume", -current_volume)
        sublime.save_settings(SETTING_NAME)
<commit_msg>Add fuction to show status messages<commit_after>import sublime, sublime_plugin
import urllib, tarfile, os, json
from subprocess import call
from os import listdir
from os.path import join, exists
from random import choice

try:
    import winsound
except Exception:
    pass

from .libs.decorators import thread

STATUS_KEY = "SUBLIMESOUND"
SETTING_NAME = "Sound.sublime-settings"
BASE_SOUNDSET_URL = "https://github.com/airtoxin/Sublime-SoundSets/blob/master/{0}.tar.gz?raw=true"
PACKLIST_URL = "https://raw.githubusercontent.com/airtoxin/Sublime-SoundSets/master/packlist.json"
SOUNDS_DIR_PATH = join(sublime.packages_path(), "Sound", "sounds")

def show_status(message):
    sublime.active_window().active_view().set_status(
        STATUS_KEY,
        message
    )
    sublime.set_timeout(
        lambda: sublime.active_window().active_view().erase_status(STATUS_KEY),
        5000
    )

class EventSound(sublime_plugin.EventListener):
    def __init__(self, *args, **kwargs):
        super(EventSound, self).__init__(*args, **kwargs)
        self.play = getattr(self, sublime.platform() + "_play")

    @thread
    def osx_play(self, event_name):
        self.on_play_flag = False
        dir_path = join(
            sublime.packages_path(),
            "Sound",
            "sounds",
            sublime.load_settings(SETTING_NAME).get("soundset"),
            event_name
        )
        if exists(dir_path):
            sound_files = [f for f in listdir(dir_path) if f.endswith(".wav") ]
            if not len(sound_files) == 0:
                volume = self.get_volume()
                call(["afplay", "-v", str(volume / 100), join(dir_path, choice(sound_files))])

    @thread
    def windows_play(self, event_name):
        self.on_play_flag = False
        dir_path = join(sublime.packages_path(), "Sound", "sounds", event_name)
        if exists(dir_path):
            sound_files = [f for f in listdir(dir_path) if f.endswith(".wav") ]
            if not len(sound_files) == 0:
                winsound.PlaySound(join(dir_path, choice(sound_files)), winsound.SND_FILENAME | winsound.SND_ASYNC)

    @thread
    def linux_play(self, event_name):
        self.on_play_flag = False
        dir_path = join(sublime.packages_path(), "Sound", "sounds", event_name)
        if exists(dir_path):
            sound_files = [f for f in listdir(dir_path) if f.endswith(".wav") ]
            if not len(sound_files) == 0:
                call(["aplay", join(dir_path, choice(sound_files))])

    def on_new_async(self, view):
        # Called when a new buffer is created. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_new"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_clone_async(self, view):
        # Called when a view is cloned from an existing one. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_clone"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_load_async(self, view):
        # Called when the file is finished loading. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_load"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_close(self, view):
        # Called when a view is closed (note, there may still be other views into the same buffer).
        self.throttle(
            lambda: self.play("on_close"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_pre_save_async(self, view):
        # Called after a view has been saved. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_save"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def on_modified_async(self, view):
        # Called after changes have been made to a view. Runs in a separate thread, and does not block the application.
        self.throttle(
            lambda: self.play("on_modify"),
            sublime.load_settings(SETTING_NAME).get("min_span")
        )

    def throttle(self, func, time):
        # Creates a function that, when executed, will only call the func function at most once per every time milliseconds.
        if not hasattr(self, "on_play_flag"): self.on_play_flag = False
        if self.on_play_flag: return
        self.on_play_flag = True
        sublime.set_timeout(func, time)

    def get_volume(self):
        volume = sublime.load_settings(SETTING_NAME).get("volume")
        return min(100, max(0, volume))

class InstallSoundsetCommand(sublime_plugin.ApplicationCommand):
    def run(self):
        def on_done(name):
            extract_name = join(sublime.packages_path(), "Sound", "sounds")
            tarfile_name = join(extract_name, name + ".tar.gz")
            status_key = "SOUND"
            try:
                urllib.request.urlretrieve(
                   BASE_SOUNDSET_URL.format(name),
                   tarfile_name
                )
                tarfile.open(tarfile_name, "r").extractall(extract_name)
                os.remove(tarfile_name)
            except:
                sublime.active_window().active_view().set_status(
                    status_key,
                    "Soundset Install Failed: " + name
                )
                sublime.set_timeout(
                    lambda: sublime.active_window().active_view().erase_status(status_key),
                    3000
                )
        def on_change(change):
            pass
        def on_cancel():
            pass

        sublime.active_window().show_input_panel(
            "Input soundset_name",
            "",
            on_done,
            on_change,
            on_cancel
        )

class ChangeSoundsetCommand(sublime_plugin.ApplicationCommand):
    def run(self):
        soundsets = [s for s in os.listdir(join(sublime.packages_path(), "Sound", "sounds")) if not s.startswith(".")]
        def on_done(i):
            if i == -1: return
            self.change_setting(soundsets[i])

        sublime.active_window().show_quick_panel(
            soundsets,
            on_done
        )

    def change_setting(self, soundset_name):
        sublime.load_settings(SETTING_NAME).set("soundset", soundset_name)
        sublime.save_settings(SETTING_NAME)

class ToggleSoundCommand(sublime_plugin.ApplicationCommand):
    def run(self):
        current_volume = sublime.load_settings(SETTING_NAME).get("volume")
        sublime.load_settings(SETTING_NAME).set("volume", -current_volume)
        sublime.save_settings(SETTING_NAME)
<|endoftext|>


<commit_before>import pygame

pygame.init()
clock = pygame.time.Clock()
crashed = False
img = pygame.image

colors = {'black' : (0,0,0), 'white' : (255,255,255), 'red' : (255,0,0), 'green' : (0,255,0), 'blue' : (0,0,255),
          'purple' : (255,0,255), 'yellow' : (255,255,0)}

disWidth = 1000
disHeight = 750
gameDis = pygame.display.set_mode((disWidth, disHeight))
pygame.display.set_caption('TCGui')
cardImg = img.load('BasicCard.png')
cardX, cardY = disWidth * .35, disHeight * .35
xchange, ychange = 0, 0

class Button:

    def __init__(self, buttonColor, sizeX, sizeY, posX, posY, text = '', font = 'freesansbold.ttf', fontColor = 'black'):
        self.text = text
        self.buttonColor = buttonColor
        self.sizeX, self.sizeY = sizeX, sizeY
        self.posX, self.posY = posX, posY
        self.font = font
        self.fontColor = fontColor

    def draw(self):
        # x, y, width, height
        textX = self.posX+(self.sizeX/2)
        textY = self.posY+(self.sizeY/2)
        textSize = self.sizeX / 5.3
        pygame.draw.rect(gameDis, colors[self.buttonColor], (self.posX, self.posY, self.sizeX, self.sizeY))
        dispText(self.text, textX, textY, self.font, textSize, colors[self.fontColor])

testButton = Button('green', 200, 50, 300, 300, 'testButton')

def dispText(msg, textX, textY, font = 'freesansbold.ttf', fontSize = 20, textColor = (0,0,0), bgColor = None):
    msgFont = pygame.font.Font(str(font), int(fontSize))
    textSurface = msgFont.render(msg, True, textColor, bgColor)
    textRect = textSurface.get_rect()
    textRect.center = (textX, textY)
    gameDis.blit(textSurface, textRect)

def drawCard(x, y):
    gameDis.blit(cardImg, (x, y))

while not crashed:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            crashed = True
        if event.type == pygame.KEYDOWN:

            if event.key == pygame.K_LEFT:
                xchange = -1
            elif event.key == pygame.K_RIGHT:
                xchange = 1

            if event.key == pygame.K_UP:
                ychange = 1
            elif event.key == pygame.K_DOWN:
                ychange = -1

        if event.type == pygame.KEYUP:
            if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
                xchange = 0
            if event.key in (pygame.K_UP, pygame.K_DOWN):
                ychange = 0

    cardX += xchange
    cardY += -ychange
    gameDis.fill(colors['white'])
    dispText('abc123', 300, 300,'freesansbold.ttf', 80, colors['blue'], colors['yellow'])
    drawCard(cardX, cardY)
    testButton.draw()
    pygame.display.update()
    clock.tick(60)

pygame.quit()
quit()<commit_msg>[--] Removed drawCard<commit_after>import pygame

pygame.init()
clock = pygame.time.Clock()
crashed = False
img = pygame.image

colors = {'black' : (0,0,0), 'white' : (255,255,255), 'red' : (255,0,0), 'green' : (0,255,0), 'blue' : (0,0,255),
          'purple' : (255,0,255), 'yellow' : (255,255,0)}

disWidth = 1000
disHeight = 750
gameDis = pygame.display.set_mode((disWidth, disHeight))
pygame.display.set_caption('TCGui')

class Button:

    def __init__(self, buttonColor, sizeX, sizeY, posX, posY, text = '', font = 'freesansbold.ttf', fontColor = 'black'):
        self.text = text
        self.buttonColor = buttonColor
        self.sizeX, self.sizeY = sizeX, sizeY
        self.posX, self.posY = posX, posY
        self.font = font
        self.fontColor = fontColor

    def draw(self):
        # x, y, width, height
        textX = self.posX+(self.sizeX/2)
        textY = self.posY+(self.sizeY/2)
        textSize = self.sizeX / 5.3
        pygame.draw.rect(gameDis, colors[self.buttonColor], (self.posX, self.posY, self.sizeX, self.sizeY))
        dispText(self.text, textX, textY, self.font, textSize, colors[self.fontColor])

testButton = Button('green', 200, 50, 300, 300, 'testButton')

def dispText(msg, textX, textY, font = 'freesansbold.ttf', fontSize = 20, textColor = (0,0,0), bgColor = None):
    msgFont = pygame.font.Font(str(font), int(fontSize))
    textSurface = msgFont.render(msg, True, textColor, bgColor)
    textRect = textSurface.get_rect()
    textRect.center = (textX, textY)
    gameDis.blit(textSurface, textRect)

while not crashed:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            crashed = True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
            elif event.key == pygame.K_RIGHT:
                testSprite.move(1, 0)
            if event.key == pygame.K_UP:
            elif event.key == pygame.K_DOWN:
                testSprite.move(0, -1)
            if event.key == pygame.K_1:
                testSprite.rotate(45)

        if event.type == pygame.KEYUP:
            if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
                pass
            if event.key in (pygame.K_UP, pygame.K_DOWN):
    gameDis.fill(colors['white'])
    dispText('abc123', 300, 300,'freesansbold.ttf', 80, colors['blue'], colors['yellow'])
    testButton.draw()
    pygame.display.update()
    clock.tick(60)

pygame.quit()
quit()<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import proto  # type: ignore

from google.protobuf import duration_pb2  # type: ignore
from google.protobuf import field_mask_pb2  # type: ignore
from google.protobuf import timestamp_pb2  # type: ignore

__protobuf__ = proto.module(
    package="google.cloud.assuredworkloads.v1beta1",
    manifest={
        "CreateWorkloadRequest",
        "UpdateWorkloadRequest",
        "DeleteWorkloadRequest",
        "GetWorkloadRequest",
        "ListWorkloadsRequest",
        "ListWorkloadsResponse",
        "Workload",
        "CreateWorkloadOperationMetadata",
    },
)

class CreateWorkloadRequest(proto.Message):
    r"""Request for creating a workload.
    Attributes:
        parent (str):
            Required. The resource name of the new Workload's parent.
            Must be of the form
            ``organizations/{org_id}/locations/{location_id}``.
        workload (google.cloud.assuredworkloads_v1beta1.types.Workload):
            Required. Assured Workload to create
        external_id (str):
            Optional. A identifier associated with the
            workload and underlying projects which allows
            for the break down of billing costs for a
            workload. The value provided for the identifier
            will add a label to the workload and contained
            projects with the identifier as the value.
    """

    parent = proto.Field(proto.STRING, number=1,)
    workload = proto.Field(proto.MESSAGE, number=2, message="Workload",)
    external_id = proto.Field(proto.STRING, number=3,)

class UpdateWorkloadRequest(proto.Message):
    r"""Request for Updating a workload.
    Attributes:
        workload (google.cloud.assuredworkloads_v1beta1.types.Workload):
            Required. The workload to update. The workload’s ``name``
            field is used to identify the workload to be updated.
            Format:
            organizations/{org_id}/locations/{location_id}/workloads/{workload_id}
        update_mask (google.protobuf.field_mask_pb2.FieldMask):
            Required. The list of fields to be updated.
    """

    workload = proto.Field(proto.MESSAGE, number=1, message="Workload",)
    update_mask = proto.Field(
        proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask,
    )

class DeleteWorkloadRequest(proto.Message):
    r"""Request for deleting a Workload.
    Attributes:
        name (str):
            Required. The ``name`` field is used to identify the
            workload. Format:
            organizations/{org_id}/locations/{location_id}/workloads/{workload_id}
        etag (str):
            Optional. The etag of the workload.
            If this is provided, it must match the server's
            etag.
    """

    name = proto.Field(proto.STRING, number=1,)
    etag = proto.Field(proto.STRING, number=2,)

class GetWorkloadRequest(proto.Message):
    r"""Request for fetching a workload.
    Attributes:
        name (str):
            Required. The resource name of the Workload to fetch. This
            is the workloads's relative path in the API, formatted as
            "organizations/{organization_id}/locations/{location_id}/workloads/{workload_id}".
            For example,
            "organizations/123/locations/us-east1/workloads/assured-workload-1".
    """

    name = proto.Field(proto.STRING, number=1,)

class ListWorkloadsRequest(proto.Message):
    r"""Request for fetching workloads in an organization.
    Attributes:
        parent (str):
            Required. Parent Resource to list workloads from. Must be of
            the form ``organizations/{org_id}/locations/{location}``.
        page_size (int):
            Page size.
        page_token (str):
            Page token returned from previous request.
            Page token contains context from previous
            request. Page token needs to be passed in the
            second and following requests.
        filter (str):
            A custom filter for filtering by properties
            of a workload. At this time, only filtering by
            labels is supported.
    """

    parent = proto.Field(proto.STRING, number=1,)
    page_size = proto.Field(proto.INT32, number=2,)
    page_token = proto.Field(proto.STRING, number=3,)
    filter = proto.Field(proto.STRING, number=4,)

class ListWorkloadsResponse(proto.Message):
    r"""Response of ListWorkloads endpoint.
    Attributes:
        workloads (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload]):
            List of Workloads under a given parent.
        next_page_token (str):
            The next page token. Return empty if reached
            the last page.
    """

    @property
    def raw_page(self):
        return self

    workloads = proto.RepeatedField(proto.MESSAGE, number=1, message="Workload",)
    next_page_token = proto.Field(proto.STRING, number=2,)

class Workload(proto.Message):
    r"""An Workload object for managing highly regulated workloads of
    cloud customers.

    Attributes:
        name (str):
            Optional. The resource name of the workload.
            Format:
            organizations/{organization}/locations/{location}/workloads/{workload}
            Read-only.
        display_name (str):
            Required. The user-assigned display name of
            the Workload. When present it must be between 4
            to 30 characters. Allowed characters are:
            lowercase and uppercase letters, numbers,
            hyphen, and spaces.

            Example: My Workload
        resources (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceInfo]):
            Output only. The resources associated with
            this workload. These resources will be created
            when creating the workload. If any of the
            projects already exist, the workload creation
            will fail. Always read only.
        compliance_regime (google.cloud.assuredworkloads_v1beta1.types.Workload.ComplianceRegime):
            Required. Immutable. Compliance Regime
            associated with this workload.
        create_time (google.protobuf.timestamp_pb2.Timestamp):
            Output only. Immutable. The Workload creation
            timestamp.
        billing_account (str):
            Required. Input only. The billing account used for the
            resources which are direct children of workload. This
            billing account is initially associated with the resources
            created as part of Workload creation. After the initial
            creation of these resources, the customer can change the
            assigned billing account. The resource name has the form
            ``billingAccounts/{billing_account_id}``. For example,
            ``billingAccounts/012345-567890-ABCDEF``.
        il4_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.IL4Settings):
            Required. Input only. Immutable. Settings
            specific to resources needed for IL4.
        cjis_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.CJISSettings):
            Required. Input only. Immutable. Settings
            specific to resources needed for CJIS.
        fedramp_high_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.FedrampHighSettings):
            Required. Input only. Immutable. Settings
            specific to resources needed for FedRAMP High.
        fedramp_moderate_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.FedrampModerateSettings):
            Required. Input only. Immutable. Settings
            specific to resources needed for FedRAMP
            Moderate.
        etag (str):
            Optional. ETag of the workload, it is
            calculated on the basis of the Workload
            contents. It will be used in Update & Delete
            operations.
        labels (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload.LabelsEntry]):
            Optional. Labels applied to the workload.
        provisioned_resources_parent (str):
            Input only. The parent resource for the resources managed by
            this Assured Workload. May be either an organization or a
            folder. Must be the same or a child of the Workload parent.
            If not specified all resources are created under the
            Workload parent. Formats: folders/{folder_id}
            organizations/{organization_id}
        kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
            Input only. Settings used to create a CMEK
            crypto key. When set a project with a KMS CMEK
            key is provisioned. This field is mandatory for
            a subset of Compliance Regimes.
        resource_settings (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceSettings]):
            Input only. Resource properties that are used
            to customize workload resources. These
            properties (such as custom project id) will be
            used to create workload resources if possible.
            This field is optional.
    """

    class ComplianceRegime(proto.Enum):
        r"""Supported Compliance Regimes."""
        COMPLIANCE_REGIME_UNSPECIFIED = 0
        IL4 = 1
        CJIS = 2
        FEDRAMP_HIGH = 3
        FEDRAMP_MODERATE = 4
        US_REGIONAL_ACCESS = 5
        HIPAA = 6
        HITRUST = 7
        EU_REGIONS_AND_SUPPORT = 8

    class ResourceInfo(proto.Message):
        r"""Represent the resources that are children of this Workload.
        Attributes:
            resource_id (int):
                Resource identifier. For a project this represents
                project_number.
            resource_type (google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceInfo.ResourceType):
                Indicates the type of resource.
        """

        class ResourceType(proto.Enum):
            r"""The type of resource."""
            RESOURCE_TYPE_UNSPECIFIED = 0
            CONSUMER_PROJECT = 1
            ENCRYPTION_KEYS_PROJECT = 2

        resource_id = proto.Field(proto.INT64, number=1,)
        resource_type = proto.Field(
            proto.ENUM, number=2, enum="Workload.ResourceInfo.ResourceType",
        )

    class KMSSettings(proto.Message):
        r"""Settings specific to the Key Management Service.
        Attributes:
            next_rotation_time (google.protobuf.timestamp_pb2.Timestamp):
                Required. Input only. Immutable. The time at
                which the Key Management Service will
                automatically create a new version of the crypto
                key and mark it as the primary.
            rotation_period (google.protobuf.duration_pb2.Duration):
                Required. Input only. Immutable. [next_rotation_time] will
                be advanced by this period when the Key Management Service
                automatically rotates a key. Must be at least 24 hours and
                at most 876,000 hours.
        """

        next_rotation_time = proto.Field(
            proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp,
        )
        rotation_period = proto.Field(
            proto.MESSAGE, number=2, message=duration_pb2.Duration,
        )

    class IL4Settings(proto.Message):
        r"""Settings specific to resources needed for IL4.
        Attributes:
            kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
                Required. Input only. Immutable. Settings
                used to create a CMEK crypto key.
        """

        kms_settings = proto.Field(
            proto.MESSAGE, number=1, message="Workload.KMSSettings",
        )

    class CJISSettings(proto.Message):
        r"""Settings specific to resources needed for CJIS.
        Attributes:
            kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
                Required. Input only. Immutable. Settings
                used to create a CMEK crypto key.
        """

        kms_settings = proto.Field(
            proto.MESSAGE, number=1, message="Workload.KMSSettings",
        )

    class FedrampHighSettings(proto.Message):
        r"""Settings specific to resources needed for FedRAMP High.
        Attributes:
            kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
                Required. Input only. Immutable. Settings
                used to create a CMEK crypto key.
        """

        kms_settings = proto.Field(
            proto.MESSAGE, number=1, message="Workload.KMSSettings",
        )

    class FedrampModerateSettings(proto.Message):
        r"""Settings specific to resources needed for FedRAMP Moderate.
        Attributes:
            kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
                Required. Input only. Immutable. Settings
                used to create a CMEK crypto key.
        """

        kms_settings = proto.Field(
            proto.MESSAGE, number=1, message="Workload.KMSSettings",
        )

    class ResourceSettings(proto.Message):
        r"""Represent the custom settings for the resources to be
        created.

        Attributes:
            resource_id (str):
                Resource identifier. For a project this represents
                project_id. If the project is already taken, the workload
                creation will fail.
            resource_type (google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceInfo.ResourceType):
                Indicates the type of resource. This field should be
                specified to correspond the id to the right project type
                (CONSUMER_PROJECT or ENCRYPTION_KEYS_PROJECT)
        """

        resource_id = proto.Field(proto.STRING, number=1,)
        resource_type = proto.Field(
            proto.ENUM, number=2, enum="Workload.ResourceInfo.ResourceType",
        )

    name = proto.Field(proto.STRING, number=1,)
    display_name = proto.Field(proto.STRING, number=2,)
    resources = proto.RepeatedField(proto.MESSAGE, number=3, message=ResourceInfo,)
    compliance_regime = proto.Field(proto.ENUM, number=4, enum=ComplianceRegime,)
    create_time = proto.Field(proto.MESSAGE, number=5, message=timestamp_pb2.Timestamp,)
    billing_account = proto.Field(proto.STRING, number=6,)
    il4_settings = proto.Field(
        proto.MESSAGE,
        number=7,
        oneof="compliance_regime_settings",
        message=IL4Settings,
    )
    cjis_settings = proto.Field(
        proto.MESSAGE,
        number=8,
        oneof="compliance_regime_settings",
        message=CJISSettings,
    )
    fedramp_high_settings = proto.Field(
        proto.MESSAGE,
        number=11,
        oneof="compliance_regime_settings",
        message=FedrampHighSettings,
    )
    fedramp_moderate_settings = proto.Field(
        proto.MESSAGE,
        number=12,
        oneof="compliance_regime_settings",
        message=FedrampModerateSettings,
    )
    etag = proto.Field(proto.STRING, number=9,)
    labels = proto.MapField(proto.STRING, proto.STRING, number=10,)
    provisioned_resources_parent = proto.Field(proto.STRING, number=13,)
    kms_settings = proto.Field(proto.MESSAGE, number=14, message=KMSSettings,)
    resource_settings = proto.RepeatedField(
        proto.MESSAGE, number=15, message=ResourceSettings,
    )

class CreateWorkloadOperationMetadata(proto.Message):
    r"""Operation metadata to give request details of CreateWorkload.
    Attributes:
        create_time (google.protobuf.timestamp_pb2.Timestamp):
            Optional. Time when the operation was
            created.
        display_name (str):
            Optional. The display name of the workload.
        parent (str):
            Optional. The parent of the workload.
        compliance_regime (google.cloud.assuredworkloads_v1beta1.types.Workload.ComplianceRegime):
            Optional. Compliance controls that should be
            applied to the resources managed by the
            workload.
    """

    create_time = proto.Field(proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp,)
    display_name = proto.Field(proto.STRING, number=2,)
    parent = proto.Field(proto.STRING, number=3,)
    compliance_regime = proto.Field(
        proto.ENUM, number=4, enum="Workload.ComplianceRegime",
    )

__all__ = tuple(sorted(__protobuf__.manifest))
<commit_msg>feat: Add Canada regions and support compliance regime (#73)<commit_after># -*- coding: utf-8 -*-
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import proto  # type: ignore

from google.protobuf import duration_pb2  # type: ignore
from google.protobuf import field_mask_pb2  # type: ignore
from google.protobuf import timestamp_pb2  # type: ignore

__protobuf__ = proto.module(
    package="google.cloud.assuredworkloads.v1beta1",
    manifest={
        "CreateWorkloadRequest",
        "UpdateWorkloadRequest",
        "DeleteWorkloadRequest",
        "GetWorkloadRequest",
        "ListWorkloadsRequest",
        "ListWorkloadsResponse",
        "Workload",
        "CreateWorkloadOperationMetadata",
    },
)

class CreateWorkloadRequest(proto.Message):
    r"""Request for creating a workload.
    Attributes:
        parent (str):
            Required. The resource name of the new Workload's parent.
            Must be of the form
            ``organizations/{org_id}/locations/{location_id}``.
        workload (google.cloud.assuredworkloads_v1beta1.types.Workload):
            Required. Assured Workload to create
        external_id (str):
            Optional. A identifier associated with the
            workload and underlying projects which allows
            for the break down of billing costs for a
            workload. The value provided for the identifier
            will add a label to the workload and contained
            projects with the identifier as the value.
    """

    parent = proto.Field(proto.STRING, number=1,)
    workload = proto.Field(proto.MESSAGE, number=2, message="Workload",)
    external_id = proto.Field(proto.STRING, number=3,)

class UpdateWorkloadRequest(proto.Message):
    r"""Request for Updating a workload.
    Attributes:
        workload (google.cloud.assuredworkloads_v1beta1.types.Workload):
            Required. The workload to update. The workload’s ``name``
            field is used to identify the workload to be updated.
            Format:
            organizations/{org_id}/locations/{location_id}/workloads/{workload_id}
        update_mask (google.protobuf.field_mask_pb2.FieldMask):
            Required. The list of fields to be updated.
    """

    workload = proto.Field(proto.MESSAGE, number=1, message="Workload",)
    update_mask = proto.Field(
        proto.MESSAGE, number=2, message=field_mask_pb2.FieldMask,
    )

class DeleteWorkloadRequest(proto.Message):
    r"""Request for deleting a Workload.
    Attributes:
        name (str):
            Required. The ``name`` field is used to identify the
            workload. Format:
            organizations/{org_id}/locations/{location_id}/workloads/{workload_id}
        etag (str):
            Optional. The etag of the workload.
            If this is provided, it must match the server's
            etag.
    """

    name = proto.Field(proto.STRING, number=1,)
    etag = proto.Field(proto.STRING, number=2,)

class GetWorkloadRequest(proto.Message):
    r"""Request for fetching a workload.
    Attributes:
        name (str):
            Required. The resource name of the Workload to fetch. This
            is the workloads's relative path in the API, formatted as
            "organizations/{organization_id}/locations/{location_id}/workloads/{workload_id}".
            For example,
            "organizations/123/locations/us-east1/workloads/assured-workload-1".
    """

    name = proto.Field(proto.STRING, number=1,)

class ListWorkloadsRequest(proto.Message):
    r"""Request for fetching workloads in an organization.
    Attributes:
        parent (str):
            Required. Parent Resource to list workloads from. Must be of
            the form ``organizations/{org_id}/locations/{location}``.
        page_size (int):
            Page size.
        page_token (str):
            Page token returned from previous request.
            Page token contains context from previous
            request. Page token needs to be passed in the
            second and following requests.
        filter (str):
            A custom filter for filtering by properties
            of a workload. At this time, only filtering by
            labels is supported.
    """

    parent = proto.Field(proto.STRING, number=1,)
    page_size = proto.Field(proto.INT32, number=2,)
    page_token = proto.Field(proto.STRING, number=3,)
    filter = proto.Field(proto.STRING, number=4,)

class ListWorkloadsResponse(proto.Message):
    r"""Response of ListWorkloads endpoint.
    Attributes:
        workloads (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload]):
            List of Workloads under a given parent.
        next_page_token (str):
            The next page token. Return empty if reached
            the last page.
    """

    @property
    def raw_page(self):
        return self

    workloads = proto.RepeatedField(proto.MESSAGE, number=1, message="Workload",)
    next_page_token = proto.Field(proto.STRING, number=2,)

class Workload(proto.Message):
    r"""An Workload object for managing highly regulated workloads of
    cloud customers.

    Attributes:
        name (str):
            Optional. The resource name of the workload.
            Format:
            organizations/{organization}/locations/{location}/workloads/{workload}
            Read-only.
        display_name (str):
            Required. The user-assigned display name of
            the Workload. When present it must be between 4
            to 30 characters. Allowed characters are:
            lowercase and uppercase letters, numbers,
            hyphen, and spaces.

            Example: My Workload
        resources (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceInfo]):
            Output only. The resources associated with
            this workload. These resources will be created
            when creating the workload. If any of the
            projects already exist, the workload creation
            will fail. Always read only.
        compliance_regime (google.cloud.assuredworkloads_v1beta1.types.Workload.ComplianceRegime):
            Required. Immutable. Compliance Regime
            associated with this workload.
        create_time (google.protobuf.timestamp_pb2.Timestamp):
            Output only. Immutable. The Workload creation
            timestamp.
        billing_account (str):
            Input only. The billing account used for the resources which
            are direct children of workload. This billing account is
            initially associated with the resources created as part of
            Workload creation. After the initial creation of these
            resources, the customer can change the assigned billing
            account. The resource name has the form
            ``billingAccounts/{billing_account_id}``. For example,
            ``billingAccounts/012345-567890-ABCDEF``.
        il4_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.IL4Settings):
            Required. Input only. Immutable. Settings
            specific to resources needed for IL4.
        cjis_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.CJISSettings):
            Required. Input only. Immutable. Settings
            specific to resources needed for CJIS.
        fedramp_high_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.FedrampHighSettings):
            Required. Input only. Immutable. Settings
            specific to resources needed for FedRAMP High.
        fedramp_moderate_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.FedrampModerateSettings):
            Required. Input only. Immutable. Settings
            specific to resources needed for FedRAMP
            Moderate.
        etag (str):
            Optional. ETag of the workload, it is
            calculated on the basis of the Workload
            contents. It will be used in Update & Delete
            operations.
        labels (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload.LabelsEntry]):
            Optional. Labels applied to the workload.
        provisioned_resources_parent (str):
            Input only. The parent resource for the resources managed by
            this Assured Workload. May be either empty or a folder
            resource which is a child of the Workload parent. If not
            specified all resources are created under the parent
            organization. Format: folders/{folder_id}
        kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
            Input only. Settings used to create a CMEK
            crypto key. When set a project with a KMS CMEK
            key is provisioned. This field is mandatory for
            a subset of Compliance Regimes.
        resource_settings (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceSettings]):
            Input only. Resource properties that are used
            to customize workload resources. These
            properties (such as custom project id) will be
            used to create workload resources if possible.
            This field is optional.
    """

    class ComplianceRegime(proto.Enum):
        r"""Supported Compliance Regimes."""
        COMPLIANCE_REGIME_UNSPECIFIED = 0
        IL4 = 1
        CJIS = 2
        FEDRAMP_HIGH = 3
        FEDRAMP_MODERATE = 4
        US_REGIONAL_ACCESS = 5
        HIPAA = 6
        HITRUST = 7
        EU_REGIONS_AND_SUPPORT = 8
        CA_REGIONS_AND_SUPPORT = 9

    class ResourceInfo(proto.Message):
        r"""Represent the resources that are children of this Workload.
        Attributes:
            resource_id (int):
                Resource identifier. For a project this represents
                project_number.
            resource_type (google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceInfo.ResourceType):
                Indicates the type of resource.
        """

        class ResourceType(proto.Enum):
            r"""The type of resource."""
            RESOURCE_TYPE_UNSPECIFIED = 0
            CONSUMER_PROJECT = 1
            CONSUMER_FOLDER = 4
            ENCRYPTION_KEYS_PROJECT = 2
            KEYRING = 3

        resource_id = proto.Field(proto.INT64, number=1,)
        resource_type = proto.Field(
            proto.ENUM, number=2, enum="Workload.ResourceInfo.ResourceType",
        )

    class KMSSettings(proto.Message):
        r"""Settings specific to the Key Management Service.
        Attributes:
            next_rotation_time (google.protobuf.timestamp_pb2.Timestamp):
                Required. Input only. Immutable. The time at
                which the Key Management Service will
                automatically create a new version of the crypto
                key and mark it as the primary.
            rotation_period (google.protobuf.duration_pb2.Duration):
                Required. Input only. Immutable. [next_rotation_time] will
                be advanced by this period when the Key Management Service
                automatically rotates a key. Must be at least 24 hours and
                at most 876,000 hours.
        """

        next_rotation_time = proto.Field(
            proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp,
        )
        rotation_period = proto.Field(
            proto.MESSAGE, number=2, message=duration_pb2.Duration,
        )

    class IL4Settings(proto.Message):
        r"""Settings specific to resources needed for IL4.
        Attributes:
            kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
                Required. Input only. Immutable. Settings
                used to create a CMEK crypto key.
        """

        kms_settings = proto.Field(
            proto.MESSAGE, number=1, message="Workload.KMSSettings",
        )

    class CJISSettings(proto.Message):
        r"""Settings specific to resources needed for CJIS.
        Attributes:
            kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
                Required. Input only. Immutable. Settings
                used to create a CMEK crypto key.
        """

        kms_settings = proto.Field(
            proto.MESSAGE, number=1, message="Workload.KMSSettings",
        )

    class FedrampHighSettings(proto.Message):
        r"""Settings specific to resources needed for FedRAMP High.
        Attributes:
            kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
                Required. Input only. Immutable. Settings
                used to create a CMEK crypto key.
        """

        kms_settings = proto.Field(
            proto.MESSAGE, number=1, message="Workload.KMSSettings",
        )

    class FedrampModerateSettings(proto.Message):
        r"""Settings specific to resources needed for FedRAMP Moderate.
        Attributes:
            kms_settings (google.cloud.assuredworkloads_v1beta1.types.Workload.KMSSettings):
                Required. Input only. Immutable. Settings
                used to create a CMEK crypto key.
        """

        kms_settings = proto.Field(
            proto.MESSAGE, number=1, message="Workload.KMSSettings",
        )

    class ResourceSettings(proto.Message):
        r"""Represent the custom settings for the resources to be
        created.

        Attributes:
            resource_id (str):
                Resource identifier. For a project this represents
                project_id. If the project is already taken, the workload
                creation will fail.
            resource_type (google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceInfo.ResourceType):
                Indicates the type of resource. This field should be
                specified to correspond the id to the right project type
                (CONSUMER_PROJECT or ENCRYPTION_KEYS_PROJECT)
            display_name (str):
                User-assigned resource display name.
                If not empty it will be used to create a
                resource with the specified name.
        """

        resource_id = proto.Field(proto.STRING, number=1,)
        resource_type = proto.Field(
            proto.ENUM, number=2, enum="Workload.ResourceInfo.ResourceType",
        )
        display_name = proto.Field(proto.STRING, number=3,)

    name = proto.Field(proto.STRING, number=1,)
    display_name = proto.Field(proto.STRING, number=2,)
    resources = proto.RepeatedField(proto.MESSAGE, number=3, message=ResourceInfo,)
    compliance_regime = proto.Field(proto.ENUM, number=4, enum=ComplianceRegime,)
    create_time = proto.Field(proto.MESSAGE, number=5, message=timestamp_pb2.Timestamp,)
    billing_account = proto.Field(proto.STRING, number=6,)
    il4_settings = proto.Field(
        proto.MESSAGE,
        number=7,
        oneof="compliance_regime_settings",
        message=IL4Settings,
    )
    cjis_settings = proto.Field(
        proto.MESSAGE,
        number=8,
        oneof="compliance_regime_settings",
        message=CJISSettings,
    )
    fedramp_high_settings = proto.Field(
        proto.MESSAGE,
        number=11,
        oneof="compliance_regime_settings",
        message=FedrampHighSettings,
    )
    fedramp_moderate_settings = proto.Field(
        proto.MESSAGE,
        number=12,
        oneof="compliance_regime_settings",
        message=FedrampModerateSettings,
    )
    etag = proto.Field(proto.STRING, number=9,)
    labels = proto.MapField(proto.STRING, proto.STRING, number=10,)
    provisioned_resources_parent = proto.Field(proto.STRING, number=13,)
    kms_settings = proto.Field(proto.MESSAGE, number=14, message=KMSSettings,)
    resource_settings = proto.RepeatedField(
        proto.MESSAGE, number=15, message=ResourceSettings,
    )

class CreateWorkloadOperationMetadata(proto.Message):
    r"""Operation metadata to give request details of CreateWorkload.
    Attributes:
        create_time (google.protobuf.timestamp_pb2.Timestamp):
            Optional. Time when the operation was
            created.
        display_name (str):
            Optional. The display name of the workload.
        parent (str):
            Optional. The parent of the workload.
        compliance_regime (google.cloud.assuredworkloads_v1beta1.types.Workload.ComplianceRegime):
            Optional. Compliance controls that should be
            applied to the resources managed by the
            workload.
        resource_settings (Sequence[google.cloud.assuredworkloads_v1beta1.types.Workload.ResourceSettings]):
            Optional. Resource properties in the input
            that are used for creating/customizing workload
            resources.
    """

    create_time = proto.Field(proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp,)
    display_name = proto.Field(proto.STRING, number=2,)
    parent = proto.Field(proto.STRING, number=3,)
    compliance_regime = proto.Field(
        proto.ENUM, number=4, enum="Workload.ComplianceRegime",
    )
    resource_settings = proto.RepeatedField(
        proto.MESSAGE, number=5, message="Workload.ResourceSettings",
    )

__all__ = tuple(sorted(__protobuf__.manifest))
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Addons modules by CLEARCORP S.A.
#    Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from report import report_sxw
from tools.translate import _
import pooler
from osv import fields,osv

from openerp.addons.account_financial_report_webkit.report.trial_balance import TrialBalanceWebkit
from openerp.addons.account_financial_report_webkit.report.webkit_parser_header_fix import HeaderFooterTextWebKitParser

def sign(number):
    return cmp(number, 0)

class IncomeStatementReport(TrialBalanceWebkit):
    def __init__(self, cr, uid, name, context):
        super(IncomeStatementReport, self).__init__(cr, uid, name, context=context)
        self.pool = pooler.get_pool(self.cr.dbname)
        self.cursor = self.cr
        #This line is to delete, the header of trial balance
        self.localcontext['additional_args'][4] = ('--header-left', '')
        self.localcontext.update({
            'cr': self.cr,
            'uid': self.uid,
            'get_fiscalyear': self.get_fiscalyear,
            'get_last_period': self.get_last_period,
            'get_data': self.get_data,
        })

    def set_context(self, objects, data, ids, report_type=None):
        start_period = self._get_form_param('period_from', data)

        self.localcontext.update({
            'start_period': start_period,
            })
        return super(IncomeStatementReport, self).set_context(objects, data, ids, report_type=report_type)

    def get_last_period_fiscalyear(self, cr, uid, fiscalyear):
        account_period_obj = self.pool.get('account.period')
        period_ids = account_period_obj.search(cr, uid, [('fiscalyear_id', '=', fiscalyear.id), ('special', '=', False)])
        periods = account_period_obj.browse(cr, uid, period_ids)
        period_select = periods[0]
        for current_period in periods:
            if current_period.date_start > period_select.date_start:
                period_select = current_period
        return period_select

    def get_last_period(self, cr, uid, start_period):
        account_period_obj = self.pool.get('account.period')
        period_ids = account_period_obj.search(cr, uid, [('fiscalyear_id', '=', start_period.fiscalyear_id.id), ('special', '=', False)])
        periods = account_period_obj.browse(cr, uid, period_ids)
        period_select = start_period
        for period in periods:
            if (period.date_start < start_period.date_start and period.date_start > period_select.date_start) or (period.date_start < start_period.date_start and start_period == period_select):
                period_select = period
        if period_select == start_period:
            fiscalyear = self.get_fiscalyear(cr, uid, start_period)
            fiscalyear_select = fiscalyear
            account_fiscalyear_obj = self.pool.get('account.fiscalyear')
            all_fiscalyears_ids = account_fiscalyear_obj.search(cr, uid, [])
            all_fiscalyears = account_fiscalyear_obj.browse(cr, uid, all_fiscalyears_ids)
            for current_fiscalyear in all_fiscalyears:
                if (current_fiscalyear.date_start < fiscalyear.date_start and current_fiscalyear.date_start > fiscalyear_select.date_start) or (current_fiscalyear.date_start < fiscalyear.date_start and fiscalyear == fiscalyear_select):
                    fiscalyear_select = current_fiscalyear
            if fiscalyear_select == fiscalyear:
                raise osv.except_osv(_('Error fiscal year'),_('There is no previous period to compare'))
            period_select = self.get_last_period_fiscalyear(cr, uid, fiscalyear_select)
        return period_select

    def get_fiscalyear(self, cr, uid, start_period):
        fiscalyear = start_period.fiscalyear_id
        return fiscalyear

    def get_opening_period(self, cr, uid, select_period, context=None):
        fiscalyear = select_period.fiscalyear_id
        period_obj = self.pool.get('account.period')
        special_period_ids = period_obj.search(cr, uid, ['&',('fiscalyear_id','=',fiscalyear.id),('special','=',True)], context=context)
        special_periods = period_obj.browse(cr, uid, special_period_ids, context=context)
        opening_period = False
        for period in special_periods:
            if not opening_period:
                opening_period = period
            elif opening_period.date_start > period.date_start:
                opening_period = period
        return opening_period

    def get_data(self, cr, uid, data, context={}):
        account_account_obj = self.pool.get('account.account')
        account_period_obj = self.pool.get('account.period')
        library_obj = self.pool.get('account.webkit.report.library')

        #TODO: remove dependency of c2c
        account_chart_id = self._get_form_param('chart_account_id', data)

        account_chart = account_account_obj.browse(cr, uid, account_chart_id)
        company_id = account_chart['company_id'].id
        category_account_ids = library_obj.get_category_accounts(cr, uid, company_id)
        period = account_period_obj.browse(cr, uid, self._get_form_param('period_from', data))
        fiscal_year = self.get_opening_period(cr, uid, period)
        opening_period = get_opening_period(cr, uid, period)

        #build account_ids list
        asset_account_ids = library_obj.get_account_child_ids(cr, uid, category_account_ids['asset'])
        liability_account_ids = library_obj.get_account_child_ids(cr, uid, category_account_ids['liability'])
        equity_account_ids = library_obj.get_account_child_ids(cr, uid, category_account_ids['equity'])
        income_account_id = category_account_ids['income'].id
        expense_account_id = category_account_ids['expense'].id

        #build accounts list
        asset_accounts = account_account_obj.browse(cr, uid, asset_account_ids)
        liability_accounts = account_account_obj.browse(cr, uid, liability_account_ids)
        equity_accounts = account_account_obj.browse(cr, uid, equity_account_ids)
        income_account = category_account_ids['income']
        expense_account = category_account_ids['expense']

        #build balances
        asset_period_balances =     library_obj.get_account_balance(cr, uid, asset_account_ids,  ['balance'], start_period_id=period.id, end_period_id=period.id)
        liability_period_balances = library_obj.get_account_balance(cr, uid, liability_account_ids, ['balance'], start_period_id=period.id, end_period_id=period.id)
        equity_period_balances =    library_obj.get_account_balance(cr, uid, equity_account_ids, ['balance'], start_period_id=period.id, end_period_id=period.id)
        income_period_balance =     library_obj.get_account_balance(cr, uid, [income_account_id],  ['balance'], start_period_id=period.id, end_period_id=period.id)
        expense_period_balance =    library_obj.get_account_balance(cr, uid, [expense_account_id], ['balance'], start_period_id=period.id, end_period_id=period.id)

        asset_fiscal_year_balances =     library_obj.get_account_balance(cr, uid, asset_account_ids,  ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)
        liability_fiscal_year_balances = library_obj.get_account_balance(cr, uid, liability_account_ids, ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)
        equity_fiscal_year_balances =    library_obj.get_account_balance(cr, uid, equity_account_ids, ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)
        income_fiscal_year_balance =     library_obj.get_account_balance(cr, uid, [income_account_id],  ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)
        expense_fiscal_year_balance =    library_obj.get_account_balance(cr, uid, [expense_account_id], ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)

        #build total balances
        total_asset_balances = {
            'period':       asset_period_balances[category_account_ids['asset'].id]['balance'],
            'fiscal_year':  asset_fiscal_year_balances[category_account_ids['asset'].id]['balance'],
        }

        total_liability_balances = {
            'period':       liability_period_balances[category_account_ids['liability'].id]['balance'],
            'fiscal_year':  liability_fiscal_year_balances[category_account_ids['liability'].id]['balance'],
        }

        total_equity_balances = {
            'period':       equity_period_balances[category_account_ids['equity'].id]['balance'],
            'fiscal_year':  equity_fiscal_year_balances[category_account_ids['equity'].id]['balance'],
        }

        total_income_balance = {
            'period':       income_period_balances[category_account_ids['income'].id]['balance'],
            'fiscal_year':  income_fiscal_year_balances[category_account_ids['income'].id]['balance'],
        }
        total_expense_balance = {
            'period':       expense_period_balances[category_account_ids['expense'].id]['balance'],
            'fiscal_year':  expense_fiscal_year_balances[category_account_ids['expense'].id]['balance'],
        }

        return {
            'asset_accounts':                   asset_accounts,
            'liability_accounts':               liability_accounts,
            'equity_accounts':                  equity_accounts,
            'income_account':                   income_account,
            'expense_account':                  expense_account,
            'asset_accounts_ids':               asset_account_ids,
            'liability_account_ids':            liability_account_ids,
            'equity_account_ids':               equity_account_ids,
            'income_account_id':                income_account_id,
            'expense_account_id':               expense_account_id,
            'total_asset_balances':             total_asset_balances,
            'total_liability_balances':         total_liability_balances,
            'total_equity_balances':            total_equity_balances,
            'total_income_balance':             total_income_balance,
            'total_expense_balance':            total_expense_balance,
            'asset_period_balances':            asset_period_balances,
            'liability_period_balances':        liability_period_balances,
            'equity_period_balances':           equity_period_balances,
            'asset_fiscal_year_balances':       asset_fiscal_year_balances,
            'liability_fiscal_year_balances':   liability_fiscal_year_balances,
            'equity_fiscal_year_balances':      equity_fiscal_year_balances,
        }

HeaderFooterTextWebKitParser(
    'report.l10n_cr_account_financial_statements.account.situation_balance_report',
    'account.account',
    'addons/l10n_cr_account_financial_statements/report/situation_balance_report.mako',
    parser=IncomeStatementReport)
<commit_msg>[FIX] self. missing<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Addons modules by CLEARCORP S.A.
#    Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from report import report_sxw
from tools.translate import _
import pooler
from osv import fields,osv

from openerp.addons.account_financial_report_webkit.report.trial_balance import TrialBalanceWebkit
from openerp.addons.account_financial_report_webkit.report.webkit_parser_header_fix import HeaderFooterTextWebKitParser

def sign(number):
    return cmp(number, 0)

class IncomeStatementReport(TrialBalanceWebkit):
    def __init__(self, cr, uid, name, context):
        super(IncomeStatementReport, self).__init__(cr, uid, name, context=context)
        self.pool = pooler.get_pool(self.cr.dbname)
        self.cursor = self.cr
        #This line is to delete, the header of trial balance
        self.localcontext['additional_args'][4] = ('--header-left', '')
        self.localcontext.update({
            'cr': self.cr,
            'uid': self.uid,
            'get_fiscalyear': self.get_fiscalyear,
            'get_last_period': self.get_last_period,
            'get_data': self.get_data,
        })

    def set_context(self, objects, data, ids, report_type=None):
        start_period = self._get_form_param('period_from', data)

        self.localcontext.update({
            'start_period': start_period,
            })
        return super(IncomeStatementReport, self).set_context(objects, data, ids, report_type=report_type)

    def get_last_period_fiscalyear(self, cr, uid, fiscalyear):
        account_period_obj = self.pool.get('account.period')
        period_ids = account_period_obj.search(cr, uid, [('fiscalyear_id', '=', fiscalyear.id), ('special', '=', False)])
        periods = account_period_obj.browse(cr, uid, period_ids)
        period_select = periods[0]
        for current_period in periods:
            if current_period.date_start > period_select.date_start:
                period_select = current_period
        return period_select

    def get_last_period(self, cr, uid, start_period):
        account_period_obj = self.pool.get('account.period')
        period_ids = account_period_obj.search(cr, uid, [('fiscalyear_id', '=', start_period.fiscalyear_id.id), ('special', '=', False)])
        periods = account_period_obj.browse(cr, uid, period_ids)
        period_select = start_period
        for period in periods:
            if (period.date_start < start_period.date_start and period.date_start > period_select.date_start) or (period.date_start < start_period.date_start and start_period == period_select):
                period_select = period
        if period_select == start_period:
            fiscalyear = self.get_fiscalyear(cr, uid, start_period)
            fiscalyear_select = fiscalyear
            account_fiscalyear_obj = self.pool.get('account.fiscalyear')
            all_fiscalyears_ids = account_fiscalyear_obj.search(cr, uid, [])
            all_fiscalyears = account_fiscalyear_obj.browse(cr, uid, all_fiscalyears_ids)
            for current_fiscalyear in all_fiscalyears:
                if (current_fiscalyear.date_start < fiscalyear.date_start and current_fiscalyear.date_start > fiscalyear_select.date_start) or (current_fiscalyear.date_start < fiscalyear.date_start and fiscalyear == fiscalyear_select):
                    fiscalyear_select = current_fiscalyear
            if fiscalyear_select == fiscalyear:
                raise osv.except_osv(_('Error fiscal year'),_('There is no previous period to compare'))
            period_select = self.get_last_period_fiscalyear(cr, uid, fiscalyear_select)
        return period_select

    def get_fiscalyear(self, cr, uid, start_period):
        fiscalyear = start_period.fiscalyear_id
        return fiscalyear

    def get_opening_period(self, cr, uid, select_period, context=None):
        fiscalyear = select_period.fiscalyear_id
        period_obj = self.pool.get('account.period')
        special_period_ids = period_obj.search(cr, uid, ['&',('fiscalyear_id','=',fiscalyear.id),('special','=',True)], context=context)
        special_periods = period_obj.browse(cr, uid, special_period_ids, context=context)
        opening_period = False
        for period in special_periods:
            if not opening_period:
                opening_period = period
            elif opening_period.date_start > period.date_start:
                opening_period = period
        return opening_period

    def get_data(self, cr, uid, data, context={}):
        account_account_obj = self.pool.get('account.account')
        account_period_obj = self.pool.get('account.period')
        library_obj = self.pool.get('account.webkit.report.library')

        #TODO: remove dependency of c2c
        account_chart_id = self._get_form_param('chart_account_id', data)

        account_chart = account_account_obj.browse(cr, uid, account_chart_id)
        company_id = account_chart['company_id'].id
        category_account_ids = library_obj.get_category_accounts(cr, uid, company_id)
        period = account_period_obj.browse(cr, uid, self._get_form_param('period_from', data))
        fiscal_year = self.get_opening_period(cr, uid, period)
        opening_period = self.get_opening_period(cr, uid, period)

        #build account_ids list
        asset_account_ids = library_obj.get_account_child_ids(cr, uid, category_account_ids['asset'])
        liability_account_ids = library_obj.get_account_child_ids(cr, uid, category_account_ids['liability'])
        equity_account_ids = library_obj.get_account_child_ids(cr, uid, category_account_ids['equity'])
        income_account_id = category_account_ids['income'].id
        expense_account_id = category_account_ids['expense'].id

        #build accounts list
        asset_accounts = account_account_obj.browse(cr, uid, asset_account_ids)
        liability_accounts = account_account_obj.browse(cr, uid, liability_account_ids)
        equity_accounts = account_account_obj.browse(cr, uid, equity_account_ids)
        income_account = category_account_ids['income']
        expense_account = category_account_ids['expense']

        #build balances
        asset_period_balances =     library_obj.get_account_balance(cr, uid, asset_account_ids,  ['balance'], start_period_id=period.id, end_period_id=period.id)
        liability_period_balances = library_obj.get_account_balance(cr, uid, liability_account_ids, ['balance'], start_period_id=period.id, end_period_id=period.id)
        equity_period_balances =    library_obj.get_account_balance(cr, uid, equity_account_ids, ['balance'], start_period_id=period.id, end_period_id=period.id)
        income_period_balance =     library_obj.get_account_balance(cr, uid, [income_account_id],  ['balance'], start_period_id=period.id, end_period_id=period.id)
        expense_period_balance =    library_obj.get_account_balance(cr, uid, [expense_account_id], ['balance'], start_period_id=period.id, end_period_id=period.id)

        asset_fiscal_year_balances =     library_obj.get_account_balance(cr, uid, asset_account_ids,  ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)
        liability_fiscal_year_balances = library_obj.get_account_balance(cr, uid, liability_account_ids, ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)
        equity_fiscal_year_balances =    library_obj.get_account_balance(cr, uid, equity_account_ids, ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)
        income_fiscal_year_balance =     library_obj.get_account_balance(cr, uid, [income_account_id],  ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)
        expense_fiscal_year_balance =    library_obj.get_account_balance(cr, uid, [expense_account_id], ['balance'], fiscal_year_id=fiscal_year.id, end_period_id=period.id)

        #build total balances
        total_asset_balances = {
            'period':       asset_period_balances[category_account_ids['asset'].id]['balance'],
            'fiscal_year':  asset_fiscal_year_balances[category_account_ids['asset'].id]['balance'],
        }

        total_liability_balances = {
            'period':       liability_period_balances[category_account_ids['liability'].id]['balance'],
            'fiscal_year':  liability_fiscal_year_balances[category_account_ids['liability'].id]['balance'],
        }

        total_equity_balances = {
            'period':       equity_period_balances[category_account_ids['equity'].id]['balance'],
            'fiscal_year':  equity_fiscal_year_balances[category_account_ids['equity'].id]['balance'],
        }

        total_income_balance = {
            'period':       income_period_balances[category_account_ids['income'].id]['balance'],
            'fiscal_year':  income_fiscal_year_balances[category_account_ids['income'].id]['balance'],
        }
        total_expense_balance = {
            'period':       expense_period_balances[category_account_ids['expense'].id]['balance'],
            'fiscal_year':  expense_fiscal_year_balances[category_account_ids['expense'].id]['balance'],
        }

        return {
            'asset_accounts':                   asset_accounts,
            'liability_accounts':               liability_accounts,
            'equity_accounts':                  equity_accounts,
            'income_account':                   income_account,
            'expense_account':                  expense_account,
            'asset_accounts_ids':               asset_account_ids,
            'liability_account_ids':            liability_account_ids,
            'equity_account_ids':               equity_account_ids,
            'income_account_id':                income_account_id,
            'expense_account_id':               expense_account_id,
            'total_asset_balances':             total_asset_balances,
            'total_liability_balances':         total_liability_balances,
            'total_equity_balances':            total_equity_balances,
            'total_income_balance':             total_income_balance,
            'total_expense_balance':            total_expense_balance,
            'asset_period_balances':            asset_period_balances,
            'liability_period_balances':        liability_period_balances,
            'equity_period_balances':           equity_period_balances,
            'asset_fiscal_year_balances':       asset_fiscal_year_balances,
            'liability_fiscal_year_balances':   liability_fiscal_year_balances,
            'equity_fiscal_year_balances':      equity_fiscal_year_balances,
        }

HeaderFooterTextWebKitParser(
    'report.l10n_cr_account_financial_statements.account.situation_balance_report',
    'account.account',
    'addons/l10n_cr_account_financial_statements/report/situation_balance_report.mako',
    parser=IncomeStatementReport)
<|endoftext|>