Beispiel #1
0
class Trigger(object):
	"""Match/action triggers for a server.
	All objects in this class are created by Triggers objects.
	"""
	def __init__(self, parent, name):
		# Parent is the Triggers object that created this one.
		# name is a unique name for this trigger.
		self.parent = parent
		self.name = name
		self.matches = OrderedDict()
		self.actions = OrderedDict()

	def __hash__(self):
		"""For sets.
		"""
		return hash(self.name)

	def __eq__(self, other):
		"""Makes comparison for equality work reasonably.
		Action and match lists must match; parents need not.
		"""
		return (
			self.name == other.name
			and self.matches == other.matches
			and self.actions == other.actions
		)
	def __ne__(self, other):
		"""Makes comparison for equality work reasonably.
		"""
		return not self.__eq__(other)

	def addMatch(self, matchSpec, matchName=""):
		"""Add one match to this trigger.
		matchSpec should be a ParmLine where the event and parameter values are regexps.
		matchName can name the match arbitrarily.
		"""
		if not matchName: matchName = "(match%03d)" % (len(self.matches)+1)
		match = Struct()
		match.name = matchName
		match.value = matchSpec
		# This allows replacements by exact name match.
		self.matches[matchName] = match

	def addAction(self, actionSpec, actionName=""):
		"""Add one action to this trigger.
		actionSpec should be an action to perform.
		actionName can name the action arbitrarily.
		"""
		if not actionName: actionName = "(action%03d)" % (len(self.actions)+1)
		action = Struct()
		action.name = actionName
		action.value = actionSpec
		# This allows replacements by exact name match.
		self.actions[actionName] = action

	def apply(self, parmline):
		"""Apply actions if and only if there is a match.
		"""
		for match in self.matches.values():
			if not self._isMatch(match, parmline): continue
			uinfo = ""
			if parmline.parms.get("userid"):
				uinfo = " (userid %s)" % (parmline.parms.userid)
			# Use errorFromEvent instead of outputFromEvent so it's not
			# silent if the server is marked silent.
			self.parent.server.errorFromEvent("%s triggers %s %s%s" % (
				parmline.event,
				self.name,
				match.name or match.value,
				uinfo
			))
			for action in self.actions.values():
				actionData = Struct()
				actionData.parmline = parmline
				actionData.match = match
				actionData.action = action
				self._doAction(actionData)
			return True
		return False

	def _isMatch(self, match, eventline):
		"""Return True on a match.
		match is a name,value struct where value is a
		ParmLine where the event and parameter values are regexps.
		eventline is an actual event line as the name implies.
		Matching is forced to be case-insensitive.
		Matches also implicitly start with ^ and end with $,
		so they must match the entire event or parameter value.
		Special cases of match.value:
			nodecode: True if eventline contains nulls or illegal UTF-8 sequences.
			line match=...: A regular expression match against the whole line.
		"""
		m = match.value
		if m.event.lower() == "nodecode":
			# Check for lines that will confuse TeamTalk 4.3.0.1891 and older.
			if chr(0) in eventline.initLine:
				return True
			try: eventline.initLine.decode("utf-8")
			except UnicodeDecodeError:
				return True
			return False
		# Whole-line matches.
		# Format: line match=<re>.
		if m.event.lower() == "line" and m.parms.get("match"):
			regexp = m.parms["match"]
			if re.match('^'+regexp+'$', eventline.initLine, re.IGNORECASE):
				return True
			return False
		# Normal RE event match and parms.
		if not re.match('^'+m.event+'$', eventline.event, re.IGNORECASE):
			return False
		# matchKey and matchRE are keys and regexps to match against
		# event parameter values.
		for matchKey in m.parms:
			matchRE = m.parms[matchKey]
			if matchKey == "address":
				# This one is special/magical:
				# It tries to match against any ".*addr" eventline key,
				# and it uses special logic, not regexp logic, to match.
				# First collect the address keys, e.g., ipaddr/udpaddr.
				addrkeys = filter(lambda k: k.endswith("addr"), eventline.parms.keys())
				# Then check each for a match.
				matched = False
				for ak in addrkeys:
					addr = eventline.parms[ak]
					if self._matchAddress(matchRE, addr):
						matched = True
						break
				if not matched: return False
			# Not a "magical" address match.
			elif not eventline.parms.has_key(matchKey): return False
			elif not re.match('^'+matchRE+'$', eventline.parms[matchKey], re.IGNORECASE):
				return False
		return True

	def _matchAddress(self, matchval, addr):
		"""Indicate if the given address matches matchval.
		Matchval should be a full address or the first part of one.
		Addr should be an event parameter value.
		Helper for isMatch().
		"""
		# Remove any extra brackets/port, often found on UDP address values.
		if "[" in addr and "]" in addr:
			addr = re.findall(r'^\[(.*?)]', addr)[0]
		# Allow IPV4 and IPV6 addresses with the same content to match.
		if not matchval.startswith(":"):
			addr = re.sub(r'^(?i)::ffff:', '', addr)
		# Remove any trailing port from an IPV4 address.
		addr = re.sub(r':\d+$', '', addr)
		# If this is a partial address, ad a dott to avoid partial number matches.
		if len(matchval.split(".")) < 4:
			matchval += "."
		# And finally do a left-side simple match.
		return addr.startswith(matchval)

	def _doAction(self, actionData):
		"""Perform one action.
		actionData properties:
			eventline: The ParmLine for the event that fired the trigger.
			match: The name,value struct for the match that matched this event.
				match.value is the ParmLine that matched this event.
			action: The name,value struct for the action to perform.
				action.value is the actual command to perform.
		match.name and action.name may be null.
		Substitutions: A string in an action like %(userid)
		becomes something like userid="123" in the actually sent command.
		If the action begins with "send," it is not sent through the
		command processor but sent directly to this server, after any
		substitutions.
		If the command begins with "say," the rest of the line is
		spoken if possible.
		"""
		a = actionData.action.value
		parmline = actionData.parmline
		# Include any parameters from the matched line.
		# We do this manually rather than with % so we can control
		# what happens when the author asks for something that doesn't exist.
		# We throw an error in such a case.
		ms = lambda m: self._doSubs(m, parmline.parms)
		a = re.sub(r'%\((\S+?)\)', ms, a)
		sendFunc = None
		if a.lower().startswith("send "):
			sendFunc = self.parent.server.send
		elif a.lower().startswith("sendwithwait "):
			sendFunc = self.parent.server.sendWithWait
		if sendFunc:
			# Remove the "send[WithWait]" part, then send it.
			a = a.split(None, 1)[1]
			sendFunc(ParmLine(a))
			return
		if a.lower().startswith("say "):
			# Remove the "say" part, then say it.
			a = a.split(None, 1)[1]
			mycmd_say(a)
			return
		# Make the action apply to the right server.
		a = "server %s %s" % (self.parent.server.shortname, a)
		# Run the command as if typed by the user.
		self.parent.runCommand(a)

	def _doSubs(self, m, parms):
		"""Do substitutions like for %(userid) in actions.
		"""
		k = m.groups()[0]
		excludeParmName = False
		if k.startswith("!"):
			excludeParmName = True
			k = k[1:]
		val = parms[k]
		if not excludeParmName:
			val = '%s="%s"' % (k, val)
		return val
Beispiel #2
0
class comboBox(QComboBox,widgetState):
    def __init__(self,widget,label=None, displayLabel=True, 
    items=None, editable=False, orientation='horizontal',callback = None,**kwargs):
        kwargs.setdefault('includeInReports', True)
        kwargs.setdefault('sizePolicy', QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
        widgetState.__init__(self,widget,label,**kwargs)
        QComboBox.__init__(self,self.controlArea)
        
        if displayLabel:
            self.hb = widgetBox(self.controlArea,orientation=orientation)
            lb = widgetLabel(self.hb, label)
            self.hb.layout().addWidget(self)
            self.hasLabel = True
            self.hb.layout().setAlignment(lb,Qt.AlignRight)
            lb.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        else:
            self.controlArea.layout().addWidget(self)
            self.hasLabel = False
        self.label = label
        
        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
        
        self.items = OrderedDict()
        self.setEditable(editable)

        if items:
            self.addItems(items)

        if callback:
            QObject.connect(self, SIGNAL('activated(int)'), callback)
    def getSettings(self):            
        """Standard getSettings"""
        r = {'items':self.items,
             'current':self.currentIndex()}
        return r
    
    def loadSettings(self,data):
        """Standard loadSettings"""
        # print _('in comboBox load')
        # print data

        self.update(data.get('items', []))
        if data.get('current', None) != None:
            self.setCurrentIndex(data['current'])
    
    def currentId(self):
        """Returns the current ID"""
        try:
            return self.items.keys()[self.currentIndex()]
        except:
            return None
    def currentItem(self):
        """Returns the current key value pair"""
        return {self.items.keys()[self.currentIndex()]:self.items.values()[self.currentIndex()]}
    def setCurrentId(self,id):
        """Sets the current ID, the ID's value will apear in the comboBox"""
        try:
            self.setCurrentIndex(self.items.keys().index(id))
        except:
            pass
    def addItems(self,items):
        """Adds items to the comboBox, new items will appear after old ones"""
        if type(items) in [dict,OrderedDict]:
            for k,v in items.items():
                self.addItem(k,v)
        elif type(items) in [list]:
            if len(items) > 0 and type(items[0]) is tuple:
                for k,v in items:
                    self.addItem(k,v)
            else:
                for v in items:
                    self.addItem(v,v)
            # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In listBox should not use list'))
        else:
            raise Exception(_('In comboBox, addItems takes a list, dict or OrderedDict'))
    
    def update(self, items):
        """Clears the comboBox and adds new items, sets the current ID to the previously selected ID if found in the items"""
        current = self.currentId()
        self.clear()
        self.addItems(items)
        self.setCurrentId(current)
        
    def clear(self):
        """Removes all items from the comboBox"""
        QComboBox.clear(self)
        self.items = OrderedDict()
    def addItem(self,id,item):
        """Adds a single item"""
        QComboBox.addItem(self,item)
        self.items[id] = item
            
    def getReportText(self, fileDir):
        """Standard getReportText"""
        r = {self.widgetName:{'includeInReports': self.includeInReports, 'text': self.currentText()}}
        #return '%s set to %s' % (self.label, self.currentText())
        return r
Beispiel #3
0
class Triggers(object):
	"""Match/action triggers for a server.
	"""
	def __init__(self, commandFunc):
		self.runCommand = commandFunc
		self.triggers = OrderedDict()
		self.thr = None
		self._q = []

	def __hash__(self):
		"""For sets.
		"""
		return hash(self.triggers)

	def __eq__(self, other):
		"""Makes comparison for equality work reasonably.
		"""
		return self.triggers == other.triggers
	def __ne__(self, other):
		"""Makes comparison for equality work reasonably.
		"""
		return not self.__eq__(other)

	def get(self, name):
		"""Get and/or make the trigger object for the given name.
		"""
		if not self.triggers.get(name):
			self.triggers[name] = Trigger(self, name)
		return self.triggers[name]

	def addMatch(self, triggerName, matchSpec, matchName=""):
		"""Add one match to a trigger.
		triggerName should uniquely identify a set of matches and associated
		actions, to separate them from any other match/action sets.
		matchSpec should be a ParmLine where the event and parameter values are regexps.
		matchName can name the match arbitrarily.
		"""
		trigger = self.get(triggerName)
		trigger.addMatch(matchSpec, matchName)

	def addAction(self, triggerName, actionSpec, actionName=""):
		"""Add one action to a trigger.
		triggerName should uniquely identify a set of matches and associated
		actions, to separate them from any other match/action sets.
		actionSpec should be an action to perform.
		actionName can name the action arbitrarily.
		"""
		trigger = self.get(triggerName)
		trigger.addAction(actionSpec, actionName)

	def apply(self, parmline):
		"""Apply actions where there is a match.
		As many match/action sets as match will have their actions applied.
		"""
		# config file triggers first.
		[trigger.apply(parmline) for trigger in self.triggers.values()]
		# Then custom code triggers if any.
		trigger_cc.apply(self.server, parmline, self.runCommand)

	@classmethod
	def loadCustomCode(cls):
		"""Load custom trigger code if it exists.
		"""
		reload(trigger_cc)

	def queue(self, parmline):
		"""Queues a trigger check instead of applying it immediately.
		"""
		self._q.append(parmline)
		if not self.thr:
			thr = threading.Thread(target=self._queueWatch)
			thr.daemon = True
			thr.start()

	def _queueWatch(self):
		"""Watch the queue for things to do.
		Runs in its own thread as started by queue().
		"""
		while True:
			if not self._q:
				sleep(0.5)
				continue
			parmline = self._q.pop(0)
			self.apply(parmline)
Beispiel #4
0
class Project(tmt.EclipseProject):
    def __init__(self, *args, **kwargs):
        tmt.EclipseProject.__init__(self, *args, **kwargs)
        tmt.WinstoneServer = self
        self.main = "net.gnehzr.tnoodle.server.TNoodleServer"
        self.argv = ['--nobrowser', '--consoleLevel=INFO']

        # Winstone does all of these things =(.
        self.ignoredWarnings += ['unchecked']
        self.ignoredWarnings += ['deprecation']
        self.ignoredWarnings += ['serial']
        self.ignoredWarnings += ['dep-ann']
        self.ignoredWarnings += ['rawtypes']

        # It is important that when we iterate through the plugins
        # in topological sorted order. This way if B uses A, B can clobber
        # A's settings.
        self.plugins = OrderedDict()

    def configure(self):
        tmt.EclipseProject.configure(self)

        self.nonJavaResourceDeps |= tmt.glob(self.srcResource,
                                             '.*$',
                                             relativeTo=self.srcResource)
        for f in xmlFileTypes:
            self.nonJavaResourceDeps -= tmt.glob(self.srcResource,
                                                 "%s$" % f,
                                                 relativeTo=self.srcResource)

        self.nonJavaSrcDeps |= tmt.glob(self.src,
                                        '.*\\.properties$',
                                        relativeTo=self.src)
        self.nonJavaSrcDeps |= tmt.glob(self.src,
                                        '.*\\.xsd$',
                                        relativeTo=self.src)
        self.nonJavaSrcDeps |= tmt.glob(self.src,
                                        '.*\\.dtd$',
                                        relativeTo=self.src)

    def addPlugin(self, project, needsDb=False):
        project.main = self.main
        project.argv = self.argv

        self.plugins[project.name] = project
        project.needsDb = needsDb

        notDotfile = lambda dirname: not dirname.startswith(".")

        def wrapCompile(ogCompile):
            def newCompile(self):
                if ogCompile(self):
                    assert self.webContent
                    for dirpath, dirnames, filenames in os.walk(
                            self.webContent):
                        dirnames[:] = filter(
                            notDotfile, dirnames
                        )  # Note that we're modifying dirnames in place

                        if "WEB-INF" in dirnames:
                            dirnames.remove("WEB-INF")
                        for filename in filter(notDotfile, filenames):
                            path = os.path.normpath(
                                os.path.join(dirpath, filename))
                            pathRelToWebContent = relpath(
                                path, self.webContent)
                            name = join(tmt.WinstoneServer.binResource,
                                        "webapps", "ROOT", pathRelToWebContent)
                            linkParent = os.path.dirname(name)
                            if not os.path.exists(linkParent):
                                os.makedirs(linkParent)
                            else:
                                assert os.path.isdir(linkParent)
                            tmt.createSymlinkIfNotExistsOrStale(
                                relpath(path, linkParent), name)
                    tmt.WinstoneServer.mungeXmlFiles(topLevelWebProject=self)

            return newCompile

        project.__class__.compile = wrapCompile(project.__class__.compile)

        def webContentDist(self):
            # We just compiled ourself, which caused a recompile
            # of winstone server, so there's no need to recompile it.
            # In fact, recompiling it would be bad, as it would nuke
            # our carefully constructed tnoodle_resources.
            tmt.WinstoneServer.dist(noRemake=True)
            tmt.WinstoneServer.distJarFile()
            shutil.copy(tmt.WinstoneServer.distJarFile(), self.distJarFile())

        project.__class__.webContentDist = webContentDist

    def getWebappDir(self):
        webappsDir = join(self.binResource, "webapps")
        webappDir = join(webappsDir, "ROOT")
        return webappDir

    def compile(self):
        if tmt.EclipseProject.compile(self):
            if tmt.TmtProject.projects[tmt.args.project] == self:
                # No wrapped compile to call this for us
                self.mungeXmlFiles(topLevelWebProject=self)

            webappDir = self.getWebappDir()
            webappWebInfDir = join(webappDir, "WEB-INF")
            libDir = join(webappWebInfDir, 'lib')
            if not os.path.exists(libDir):
                os.makedirs(libDir)
            classesDir = join(webappWebInfDir, 'classes')
            if not os.path.exists(classesDir):
                os.makedirs(classesDir)

    def mungeXmlFiles(self, topLevelWebProject):
        for f in xmlFileTypes:
            deps = topLevelWebProject.getRecursiveDependenciesTopoSorted()

            webappDir = self.getWebappDir()
            webappWebInfDir = join(webappDir, "WEB-INF")
            if not os.path.isdir(webappWebInfDir):
                os.makedirs(webappWebInfDir)

            srcWebInfDir = join(self.srcResource, "webapps", "ROOT", "WEB-INF")
            xmlRoot = ET.parse(join(srcWebInfDir, f)).getroot()

            if self.needsDb():
                h2ConsoleServlet = """<?xml version="1.0" encoding="UTF-8"?>
<junk>
	<!-- H2 web console -->
	<servlet>
		<servlet-name>H2Console</servlet-name>
		<servlet-class>org.h2.server.web.WebServlet</servlet-class>
		<init-param>
			<param-name>properties</param-name>
			<param-value>null</param-value>
		</init-param>
		<!--
		<init-param>
			<param-name>webAllowOthers</param-name>
			<param-value></param-value>
		</init-param>
		<init-param>
			<param-name>trace</param-name>
			<param-value></param-value>
		</init-param>
		-->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet>
		<servlet-name>InitializeH2Console</servlet-name>
		<servlet-class>net.gnehzr.tnoodle.server.InitializeH2Console</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>H2Console</servlet-name>
		<url-pattern>/h2/*</url-pattern>
	</servlet-mapping>
</junk>
"""
                root = ET.fromstring(h2ConsoleServlet)
                for child in reversed(root):
                    xmlRoot.insert(0, child)

            for project in deps:
                if project in self.plugins.values():
                    assert project.webContent
                    pluginXmlFile = join(project.webContent, "WEB-INF", f)
                    if not os.path.exists(pluginXmlFile):
                        continue
                    tree = ET.parse(pluginXmlFile)
                    root = tree.getroot()
                    for child in reversed(root):
                        xmlRoot.insert(0, child)

            xmlFile = join(webappWebInfDir, f)
            xmlFileOut = open(xmlFile, 'w')

            ET.register_namespace("", "http://java.sun.com/xml/ns/javaee")

            xmlFileOut.write(ET.tostring(xmlRoot))
            xmlFileOut.close()

    def needsDb(self):
        if getattr(tmt.args, "project", None) is None:
            # None may not yet be a key in tmt.TmtProject.projects,
            # we just hack around this by unconditionally returning True here.
            return True
        webProject = tmt.TmtProject.projects[tmt.args.project]
        if webProject == self:
            return True
        deps = webProject.getRecursiveDependenciesTopoSorted(
            exclude=set([self]))

        for project in deps:
            if project in self.plugins.values():
                if project.needsDb:
                    return True

        return False

    def getJars(self, includeCompileTimeOnlyDependencies=False):
        jars = tmt.EclipseProject.getJars(self,
                                          includeCompileTimeOnlyDependencies=
                                          includeCompileTimeOnlyDependencies)
        if self.needsDb():
            jars.append(tmt.TmtProject.projects['h2-1.3.169.jar'])

        return jars

    def tweakJarFile(self, jar):
        # We don't necessarily want all the plugins in self.plugins to load here,
        # we only want the ones that the project we're currently building somehow
        # depends on.
        webProject = tmt.TmtProject.projects[tmt.args.project]

        # Out jar file already contains everything needed to start up winstone.
        # All the contents of tnoodle_resources are there too (including webroot).
        # The problem is that even after compiling, webroot/WEB-INF/lib/ and
        # webroot/WEB-INF/classes/ are still unpopulated, so simply jarring it up
        # isn't good enough. Here we populate classes/ and lib/. To do so, we need
        # all of the things that webProject depends on, EXCEPT for winstone (ourself).
        deps = webProject.getRecursiveDependenciesTopoSorted(
            exclude=set([self]))

        webInf = join("tnoodle_resources", "webapps", "ROOT", "WEB-INF")
        libDir = join(webInf, "lib")
        classesDir = join(webInf, "classes")
        for project in deps:
            assert project is not self
            if hasattr(project, "jarFile"):
                arcPath = join(libDir, basename(project.jarFile))
                jar.write(project.jarFile, arcPath)
            elif isinstance(project, tmt.EclipseProject):
                for dirpath, dirnames, filenames in os.walk(project.bin,
                                                            followlinks=True):
                    for name in filenames:
                        if dirpath.startswith(
                                join(project.bin, "tnoodle_resources")):
                            destDir = ""
                        else:
                            destDir = classesDir
                        path = join(dirpath, name)
                        prefixLen = len(project.bin)
                        if project.bin.endswith("/"):
                            prefixLen += 1
                        arcPath = join(destDir, path[prefixLen + 1:])
                        jar.write(path, arcPath)
Beispiel #5
0
class Project(tmt.EclipseProject):
	def __init__(self, *args, **kwargs):
		tmt.EclipseProject.__init__(self, *args, **kwargs)
		tmt.WinstoneServer = self
		self.main = "net.gnehzr.tnoodle.server.TNoodleServer"
		self.argv = [ '--nobrowser', '--consoleLevel=INFO' ]

		# Winstone does all of these things =(.
		self.ignoredWarnings += [ 'unchecked' ]
		self.ignoredWarnings += [ 'deprecation' ]
		self.ignoredWarnings += [ 'serial' ]
		self.ignoredWarnings += [ 'dep-ann' ]
		self.ignoredWarnings += [ 'rawtypes' ]


        # It is important that when we iterate through the plugins
        # in topological sorted order. This way if B uses A, B can clobber
        # A's settings.
		self.plugins = OrderedDict()

	def configure(self):
		tmt.EclipseProject.configure(self)

		self.nonJavaResourceDeps |= tmt.glob(self.srcResource, '.*$', relativeTo=self.srcResource)
		for f in xmlFileTypes:
			self.nonJavaResourceDeps -= tmt.glob(self.srcResource, "%s$" % f, relativeTo=self.srcResource)

		self.nonJavaSrcDeps |= tmt.glob(self.src, '.*\\.properties$', relativeTo=self.src)
		self.nonJavaSrcDeps |= tmt.glob(self.src, '.*\\.xsd$', relativeTo=self.src)
		self.nonJavaSrcDeps |= tmt.glob(self.src, '.*\\.dtd$', relativeTo=self.src)

	def addPlugin(self, project, needsDb=False):
		project.main = self.main
		project.argv = self.argv

		self.plugins[project.name] = project
		project.needsDb = needsDb

		notDotfile = lambda dirname: not dirname.startswith(".")
		def wrapCompile(ogCompile):
			def newCompile(self):
				if ogCompile(self):
					assert self.webContent
					for dirpath, dirnames, filenames in os.walk(self.webContent):
						dirnames[:] = filter(notDotfile, dirnames) # Note that we're modifying dirnames in place

						if "WEB-INF" in dirnames:
							dirnames.remove("WEB-INF")
						for filename in filter(notDotfile, filenames):
							path = os.path.normpath(os.path.join(dirpath, filename))
							pathRelToWebContent = relpath(path, self.webContent)
							name = join(tmt.WinstoneServer.binResource, "webapps", "ROOT", pathRelToWebContent)
							linkParent = os.path.dirname(name)
							if not os.path.exists(linkParent):
								os.makedirs(linkParent)
							else:
								assert os.path.isdir(linkParent)
							tmt.createSymlinkIfNotExistsOrStale(relpath(path, linkParent), name)
					tmt.WinstoneServer.mungeXmlFiles(topLevelWebProject=self)
			return newCompile
		project.__class__.compile = wrapCompile(project.__class__.compile)

		def webContentDist(self):
			# We just compiled ourself, which caused a recompile
			# of winstone server, so there's no need to recompile it.
			# In fact, recompiling it would be bad, as it would nuke
			# our carefully constructed tnoodle_resources.
			tmt.WinstoneServer.dist(noRemake=True, implementationTitle=self.fullName)
			tmt.WinstoneServer.distJarFile()
			shutil.copy(tmt.WinstoneServer.distJarFile(), self.distJarFile())
		project.__class__.webContentDist = webContentDist

	def getWebappDir(self):
		webappsDir = join(self.binResource, "webapps")
		webappDir = join(webappsDir, "ROOT")
		return webappDir

	def compile(self):
		if tmt.EclipseProject.compile(self):
			if tmt.TmtProject.projects[tmt.args.project] == self:
                # No wrapped compile to call this for us
				self.mungeXmlFiles(topLevelWebProject=self)

			webappDir = self.getWebappDir()
			webappWebInfDir = join(webappDir, "WEB-INF")
			libDir = join(webappWebInfDir, 'lib')
			if not os.path.exists(libDir):
				os.makedirs(libDir)
			classesDir = join(webappWebInfDir, 'classes')
			if not os.path.exists(classesDir):
				os.makedirs(classesDir)

	def mungeXmlFiles(self, topLevelWebProject):
		for f in xmlFileTypes:
			deps = topLevelWebProject.getRecursiveDependenciesTopoSorted()

			webappDir = self.getWebappDir()
			webappWebInfDir = join(webappDir, "WEB-INF")
			if not os.path.isdir(webappWebInfDir):
				os.makedirs(webappWebInfDir)

			srcWebInfDir = join(self.srcResource, "webapps", "ROOT", "WEB-INF")
			xmlRoot = ET.parse(join(srcWebInfDir, f)).getroot()

			if self.needsDb():
				h2ConsoleServlet = """<?xml version="1.0" encoding="UTF-8"?>
<junk>
	<!-- H2 web console -->
	<servlet>
		<servlet-name>H2Console</servlet-name>
		<servlet-class>org.h2.server.web.WebServlet</servlet-class>
		<init-param>
			<param-name>properties</param-name>
			<param-value>null</param-value>
		</init-param>
		<!--
		<init-param>
			<param-name>webAllowOthers</param-name>
			<param-value></param-value>
		</init-param>
		<init-param>
			<param-name>trace</param-name>
			<param-value></param-value>
		</init-param>
		-->
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet>
		<servlet-name>InitializeH2Console</servlet-name>
		<servlet-class>net.gnehzr.tnoodle.server.InitializeH2Console</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>H2Console</servlet-name>
		<url-pattern>/h2/*</url-pattern>
	</servlet-mapping>
</junk>
"""
				root = ET.fromstring(h2ConsoleServlet)
				for child in reversed(root):
					xmlRoot.insert(0, child)

			for project in deps:
				if project in self.plugins.values():
					assert project.webContent
					pluginXmlFile = join(project.webContent, "WEB-INF", f)
					if not os.path.exists(pluginXmlFile):
						continue
					tree = ET.parse(pluginXmlFile)
					root = tree.getroot()
					for child in reversed(root):
						xmlRoot.insert(0, child)

			xmlFile = join(webappWebInfDir, f)
			xmlFileOut = open(xmlFile, 'w')

			ET.register_namespace("", "http://java.sun.com/xml/ns/javaee")

			xmlFileOut.write(ET.tostring(xmlRoot))
			xmlFileOut.close()

	def needsDb(self):
		if getattr(tmt.args, "project", None) is None:
			# None may not yet be a key in tmt.TmtProject.projects,
			# we just hack around this by unconditionally returning True here.
			return True
		webProject = tmt.TmtProject.projects[tmt.args.project]
		if webProject == self:
			return True
		deps = webProject.getRecursiveDependenciesTopoSorted(exclude=set([self]))

		for project in deps:
			if project in self.plugins.values():
				if project.needsDb:
					return True

		return False

	def getJars(self, includeCompileTimeOnlyDependencies=False):
		jars = tmt.EclipseProject.getJars(self, includeCompileTimeOnlyDependencies=includeCompileTimeOnlyDependencies)
		if self.needsDb():
			jars.append(tmt.TmtProject.projects['h2-1.3.169.jar'])

		return jars

	def tweakJarFile(self, jar):
        # We don't necessarily want all the plugins in self.plugins to load here,
        # we only want the ones that the project we're currently building somehow
        # depends on.
		webProject = tmt.TmtProject.projects[tmt.args.project]

		# Out jar file already contains everything needed to start up winstone.
		# All the contents of tnoodle_resources are there too (including webroot).
		# The problem is that even after compiling, webroot/WEB-INF/lib/ and
		# webroot/WEB-INF/classes/ are still unpopulated, so simply jarring it up
		# isn't good enough. Here we populate classes/ and lib/. To do so, we need
		# all of the things that webProject depends on, EXCEPT for winstone (ourself).
		deps = webProject.getRecursiveDependenciesTopoSorted(exclude=set([self]))

		webInf = join("tnoodle_resources", "webapps", "ROOT", "WEB-INF")
		libDir = join(webInf, "lib")
		classesDir = join(webInf, "classes")
		for project in deps:
			assert project is not self
			if hasattr(project, "jarFile"):
				arcPath = join(libDir, basename(project.jarFile))
				jar.write(project.jarFile, arcPath)
			elif isinstance(project, tmt.EclipseProject):
				for dirpath, dirnames, filenames in os.walk(project.bin, followlinks=True):
					for name in filenames:
						if dirpath.startswith(join(project.bin, "tnoodle_resources")):
							destDir = ""
						else:
							destDir = classesDir
						path = join(dirpath, name)
						prefixLen = len(project.bin)
						if project.bin.endswith("/"):
							prefixLen += 1
						arcPath = join(destDir, path[prefixLen+1:])
						jar.write(path, arcPath)
Beispiel #6
0
class comboBox(QComboBox, widgetState):
    def __init__(self,
                 widget,
                 label=None,
                 displayLabel=True,
                 includeInReports=True,
                 items=None,
                 editable=False,
                 orientation='horizontal',
                 callback=None):

        widgetState.__init__(self, widget, label, includeInReports)
        QComboBox.__init__(self, self.controlArea)

        if displayLabel:
            self.hb = widgetBox(self.controlArea, orientation=orientation)
            widgetLabel(self.hb, label)
            self.hb.layout().addWidget(self)
            self.hasLabel = True
        else:
            self.controlArea.layout().addWidget(self)
            self.hasLabel = False
        self.label = label

        self.items = OrderedDict()
        self.setEditable(editable)

        if items:
            self.addItems(items)

        if callback:
            QObject.connect(self, SIGNAL('activated(int)'), callback)

    def getSettings(self):
        r = {'items': self.items, 'current': self.currentIndex()}
        return r

    def loadSettings(self, data):
        # print _('in comboBox load')
        # print data

        self.addItems(data['items'])
        self.setCurrentIndex(data['current'])

    def currentId(self):
        try:
            return self.items.keys()[self.currentIndex()]
        except:
            return None

    def currentItem(self):
        return {
            self.items.keys()[self.currentIndex()]:
            self.items.values()[self.currentIndex()]
        }

    def setCurrentId(self, id):
        try:
            self.setCurrentIndex(self.items.keys().index(id))
        except:
            pass

    def addItems(self, items):
        if type(items) in [dict, OrderedDict]:
            for k, v in items.items():
                self.addItem(k, v)
        elif type(items) in [list]:
            if len(items) > 0 and type(items[0]) is tuple:
                for k, v in items:
                    self.addItem(k, v)
            else:
                for v in items:
                    self.addItem(v, v)
            # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In listBox should not use list'))
        else:
            raise Exception(
                _('In comboBox, addItems takes a list, dict or OrderedDict'))

    def update(self, items):
        current = self.currentId()
        self.clear()
        self.addItems(items)
        self.setCurrentId(current)

    def clear(self):
        QComboBox.clear(self)
        self.items = OrderedDict()

    def addItem(self, id, item):
        QComboBox.addItem(self, item)
        self.items[id] = item

    def getReportText(self, fileDir):

        r = {
            self.widgetName: {
                'includeInReports': self.includeInReports,
                'text': self.currentText()
            }
        }
        #return '%s set to %s' % (self.label, self.currentText())
        return r
Beispiel #7
0
class listBox(QListWidget,widgetState):
    def __init__(self, widget, value=None, label=None, displayLabel=True, orientation='vertical', selectionMode=QAbstractItemView.SingleSelection, enableDragDrop = 0, dragDropCallback = None, dataValidityCallback = None, sizeHint = None, callback=None, items = None, *args, **kwargs):
        kwargs.setdefault('includeInReports', True)
        kwargs.setdefault('sizePolicy', QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
        widgetState.__init__(self,widget,label,**kwargs)
        QListWidget.__init__(self, *args)
        self.label = label
        self.widget = self.controlArea
        if displayLabel:
            self.hb = groupBox(self.controlArea,label=label,orientation=orientation)
            
        else:
            self.hb = widgetBox(self.controlArea,orientation=orientation)
            
        self.hb.layout().addWidget(self)
        self.ogValue = value
        self.ogLabels = label
        self.enableDragDrop = enableDragDrop
        self.dragDopCallback = dragDropCallback
        self.dataValidityCallback = dataValidityCallback
        self.defaultSizeHint = QSize(150,100)
        self.setSelectionMode(selectionMode)
        if enableDragDrop:
            self.setDragEnabled(1)
            self.setAcceptDrops(1)
            self.setDropIndicatorShown(1)
            #self.setDragDropMode(QAbstractItemView.DragDrop)
            
            self.dragStartPosition = 0
        
        self.listItems = OrderedDict()
        if items:
            self.addItems(items)
        
        if callback:
            QObject.connect(self, SIGNAL('itemClicked(QListWidgetItem*)'), callback)



    def getItems(self):
        """Returns an OrderedDict of the items (key, value) in the listBox, this can be treated as a dict also."""
        return self.listItems

    def addItem(self,id,item):
        QListWidget.addItem(self,item)
        self.listItems[id] = item
    def addItems(self,items):
        progressBar = startProgressBar('Setting List Items', '', len(items))
        progress = 0
        if type(items) in [dict,OrderedDict]:
            
            for k,v in items.items():
                self.addItem(k,v)
                progress += 1
                progressBar.setValue(progress)
            
        elif type(items) in [list]:
            progressBar = startProgressBar('Setting List Items', '', len(items))
            if len(items) > 0 and type(items[0]) is tuple:
                for k,v in items:
                    self.addItem(k,v)
                    progress += 1
                    progressBar.setValue(progress)
            else:
                for v in items:
                    self.addItem(v,v)
                    progress += 1
                    progressBar.setValue(progress)
            # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In listBox should not use list'))
        else:
            progressBar.hide()
            raise Exception(_('In listBox, addItems takes a list, dict or OrderedDict'))
        progressBar.hide()
    def setSelectedIds(self,ids):
        """Sets a list of ids (ids) to be selected."""
        if ids == None: return
        progressBar = startProgressBar('Setting Selected Items', '', len(ids))
        progress = 0
        for x in ids:
            try:
                self.item(self.listItems.keys().index(x)).setSelected(True)
            except:
                pass
            progress += 1
            progressBar.setValue(progress)
    def update(self, items):
        """Clears the list, adds new items, and sets any selected items in the old list to being selected in the new list (if they exist of course)."""
        current = self.selectedIds()
        self.clear()
        self.addItems(items)
        self.setSelectedIds(current)
        

    def clear(self):
        """Clears the list"""
        QListWidget.clear(self)
        self.listItems = OrderedDict()

    def invertSelection(self):
        for i in range(self.count()):
            if self.isItemSelected(self.item(i)):
                self.item(i).setSelected(False)
            else:
                self.item(i).setSelected(True)
    
    def selectionCount(self):
        return len(self.selectedIndexes())
    def currentSelection(self):
        """Returns a list of selected values (the text in the list)"""
        return self.selectedItems().values()
    def selectedItems(self):
        """Returns a dict of selected items."""
        items = {}
        for x in self.selectedIndexes():
            items[self.listItems.keys()[x.row()]] = self.listItems.values()[x.row()]
        return items
    def selectedIds(self):
        """Returns a list of selected ids"""
        ids = []
        for x in self.selectedIndexes():
            ids.append(self.listItems.keys()[x.row()])
        return ids
        
    #def setSelectedIds(self, ids):
        #if ids == None: return
        #for i in range(self.count()):
            #if self.listItems.keys()[i] in ids:
                #self.item(i).setSelect(True)
    
    def sizeHint(self):
        return self.defaultSizeHint
    def startDrag(self, supportedActions):
        if not self.enableDragDrop: return

        drag = QDrag(self)
        mime = QMimeData()

        if not self.ogValue:
            selectedItems = [i for i in range(self.count()) if self.item(i).isSelected()]
        else:
            selectedItems = getdeepattr(self.widget, self.ogValue, default = [])

        mime.setText(unicode(selectedItems))
        mime.source = self
        drag.setMimeData(mime)
        drag.start(Qt.MoveAction)

    def dragEnterEvent(self, ev):
        if not self.enableDragDrop: return
        if self.dataValidityCallback: return self.dataValidityCallback(ev)

        if ev.mimeData().hasText():
            ev.accept()
        else:
            ev.ignore()
    def dragMoveEvent(self, ev):
        if not self.enableDragDrop: return
        if self.dataValidityCallback: return self.dataValidityCallback(ev)

        if ev.mimeData().hasText():
            ev.setDropAction(Qt.MoveAction)
            ev.accept()
        else:
            ev.ignore()

    def dropEvent(self, ev):
        if not self.enableDragDrop: return
        if ev.mimeData().hasText():
            item = self.itemAt(ev.pos())
            if item:
                index = self.indexFromItem(item).row()
            else:
                index = self.count()

            source = ev.mimeData().source
            selectedItemIndices = eval(unicode(ev.mimeData().text()))

            if self.ogLabels != None and self.ogValue != None:
                allSourceItems = getdeepattr(source.widget, source.ogLabels, default = [])
                selectedItems = [allSourceItems[i] for i in selectedItemIndices]
                allDestItems = getdeepattr(self.widget, self.ogLabels, default = [])

                if source != self:
                    setattr(source.widget, source.ogLabels, [item for item in allSourceItems if item not in selectedItems])   # TODO: optimize this code. use the fact that the selectedItemIndices is a sorted list
                    setattr(self.widget, self.ogLabels, allDestItems[:index] + selectedItems + allDestItems[index:])
                    setattr(source.widget, source.ogValue, [])  # clear selection in the source widget
                else:
                    items = [item for item in allSourceItems if item not in selectedItems]
                    if index < len(allDestItems):
                        while index > 0 and index in getdeepattr(self.widget, self.ogValue, default = []):      # if we are dropping items on a selected item, we have to select some previous unselected item as the drop target
                            index -= 1
                        destItem = allDestItems[index]
                        index = items.index(destItem)
                    else:
                        index = max(0, index - len(selectedItems))
                    setattr(self.widget, self.ogLabels, items[:index] + selectedItems + items[index:])
                setattr(self.widget, self.ogValue, range(index, index+len(selectedItems)))
            else:       # if we don't have variables ogValue and ogLabel
                if source != self:
                    self.insertItems(source.selectedItems())
                    for index in selectedItemIndices[::-1]:
                        source.takeItem(index)
                else:
                    if index < self.count():
                        while index > 0 and self.item(index).isSelected():      # if we are dropping items on a selected item, we have to select some previous unselected item as the drop target
                            index -= 1
                    items = [source.item(i) for i in selectedItemIndices]
                    for ind in selectedItemIndices[::-1]:
                        source.takeItem(ind)
                        if ind <= index: index-= 1
                    for item in items[::-1]:
                        self.insertItem(index, item)
                    self.clearSelection()
                    for i in range(index, index+len(items)):
                        self.item(i).setSelected(1)

            if self.dragDopCallback:        # call the callback
                self.dragDopCallback()
            ev.setDropAction(Qt.MoveAction)
            ev.accept()
            
            ## whatever all of this does we need to execute the function to update the items
            self.updateRedRItems()
        else:
            ev.ignore()

    def updateRedRItems(self):
        """Updates the items in the list to a new order."""
        ## we go through all of the items and remake the items OrderedDict
        newDict = OrderedDict()
        for r in range(self.count()):
            t = unicode(self.item(r).text())  # get the text of the item
            if t not in self.listItems.values():
                newDict[t] = t
            else:
                for i, ov in self.listItems.items():
                    if ov == t:
                        newDict[i] = ov
        self.listItems = newDict
    def getSettings(self):
        #print 'saving list box'
        r = {'items':self.listItems, 'selected':self.selectedIds()}
        #print r
        return r
    def loadSettings(self,data):
        self.clear()
        self.addItems(data.get('items', []))
        self.setSelectedIds(data.get('selected', None))
    def getReportText(self, fileDir):
        items = self.getItems()
        selected = self.currentSelection()
        new = []
        
        for x in items:
            if x in selected:
                new.append([_('Selected'), x])
            else:
                new.append([_('Not Selected'),x])
        #print new
        text = redRReports.createTable(new,columnNames=[_('Selection'),_('Option')])
        # if text != '':
            # text += '\nSelected text has * in front'
        
        r = {self.widgetName:{'includeInReports': self.includeInReports, 'text': text}}

        return r
Beispiel #8
0
class listBox(QListWidget, widgetState):
    def __init__(self,
                 widget,
                 value=None,
                 label=None,
                 displayLabel=True,
                 includeInReports=True,
                 orientation='vertical',
                 selectionMode=QAbstractItemView.SingleSelection,
                 enableDragDrop=0,
                 dragDropCallback=None,
                 dataValidityCallback=None,
                 sizeHint=None,
                 callback=None,
                 toolTip=None,
                 items=None,
                 *args):

        widgetState.__init__(self, widget, label, includeInReports)
        QListWidget.__init__(self, *args)
        self.label = label
        self.widget = self.controlArea
        if displayLabel:
            self.hb = groupBox(self.controlArea,
                               label=label,
                               orientation=orientation)

        else:
            self.hb = widgetBox(self.controlArea, orientation=orientation)

        self.hb.layout().addWidget(self)
        self.ogValue = value
        self.ogLabels = label
        self.enableDragDrop = enableDragDrop
        self.dragDopCallback = dragDropCallback
        self.dataValidityCallback = dataValidityCallback
        if not sizeHint:
            self.defaultSizeHint = QSize(150, 100)
        else:
            self.defaultSizeHint = sizeHint
        self.setSelectionMode(selectionMode)
        if enableDragDrop:
            self.setDragEnabled(1)
            self.setAcceptDrops(1)
            self.setDropIndicatorShown(1)
            #self.setDragDropMode(QAbstractItemView.DragDrop)

            self.dragStartPosition = 0
        if toolTip:
            self.setToolTip(toolTip)

        self.listItems = OrderedDict()
        if items:
            self.addItems(items)

        if callback:
            QObject.connect(self, SIGNAL('itemClicked(QListWidgetItem*)'),
                            callback)

    def getItems(self):
        return self.listItems

    def addItem(self, id, item):
        QListWidget.addItem(self, item)
        self.listItems[id] = item

    def addItems(self, items):
        if type(items) in [dict, OrderedDict]:
            for k, v in items.items():
                self.addItem(k, v)
        elif type(items) in [list]:
            if len(items) > 0 and type(items[0]) is tuple:
                for k, v in items:
                    self.addItem(k, v)
            else:
                for v in items:
                    self.addItem(v, v)
            # redRLog.log(redRLog.REDRCORE,redRLog.DEBUG,_('In listBox should not use list'))
        else:
            raise Exception(
                _('In listBox, addItems takes a list, dict or OrderedDict'))

    def setSelectedIds(self, ids):
        for x in ids:
            try:
                self.item(self.listItems.keys().index(x)).setSelected(True)
            except:
                pass

    def update(self, items):
        current = self.selectedIds()
        self.clear()
        self.addItems(items)
        self.setSelectedIds(current)

    def clear(self):
        QListWidget.clear(self)
        self.items = OrderedDict()

    def invertSelection(self):
        for i in range(self.count()):
            if self.isItemSelected(self.item(i)):
                self.item(i).setSelected(False)
            else:
                self.item(i).setSelected(True)

    def selectionCount(self):
        return len(self.selectedIndexes())

    def currentSelection(self):
        return self.selectedItems().values()

    def selectedItems(self):
        items = {}
        for x in self.selectedIndexes():
            items[self.listItems.keys()[x.row()]] = self.listItems.values()[
                x.row()]
        return items

    def selectedIds(self):
        ids = []
        for x in self.selectedIndexes():
            ids.append(self.listItems.keys()[x.row()])
        return ids

    def sizeHint(self):
        return self.defaultSizeHint

    def startDrag(self, supportedActions):
        if not self.enableDragDrop: return

        drag = QDrag(self)
        mime = QMimeData()

        if not self.ogValue:
            selectedItems = [
                i for i in range(self.count()) if self.item(i).isSelected()
            ]
        else:
            selectedItems = getdeepattr(self.widget, self.ogValue, default=[])

        mime.setText(unicode(selectedItems))
        mime.source = self
        drag.setMimeData(mime)
        drag.start(Qt.MoveAction)

    def dragEnterEvent(self, ev):
        if not self.enableDragDrop: return
        if self.dataValidityCallback: return self.dataValidityCallback(ev)

        if ev.mimeData().hasText():
            ev.accept()
        else:
            ev.ignore()

    def dragMoveEvent(self, ev):
        if not self.enableDragDrop: return
        if self.dataValidityCallback: return self.dataValidityCallback(ev)

        if ev.mimeData().hasText():
            ev.setDropAction(Qt.MoveAction)
            ev.accept()
        else:
            ev.ignore()

    def dropEvent(self, ev):
        if not self.enableDragDrop: return
        if ev.mimeData().hasText():
            item = self.itemAt(ev.pos())
            if item:
                index = self.indexFromItem(item).row()
            else:
                index = self.count()

            source = ev.mimeData().source
            selectedItemIndices = eval(unicode(ev.mimeData().text()))

            if self.ogLabels != None and self.ogValue != None:
                allSourceItems = getdeepattr(source.widget,
                                             source.ogLabels,
                                             default=[])
                selectedItems = [
                    allSourceItems[i] for i in selectedItemIndices
                ]
                allDestItems = getdeepattr(self.widget,
                                           self.ogLabels,
                                           default=[])

                if source != self:
                    setattr(
                        source.widget, source.ogLabels, [
                            item for item in allSourceItems
                            if item not in selectedItems
                        ]
                    )  # TODO: optimize this code. use the fact that the selectedItemIndices is a sorted list
                    setattr(
                        self.widget, self.ogLabels, allDestItems[:index] +
                        selectedItems + allDestItems[index:])
                    setattr(source.widget, source.ogValue,
                            [])  # clear selection in the source widget
                else:
                    items = [
                        item for item in allSourceItems
                        if item not in selectedItems
                    ]
                    if index < len(allDestItems):
                        while index > 0 and index in getdeepattr(
                                self.widget, self.ogValue, default=[]
                        ):  # if we are dropping items on a selected item, we have to select some previous unselected item as the drop target
                            index -= 1
                        destItem = allDestItems[index]
                        index = items.index(destItem)
                    else:
                        index = max(0, index - len(selectedItems))
                    setattr(self.widget, self.ogLabels,
                            items[:index] + selectedItems + items[index:])
                setattr(self.widget, self.ogValue,
                        range(index, index + len(selectedItems)))
            else:  # if we don't have variables ogValue and ogLabel
                if source != self:
                    self.insertItems(source.selectedItems())
                    for index in selectedItemIndices[::-1]:
                        source.takeItem(index)
                else:
                    if index < self.count():
                        while index > 0 and self.item(index).isSelected(
                        ):  # if we are dropping items on a selected item, we have to select some previous unselected item as the drop target
                            index -= 1
                    items = [source.item(i) for i in selectedItemIndices]
                    for ind in selectedItemIndices[::-1]:
                        source.takeItem(ind)
                        if ind <= index: index -= 1
                    for item in items[::-1]:
                        self.insertItem(index, item)
                    self.clearSelection()
                    for i in range(index, index + len(items)):
                        self.item(i).setSelected(1)

            if self.dragDopCallback:  # call the callback
                self.dragDopCallback()
            ev.setDropAction(Qt.MoveAction)
            ev.accept()

            ## whatever all of this does we need to execute the function to update the items
            self.updateRedRItems()
        else:
            ev.ignore()

    def updateRedRItems(self):
        ## we go through all of the items and remake the items OrderedDict
        newDict = OrderedDict()
        for r in range(self.count()):
            t = unicode(self.itemAt(r).text())  # get the text of the item
            if t not in self.listItems.values():
                newDict[t] = t
            else:
                for i, ov in self.listItems.items():
                    if ov == t:
                        newDict[i] = ov
        self.listItems = newDict

    def getSettings(self):
        print 'saving list box'
        r = {'items': self.items, 'selected': self.selectedIds()}
        print r
        return r

    def loadSettings(self, data):
        print _('loading list box')
        print data
        self.clear()
        self.addItems(data['items'])
        self.setSelectedIds(data['selected'])

    def getReportText(self, fileDir):
        items = self.getItems()
        selected = self.currentSelection()
        new = []

        for x in items:
            if x in selected:
                new.append([_('Selected'), x])
            else:
                new.append([_('Not Selected'), x])
        #print new
        text = redRReports.createTable(
            new, columnNames=[_('Selection'), _('Option')])
        # if text != '':
        # text += '\nSelected text has * in front'

        r = {
            self.widgetName: {
                'includeInReports': self.includeInReports,
                'text': text
            }
        }

        return r