示例#1
0
class mainwin(QMainWindow):
	def __init__(self, parent=None):
		super(mainwin, self).__init__(parent)
		self.setWindowTitle("Nigandu English to Tamil Dictionary")
		self.setGeometry(200, 50, 650, 600)
		self.setMinimumHeight(620)
		self.setMinimumWidth(650)
		self.setMaximumHeight(660)
		self.setMaximumWidth(800)
		#Setting up status bar
		self.myStatusBar = QStatusBar()
		self.myStatusBar.showMessage('Ready', 7000)
		self.setStatusBar(self.myStatusBar)
		#Setting up application icon
		appIcon = QIcon(":/icons/njnlogo.png")
		self.setWindowIcon(appIcon)

		# defining the central widget
		self.central = QWidget(self)

		#combobox plus search button
		self.whole = QVBoxLayout(self.central)
		self.gridlayout = QGridLayout()
		self.comboBox = QLineEdit(self)
		#self.comboBox.setEditable(True)
		self.comboBox.setObjectName("comboBox")
		self.completer = QCompleter(self.comboBox)
		self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
		self.completer.setCaseSensitivity(Qt.CaseInsensitive)
		self.completer.setMaxVisibleItems(10)
		self.comboBox.setCompleter(self.completer)
		#self.comboBox.setCompleter()
		self.gridlayout.addWidget(self.comboBox, 1, 1, 1, 2)

		self.searchbtn = QPushButton()
		self.searchbtn.setObjectName("searchbtn")
		self.searchbtn.setText("&Search")
		self.gridlayout.addWidget(self.searchbtn, 1, 3)

		vbox = QVBoxLayout()
		self.tamtext = QTextBrowser()
		self.listview = QListWidget(self)
		#self.listview.setEditTriggers(QAbstractItemView.NoEditTriggers)
		self.listview.setWindowTitle("Suggested words")
		self.tamtext.setMinimumHeight(100)
		self.tamtext.setMaximumHeight(150)
		vbox.addWidget(self.tamtext)
		self.suglbl = QLabel(self)
		self.suglbl.setText("Suggested Words:")
		vbox.addWidget(self.suglbl)
		vbox.addWidget(self.listview)

		self.whole.addLayout(self.gridlayout)
		self.whole.addLayout(vbox)
		self.setCentralWidget(self.central)

		#setting docks
		self.histdockwidg = QDockWidget("History", self)
		self.bkmdockwidg = QDockWidget("Book Marks", self)
		self.histdockwidg.setObjectName("self.histdockwidg")
		self.bkmdockwidg.setObjectName("self.bkmdockwidg")

		#self.histdockwidg.setMaximumWidth(histwidth)
		self.histdockwidg.setAllowedAreas(Qt.RightDockWidgetArea)
		self.bkmdockwidg.setAllowedAreas(Qt.RightDockWidgetArea)
		self.histdockwidg.setMaximumWidth(250)
		self.bkmdockwidg.setMaximumWidth(250)
		self.histdockwidg.setMinimumWidth(200)
		self.bkmdockwidg.setMinimumWidth(200)

		#self.bkmdockwidg.setMaximumWidth(histwidth)
		self.histli = QListWidget()
		self.bkmli = QListWidget()
		self.histlis = [0]
		self.bkmlistfromfile = []
		self.histdockwidg.setWidget(self.histli)
		self.bkmdockwidg.setWidget(self.bkmli)
		self.addDockWidget(Qt.RightDockWidgetArea, self.histdockwidg)
		self.addDockWidget(Qt.RightDockWidgetArea, self.bkmdockwidg)

		#file menu
		fi_addwrd = self.createactions("&Add a word...", self.addwrdf, "Alt+A", ":/icons/add.png",
		                               "Add a word to the dictionary. . .")
		fi_options = self.createactions("&Options", self.optionsf, "None", ":/icons/options.png",
		                                "Change the default settings. . .")
		fi_help = self.createactions("&Help", self.helpf, QKeySequence.HelpContents, ":/icons/help.png",
		                             "Help contents. . .")
		fi_quit = self.createactions("&Quit", self.close, QKeySequence.Close, ":/icons/quit.png",
		                             "Close the application. . .")
		fplus = self.createactions("FontPlus", self.fplusf, "None", ":/icons/fplus.png", "Increase the font size")
		fminus = self.createactions("FontMinus", self.fminusf, "None", ":/icons/fminus.png", "Decrease the font size")
		#list of file actions
		fi_menu = (fi_addwrd, fi_options, fi_help, None, fi_quit)

		#go menu
		self.go_prev = self.createactions("&Previous Word", self.prevf, "Alt+Z", ":/icons/prev.png",
		                                  "Previous Word")
		self.go_next = self.createactions("&Next Word", self.nextf, "Alt+X", ":/icons/next.png", "Next Word")
		self.go_rand = self.createactions("&Random Word", self.randf, "Ctrl+R", ":/icons/rand.png",
		                                  "Select a random word")
		#list of go actions
		go_menu = (self.go_prev, self.go_next, self.go_rand )
		self.go_next.setEnabled(False)
		self.go_prev.setEnabled(False)

		#book mark menu
		self.bkm_addfav = self.createactions("&Bookmark", self.addfavf, "Ctrl+B", ":/icons/bookmark.png",
		                                     "Book mark this word")
		self.bkm_viewbkm = self.createactions("&View Bookmarks", self.viewbkmf, "Alt+V", ":/icons/viewbkm.png",
		                                      "View bookmarked words")
		#list of book mark items
		bkm_menu = (self.bkm_addfav, self.bkm_viewbkm)

		#help menu
		hlp_about = self.createactions("Abo&ut", self.aboutf, "Ctrl+U", ":/icons/about.png", "About")
		hlp_visitblog = self.createactions("&Visit Blog", self.visitblogf, "None", ":/icons/visitblog.png",
		                                   "Visit our blog")
		hlp_help = self.createactions("&Help", self.helpf, "Ctrl+H", ":/icons/help.png", "Help Contents")
		#list of help menu items
		hlp_menu = (hlp_about, hlp_visitblog, hlp_help)

		#Setting up the menubar
		filemenu = self.menuBar().addMenu("&File")
		self.addmenu(filemenu, fi_menu)
		gomenu = self.menuBar().addMenu("&Go")
		self.addmenu(gomenu, go_menu)
		bkmmenu = self.menuBar().addMenu("&Book Mark")
		self.addmenu(bkmmenu, bkm_menu)
		helpmenu = self.menuBar().addMenu("&Help")
		self.addmenu(helpmenu, hlp_menu)
		intn = QSize(40, 40)
		self.setIconSize(intn)
		#Setting up the tool bar
		filetools = self.addToolBar("File")
		filetools.setObjectName("filetools")
		self.addmenu(filetools, (fi_addwrd, fplus, fminus))

		gotools = self.addToolBar("Go")
		gotools.setObjectName("gotools")
		self.addmenu(gotools, go_menu)

		bkmtools = self.addToolBar("Bkm")
		bkmtools.setObjectName("bkmtools")
		self.addmenu(bkmtools, bkm_menu)

		hlptools = self.addToolBar("Help")
		hlptools.setObjectName("helptools")
		self.addmenu(hlptools, hlp_menu)

		self.loadfiles()
		self.returncount = 0
		self.bkm_addfav.setEnabled(False)

		#clipboard function
		if self.clipauto:
			clip = QApplication.clipboard()
			cliptxt = clip.text()
			self.comboBox.setText(cliptxt)
			self.setevent()

		#connections
		self.connect(self.comboBox, SIGNAL("textChanged(QString)"), self.search)
		self.connect(self.comboBox, SIGNAL("returnPressed()"), self.returnpressedevent)
		self.connect(self.searchbtn, SIGNAL("clicked()"), self.onenter)
		self.connect(self.listview, SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self.listwidcall)
		self.connect(self.histli, SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self.listwidcall)
		self.connect(self.bkmli, SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self.listwidcall)

	def writehistlis(self, lis):
		if len(lis) >= 2:
			for i in range(1, len(lis)):
				cur.execute("insert into HISTORY values(?)", (lis[i], ))

	def writebkmlis(self, lis):
		cur.execute("delete from BOOKMARKS")
		if len(lis) > 0:
			for i in range(len(lis)):
				cur.execute("insert into BOOKMARKS values(?)", (lis[i], ))

	def listwidcall(self, item):
		self.comboBox.setText(item.text())
		self.setevent()

	def search(self, text, *args):
		li = []
		tplus = text + "%"
		cur.execute("select ENGW from ENGTAM where ENGW like ? limit 20", (tplus, ))
		cuf = cur.fetchall()
		model = QStringListModel()
		for i in range(len(cuf)):
			k = cuf[i][0]
			li.append(k)
		model.setStringList(li)
		self.completer.setModel(model)

	def returnpressedevent(self, *args):
		self.comboBox.selectAll()
		self.returncount += 1
		if self.returncount % 2 == 0:
			self.setevent()
		else:
			self.comboBox.selectAll()

	def setevent(self):
		self.comboBox.selectAll()
		self.bkm_addfav.setEnabled(True)
		lis = []
		eng = self.comboBox.text()
		cur.execute("SELECT rowid, TAMW FROM ENGTAM WHERE ENGW like ? limit 1", (eng,))
		cuf = cur.fetchall()
		if len(cuf) == 0:
			self.tamtext.setText("No words found. . . ")
			self.listview.addItem("No Suggestions. . .")
		else:
			for i in range(len(cuf)):
				tam = cuf[0][1]
				rowid = cuf[0][0]
				self.tamtext.setText(tam)
				if rowid <= 25:
					start = 0
					end = 50
				elif rowid >= 190513:
					start = rowid - 190487
					end = rowid + 190537
				else:
					start = rowid - 25
					end = rowid + 25
				cur.execute("SELECT ENGW FROM ENGTAM WHERE rowid>=? and rowid<=?", (start, end, ))
				cuff = cur.fetchall()
				for i in range(len(cuff)):
					engw = cuff[i][0]
					lis.append(engw)
				if self.listview.count() is not None:
					self.listview.clear()
				self.listview.addItems(lis)
				self.addtoli(eng, self.histlis)
				if self.histlis[0] >= 2:
					self.go_prev.setEnabled(True)
				self.comboBox.setFocus()
				if self.histdock:
					self.histli.addItem(eng)

	def addtoli(self, addw, lis, c=1):
		if len(lis) > 0:
			if type(lis[0]) == int:
				if len(lis) >= 2:
					for i in range(1, len(lis)):
						if lis[i] == addw:
							c = 0
							pass
					if c == 1:
						lis.append(addw)
				else:
					lis.append(addw)
				lis[0] = len(lis) - 1

	def addtobkmli(self, addw, lis, nc=1):
		for i in range(len(lis)):
			if lis[i] == addw:
				nc = 0
				pass
		if nc == 1:
			lis.append(addw)

	def onenter(self, *args):
		self.comboBox.selectAll()
		self.setevent()

	def loadfiles(self):
		self.loadsettings()
		self.loadhistlis()
		self.loadbkm()
		self.setfontsize(int(self.fontsize))
		self.setdocks()


	def setdocks(self):
		ist = str(self.histdock)
		jst = str(self.bkmdock)

		if ist == "False":
			self.removedock(self.histdockwidg)
		else:
			self.adddock(self.histdockwidg)

		if jst == "False":
			self.removedock(self.bkmdockwidg)
		else:
			self.adddock(self.bkmdockwidg)

	def loadsettings(self):
		cur.execute("select * from SETTINGS")
		cuffun = cur.fetchall()
		fn = int(cuffun[0][1])
		self.fontsize = fn
		self.clipauto = cuffun[1][1]
		self.histdock = cuffun[2][1]
		self.savehist = cuffun[3][1]
		self.bkmdock = cuffun[4][1]
		self.delhist = cuffun[5][1]
		self.delbkm = cuffun[6][1]

	def loadhistlis(self):
		histtodockli = []
		cur.execute("select * from HISTORY")
		historyfetch = cur.fetchall()
		for i in range(len(historyfetch)):
				self.addtobkmli(historyfetch[i][0], histtodockli)
		for i in histtodockli:
			self.histli.addItem(i)

	def loadbkm(self):
		cur.execute("select * from BOOKMARKS")
		bkmfetch = cur.fetchall()
		for i in range(len(bkmfetch)):
				self.addtobkmli(bkmfetch[i][0], self.bkmlistfromfile)
		for i in self.bkmlistfromfile:
			self.bkmli.addItem(i)

	def createactions(self, text, slot=None, shortcut="None", icon=None, tip=None, checkable=False,
	                  signal="triggered()"):
		action = QAction(text, self)
		if icon is not None:
			action.setIcon(QIcon(icon))
		if shortcut is not None:
			action.setShortcut(shortcut)
		if tip is not None:
			action.setToolTip(tip)
			action.setStatusTip(tip)
		if slot is not None:
			self.connect(action, SIGNAL(signal), slot)
		if checkable:
			action.setCheckable(True)
		return action

	def addmenu(self, target, actions):
		for action in actions:
			if action is None:
				target.addSeparator()
			else:
				target.addAction(action)

	#Actions
	def addwrdf(self):
		self.dlg = addawrd()
		self.dlg.show()
		self.connect(self.dlg.buttonBox, SIGNAL("rejected()"), self.dlg.close)
		self.connect(self.dlg.buttonBox, SIGNAL("accepted()"), self.addawordtodb)


	def addawordtodb(self):
		eng = self.dlg.lineEdit.text()
		tam = self.dlg.lineEdit_2.text()
		if len(eng) != 0 and len(tam) != 0:
			cur.execute("INSERT INTO ENGTAM(ENGW, TAMW) VALUES(?, ?)", (eng, tam, ))
			self.dlg.close()
			QMessageBox.information(self, "Nigandu Eng -> Tam Dictionary", "Added Successfully. . .")
		else:
			self.dlg.lineEdit.setFocus()
			self.dlg.close()
			QMessageBox.warning(self, "Nigandu Eng -> Tam Dictionary", "Invalid Entry. . .")

	def optionsf(self):
		self.opt = optdlg(self)
		self.opt.spinBox.setProperty("value", int(self.fontsize))
		font = QFont()
		font.setPixelSize(int(self.fontsize))
		self.opt.sampletxt.setFont(font)

		if str(self.clipauto) == "True":
			self.opt.checkclip.setChecked(True)
		elif str(self.clipauto) == "False":
			self.opt.checkclip.setChecked(False)

		if str(self.histdock) == "True":
			self.opt.checkshowhistdock.setChecked(True)
		elif str(self.histdock) == "False":
			self.opt.checkshowhistdock.setChecked(False)

		if str(self.bkmdock) == "True":
			self.opt.checkshowbkmdock.setChecked(True)
		elif str(self.bkmdock) == "False":
			self.opt.checkshowbkmdock.setChecked(False)

		self.opt.show()
		self.connect(self.opt.buttonBox, SIGNAL("accepted()"), self.optok)
		self.connect(self.opt.buttonBox.button(QDialogButtonBox.Apply), SIGNAL("clicked()"), self.optapply)
		self.connect(self.opt.checkdelhist, SIGNAL("stateChanged(int)"), self.deleteallhist)
		self.connect(self.opt.checkshowhistdock, SIGNAL("stateChanged(int)"), self.shownexttime)
		self.connect(self.opt.checkshowbkmdock, SIGNAL("stateChanged(int)"), self.shownexttime)

	def shownexttime(self, i):
		if i == 0:
			pass
		if i == 2:
			QMessageBox.information(self, self.windowTitle(), "Click Apply or Ok \n The Dock window will be added, \n the next time you start the application. . .")

	def optok(self):
		self.optapply()
		self.opt.close()

	def optapply(self):
		self.updatesettings()
		self.applyopt()

	def updatesettings(self):
		self.fontsize = self.opt.spinBox.value()
		self.clipauto = self.opt.checkclip.isChecked()
		self.histdock = self.opt.checkshowhistdock.isChecked()
		self.bkmdock = self.opt.checkshowbkmdock.isChecked()
		self.delhist = self.opt.checkdelhist.isChecked()

		for i, j in [("fontsize", self.fontsize),("clipauto", str(self.clipauto)),("histdock", str(self.histdock)),
		             ("bkmdock", str(self.bkmdock)),("delhist", str(self.delhist))]:
			cur.execute("UPDATE SETTINGS SET setting=? WHERE field=?", (j, i, ))


	def applyopt(self):
		self.loadsettings()
		self.setfontsize(int(self.fontsize))
		if str(self.bkmdock) == "False" or str(self.histdock) == "False":
			self.setdocks()

	def removedock(self, dock):
		self.removeDockWidget(dock)

	def adddock(self, dock):
		self.addDockWidget(Qt.RightDockWidgetArea, dock)

	def deleteallhist(self, i):
		if i == 0:
			pass
		elif i == 2:
			self.histli.clear()
			self.histlis = [0]
			cur.execute("delete from HISTORY")
			QMessageBox.information(self, self.windowTitle(), "All the History Records are deleted. . .")

	def setfontsize(self, i):
		if i >= 8 or i <= 24:
			font = QFont()
			font.setPixelSize(i)
			self.comboBox.setFont(font)
			self.searchbtn.setFont(font)
			self.bkmli.setFont(font)
			self.histli.setFont(font)
			self.listview.setFont(font)
			self.tamtext.setFont(font)

	def helpf(self):
		form = helpform.HelpForm("index.html", self)
		form.show()

	def closeEvent(self, *args, **kwargs):
		self.writehistlis(self.histlis)
		self.writebkmlis(self.bkmlistfromfile)

		for i, j in [("fontsize", int(self.fontsize)),("clipauto", str(self.clipauto)),("histdock", str(self.histdock)),
		             ("bkmdock", str(self.bkmdock)),("delhist", str(self.delhist))]:
			cur.execute("UPDATE SETTINGS SET setting=? WHERE field=?", (j, i, ))

		con.commit()
		con.close()

	def fplusf(self):
		self.fontsize += 1
		if self.fontsize <= 24:
			self.setfontsize(self.fontsize)

	def fminusf(self):
		self.fontsize -= 1
		if self.fontsize >= 10:
			self.setfontsize(self.fontsize)

	def prevf(self):
		pr = self.histlis[0] - 1
		if pr > 1:
			self.comboBox.setText(self.histlis[pr])
			self.setevent()
			self.histlis[0] = pr
			self.go_next.setEnabled(True)
		elif pr == 1:
			self.comboBox.setText(self.histlis[pr])
			self.setevent()
			self.histlis[0] = pr
			self.go_next.setEnabled(True)
			self.go_prev.setEnabled(False)
		else:
			pass

	def nextf(self):
		pr = self.histlis[0] + 1
		if pr < len(self.histlis) - 1:
			self.comboBox.setText(self.histlis[pr])
			self.setevent()
			self.histlis[0] = pr
			self.go_prev.setEnabled(True)
		elif pr == len(self.histlis) - 1:
			self.comboBox.setText(self.histlis[pr])
			self.setevent()
			self.histlis[0] = pr
			self.go_prev.setEnabled(True)
			self.go_next.setEnabled(False)
		else:
			pass

	def randf(self):
		import random

		n = random.randrange(190538)
		cur.execute("select ENGW from ENGTAM where rowid = ?", (n, ))
		cuf = cur.fetchone()
		self.comboBox.setText(cuf[0])
		self.setevent()

	def addfavf(self):
		txt = self.comboBox.text()
		if len(txt) != 0:
			self.addtobkmli(txt, self.bkmlistfromfile)
			self.writetolistwidget(self.bkmlistfromfile, self.bkmli)


	def sortit(self):
		self.bkmlistfromfile.sort()
		self.writetolistwidget(self.bkmlistfromfile, self.form.listWidget)
		self.writetolistwidget(self.bkmlistfromfile, self.bkmli)
		cur.execute("delete from BOOKMARKS")


	def writetolistwidget(self, lis, liswid):
		liswid.clear()
		for i in lis:
			liswid.addItem(i)

	def deletecurrentbkm(self):
		ct = self.form.listWidget.currentItem().text()
		self.bkmlistfromfile.remove(ct)
		self.writetolistwidget(self.bkmlistfromfile, self.bkmli)
		self.writetolistwidget(self.bkmlistfromfile, self.form.listWidget)
		cur.execute("delete from BOOKMARKS")

	def deleteallbkm(self):
		self.form.listWidget.clear()
		self.bkmli.clear()
		self.bkmlistfromfile = []
		cur.execute("delete from BOOKMARKS")

	def viewbkmf(self):
		self.form = managebkm(self)
		self.writetolistwidget(self.bkmlistfromfile, self.form.listWidget)
		self.form.show()
		self.connect(self.form.closebtn, SIGNAL("clicked()"), self.form.close)
		self.connect(self.form.sortbtn, SIGNAL("clicked()"), self.sortit)
		self.connect(self.form.deletebtn, SIGNAL("clicked()"), self.deletecurrentbkm)
		self.connect(self.form.deleteallbtn, SIGNAL("clicked()"), self.deleteallbkm)

	def aboutf(self):
		QMessageBox.about(self, "About Nigandu English to Tamil Dictionary",
		                  """<b>Nigandu English to Tamil Dictionary</b> v %s
			                  <p>This is the first corss-platform English to Tamil
			                  bilingual dictionary; Free to use.</p>
			                  <p>Copyright &copy; 2014 NJN Private Ltd.
	                             All rights reserved.</p>
	                          <p>Thanks to Python and PySide Project.</p>
	                          <p>Using Python 3.3, Qt 4.8 and PySide 1.2.1</p>""" % (__version__))

	def visitblogf(self):
		webbrowser.open("http://www.e-nool.blogspot.com")
class HighwayAnalyzeWidget(QWidget):
    def __init__(self):
        super(HighwayAnalyzeWidget,self).__init__()
        self.averageSimulationTime = 325.0
        mainLayout = QVBoxLayout()
        mainLayout.setAlignment(Qt.AlignTop|Qt.AlignHCenter)
        mainLayout.setSpacing(0)
        self.setLayout(mainLayout)
        topWidget = QWidget()
        self.topLayout = QHBoxLayout()
        self.topLayout.setSpacing(0)
        topWidget.setLayout(self.topLayout)
        topLeftWidget = QWidget()
        self.topLeftLayout = QVBoxLayout()
        topLeftWidget.setLayout(self.topLeftLayout)
        self.setupTopGroup()
        self.setupFilterGroup()
        self.topLayout.addWidget(topLeftWidget)
        self.layout().addWidget(topWidget)
        # Button and log
        buttonAndLogWidget = QWidget()
        buttonAndLogWidget.setLayout(QVBoxLayout())
        # Analyze the results BUTTON
        self.analyzeResultsButton = QPushButton('Analyze the results')
        self.analyzeResultsButton.clicked.connect(self.analyzeResults)
        self.analyzeResultsButton.setEnabled(False)
        buttonAndLogWidget.layout().addWidget(self.analyzeResultsButton)
        # LOG
        self.logText = QTextBrowser()
        self.logText.setFont(QFont('Century Gothic', 7))
        self.logText.setWordWrapMode(QTextOption.NoWrap)
        buttonAndLogWidget.layout().addWidget(self.logText)
        self.topLayout.addWidget(buttonAndLogWidget)
        self.results = []
        self.logFile = os.path.join(self.resultsPath(), 'analyze_'+os.uname()[1]+'.log')
        # Image
        self.picLabel = QLabel()
        self.picLabel.setAlignment(Qt.AlignHCenter)
        #self.picLabel.resize(800,600)
        self.picLabel.setMinimumSize(800,600)
        self.layout().addWidget(self.picLabel)
    def setupTopGroup(self):
        topGroup = QGroupBox("Simulation Results")
        self.resultsPathLineEdit = SimpleOption('resultsPath','Results Path','/home/thomas/Dropbox/Keio/research/results/')
        topGroupLayout = QVBoxLayout()
        topGroupLayout.setSpacing(0)
        topGroupLayout.setAlignment(Qt.AlignTop)
        topGroupLayout.addWidget(self.resultsPathLineEdit)
        self.loadResultsLabel = QLabel()
        self.loadResultsLabel.setAlignment(Qt.AlignHCenter)
        topGroupLayout.addWidget(self.loadResultsLabel)
        self.loadResultsButton = QPushButton("Load the results")
        self.loadResultsButton.clicked.connect(self.loadResults)
        topGroupLayout.addWidget(self.loadResultsButton)
        topGroup.setLayout(topGroupLayout)
        self.topLeftLayout.addWidget(topGroup)
    def resultsPath(self):
        return self.resultsPathLineEdit.getValue()
    def setupFilterGroup(self):
        filterGroup = QGroupBox('Filter the results')
        filterGroupLayout = QVBoxLayout()
        filterGroupLayout.setSpacing(0)
        filterGroupLayout.setAlignment(Qt.AlignTop)
        # Distribution Model
        self.filterDistribution = SimpleComboboxOption('dis','Speed Distribution Model',3, True, 'Uniform','Exponential','Normal','Log Normal')
        filterGroupLayout.addWidget(self.filterDistribution)
        self.filterDistribution.setVisible(False)
        # Number of results per point
        self.filterNb = SimpleSpinOption('simuNbMin', 'Minimum results for a given setting', 10, integer=True, checkable=True)
        self.filterNb.checkBox.setChecked(True)
        filterGroupLayout.addWidget(self.filterNb)
        # Filter the date
        dateWidget = QWidget()
        dateWidget.setLayout(QHBoxLayout())
        self.filterDate = QCheckBox('After')
        self.filterDate.setChecked(QSettings().value('filterDate','0')=='1')
        dateWidget.layout().addWidget(self.filterDate)
        self.filterDateYear = QComboBox()
        for m in xrange(2010,2012):
            self.filterDateYear.addItem(str(m))
        self.filterDateYear.setCurrentIndex(int(QSettings().value('dateYear', 1)))
        dateWidget.layout().addWidget(self.filterDateYear)
        dateWidget.layout().addWidget(QLabel('Year'))
        self.filterDateMonth = QComboBox()
        for m in xrange(1,13):
            self.filterDateMonth.addItem(str(m))
        self.filterDateMonth.setCurrentIndex(int(QSettings().value('dateMonth', 4)))
        dateWidget.layout().addWidget(self.filterDateMonth)
        dateWidget.layout().addWidget(QLabel('Month'))
        self.filterDateDay = QComboBox()
        for d in xrange(1,32):
            self.filterDateDay.addItem(str(d))
        self.filterDateDay.setCurrentIndex(int(QSettings().value('dateDay', 0)))
        dateWidget.layout().addWidget(self.filterDateDay)
        dateWidget.layout().addWidget(QLabel('Day'))
        filterGroupLayout.addWidget(dateWidget)
        filterGroup.setLayout(filterGroupLayout)
        self.topLeftLayout.addWidget(filterGroup)
        # Filter the scenario
        self.filterScenar = SimpleComboboxOption('scenar','Scenario',1, True, 'vanet-highway-test-thomas','vanet-highway-scenario2')
        filterGroupLayout.addWidget(self.filterScenar)
        # Filter gap
        self.filterGap = SimpleSpinOption('avgdistanalyze','Average Distance (m)',100, checkable=True)
        filterGroupLayout.addWidget(self.filterGap)
    def loadResults(self):
        self.loadResultsButton.setText('Loading the results...')
        self.loadResultsButton.setEnabled(False)
        self.results = []
        self.resultsThread = LoadResults(resultsPath=self.resultsPath())
        self.resultsThread.done.connect(self.loadResultsDone)
        self.resultsThread.error.connect(self.loadResultsError)
        self.resultsThread.start()
    @Slot(str)
    def loadResultsError(self, errorMsg):
        QMessageBox.critical(self, 'Error!', errorMsg)
        self.analyzeResultsButton.setEnabled(False)
    @Slot(dict)
    def loadResultsDone(self, results):
        self.results = results
        resultsNb = len(self.results)
        msg= 'Found %d Simulation Results\n(%d invalid files, %d simulations failed)' % (resultsNb, self.resultsThread.fileUnloadable, self.resultsThread.simulationFailed)
        self.loadResultsLabel.setText(msg)
        #self.calculateAverageSimulationTime()
        self.loadResultsButton.setText('Reload the results')
        self.loadResultsButton.setEnabled(True)
        self.analyzeResultsButton.setEnabled(True)
        if resultsNb>0:
            self.analyzeResults()
    def calculateAverageSimulationTime(self):
        totalTime = 0
        nb = 0
        for r in self.results:
            if 'simulationTime' in r:
                #print 'simu time: %s' % r['simulationTime']
                totalTime += int(r['simulationTime'])
                nb += 1
            #print 'from %s: [%3.3f,%3.3f]' % (r['filename'], r['settings']['prate'],r['results']['timeToReachDest'])
        if nb<=0:
            errorMsg= 'No simulation found with simulationTime'
            QMessageBox.critical(self, 'Error!', errorMsg)
            self.averageSimulationTime = 290.0
        else:
            self.averageSimulationTime= totalTime/nb
            self.loadResultsLabel.setText(self.loadResultsLabel.text()+'\nAverage simulation time: %3.0f'%self.averageSimulationTime)
    def fil(self, r):
        return self.checkDis(r) and self.checkDate(r) and self.checkGap(r) and self.checkScenario(r)
    def checkDis(self,r):
        return (not self.filterDistribution.checkBox.isChecked()) or r['settings']['dis']==self.filterDistribution.getValue()
    def checkDate(self, r):
        return (not self.filterDate.isChecked()) or (r['date'] >= datetime(int(self.filterDateYear.currentText()), int(self.filterDateMonth.currentText()), int(self.filterDateDay.currentText())))
    def checkScenario(self, r):
        return (not self.filterScenar.checkBox.isChecked()) or r['scenario']==self.filterScenar.getName()
    def checkGap(self, r):
        return (not self.filterGap.checkBox.isChecked()) or float(r['settings']['avgdist'])==float(self.filterGap.getValue())
    def analyzeResults(self):
        self.saveSettings()
        if len(self.results)<=0:
            QMessageBox.critical(self, 'Error!', 'No results loaded :s')
            return
        self.log("=== ANALYZING RESULTS ===")
        self.logText.clear()
        p=0
        meanValues = {}
        uniqueName = dateToFilename()
        gnuPlotDataFile =os.path.join(self.resultsPath(),'graphs/' + uniqueName+'.dat')
        with open(gnuPlotDataFile,'w') as data:
            while p<=100:
                nb = 0
                totalTimeToReachDest = 0
                totalSimulationTime  = 0
                for result in filter(lambda x: x['settings']['prate']==p and self.fil(x), self.results):
                    totalSimulationTime  += float(result['simulationTime'])
                    totalTimeToReachDest += float(result['results']['timeToReachDest'])
                    nb += 1
                if self.filterNb.checkBox.isChecked():
                    minNb = self.filterNb.getValue()
                else:
                    minNb = 0
                if nb>minNb:
                    meanSimulationTime  = float(1.0*totalSimulationTime/nb)
                    meanTimeToReachDest = float(1.0*totalTimeToReachDest/nb)
                    meanValues[p] = {'prate':p,
                                     'simuLationTime':meanSimulationTime,
                                     'simulationsNb':nb,
                                     'timeToReachDest':meanTimeToReachDest}
                    self.log(meanValues[p])
                    toPlot = '%s %s' % (p, meanValues[p]['timeToReachDest'])
                    #print toPlot
                    data.write(toPlot+'\n')
                p += 1
            data.close()
        if len(meanValues)>0:
            outputPic = 'graphs/' + uniqueName
            s = subprocess.Popen(['./toPlot.sh', outputPic, gnuPlotDataFile], cwd=self.resultsPath())
            s.wait()
            outputPicPath = os.path.join(self.resultsPath(),outputPic+'.svg')
            pic = QImage(outputPicPath)
            #pic = pic.scaled(QSize(640,480))
            self.picLabel.setPixmap(QPixmap(pic))
            #os.system(os.path.join(self.resultsPath(),'toPlot.sh'))
        else:
            QMessageBox.critical(self, 'Error!', 'No simulation satisfies the criteria...')
    def log(self, txt):
        toLog = str(txt)
        toLogFile = '%s | %s' % (datetime.now(), txt)
        with open(self.logFile, 'a') as logFile:
            logFile.write(toLogFile+'\n')
        self.logText.append(toLog)
    def saveSettings(self):
        QSettings().setValue('simuNbMin', self.filterNb.getValue())
        QSettings().setValue('avgdistanalyze', self.filterGap.getValue())
        QSettings().setValue('scenar', self.filterScenar.getValue())
        QSettings().setValue('dis', self.filterDistribution.getValue())
        QSettings().setValue('dateDay', self.filterDateDay.currentIndex())
        QSettings().setValue('dateMonth', self.filterDateMonth.currentIndex())
        QSettings().setValue('dateYear', self.filterDateYear.currentIndex())
        if self.filterDate.isChecked():
            QSettings().setValue('filterDate', '1')
        else:
            QSettings().setValue('filterDate', '0')
class HighwaySimulatorGui(QMainWindow):
    def __init__(self):
        super(HighwaySimulatorGui, self).__init__()
        centralTab = QTabWidget()
        mainWidget = QWidget()
        self.resultsWidget = HighwayAnalyzeWidget()
        centralTab.addTab(mainWidget, 'Run')
        centralTab.addTab(self.resultsWidget, 'Analyze')
        self.setCentralWidget(centralTab)
        centralLayout = QVBoxLayout()
        #centralLayout.setSpacing(0)
        centralLayout.setAlignment(Qt.AlignTop)
        gridWidget = QWidget()
        gridLayout = QGridLayout()
        gridLayout.setSpacing(0)
        gridWidget.setLayout(gridLayout)
        mainWidget.setLayout(centralLayout)
        self.options = dict()
        # GENERAL
        generalGroup = QGroupBox('General Settings')
        generalGroup.setLayout(QVBoxLayout())
        generalGroup.layout().setSpacing(0)
        self.pathOption = SimpleOption('path','Output Path','/home/thomas/Dropbox/Keio/research/results/')
        generalGroup.layout().addWidget(self.pathOption)
        self.scenarioOption = SimpleComboboxOption('scenario','Scenario',1, False, 'vanet-highway-test-thomas','vanet-highway-scenario2')
        self.scenarioOption.combo.currentIndexChanged[int].connect(self.scenarioChanged)
        generalGroup.layout().addWidget(self.scenarioOption)
        self.options['time'] = SimpleSpinOption('time','Simulation Time (sec.)',1500,True)
        self.options['time'].setRange(0,3000)
        self.options['mix'] = SimpleSpinOption('mix','Percentage of cars compare to trucks (%)',80,True)
        self.options['mix'].setRange(0,100)
        self.options['gap'] = SimpleSpinOption('gap','Average Gap (m.)',5)
        self.options['gap'].setRange(1,2000)
        self.options['lane'] = SimpleSpinOption('lane','Number of Lanes',2,True)
        self.options['lane'].setRange(2,4)
        self.options['spl'] = SimpleSpinOption('spl','Speed Limit (km/h)',130,True)
        self.options['spl'].setRange(1,200)
        for widget in ('time','mix','gap','lane','spl'):
            generalGroup.layout().addWidget(self.options[widget])
        gridLayout.addWidget(generalGroup,0,0)
        # TRAFFIC
        trafficGroup = QGroupBox('Traffic Settings')
        trafficGroup.setLayout(QVBoxLayout())
        trafficGroup.layout().setSpacing(0)
        # m/s = (km/h)*1000/3600
        self.options['vel1'] = SimpleSpinOption('vel1','Average Speed (km/h)',105,True)
        self.options['vel1'].setRange(5,150)
        self.options['dis'] = SimpleComboboxOption('dis','Speed Distribution Model',3, False, 'Uniform','Exponential','Normal','Log Normal')
        self.options['spstd'] = SimpleSpinOption('spstd','Speed Distribution Variance',1.0)
        self.options['spstd'].setRange(0,50)
        self.options['flow1'] = SimpleSpinOption('flow1','Traffic Flow Mean (veh/s)',1.0)
        self.options['flow1'].setRange(0.1,50.0)
        self.options['std1'] = SimpleSpinOption('std1','Traffic Flow Variance',0.8)
        self.options['std1'].setRange(0.1,50.0)
        self.options['maxflow'] = SimpleSpinOption('maxflow','Traffic Maximum Flow (veh/s)',5)
        self.options['maxflow'].setRange(0.1,50.0)
        # Scenar 2
        self.options['avgdist'] = SimpleSpinOption('avgdist','Average Distance (m)',100)
        self.options['avgdist'].setRange(1,10000)
        self.options['avgspeed'] = SimpleSpinOption('avgspeed','Average Speed (km/h)',105)
        self.options['avgspeed'].setRange(1,10000)
        self.options['despeed'] = SimpleSpinOption('despeed','Desired Speed (km/h)',130)
        self.options['despeed'].setRange(1,10000)
        self.options['ambumaxspeed'] = SimpleSpinOption('ambumaxspeed','Ambu Max Speed (km/h)',165)
        self.options['ambumaxspeed'].setRange(1,10000)
        self.options['ambuinitspeed'] = SimpleSpinOption('ambuinitspeed','Ambu Initial Speed (km/h)',130)
        self.options['ambuinitspeed'].setRange(1,10000)
        for widget in ('vel1','dis','spstd','flow1','std1','maxflow',
                       'avgdist', 'avgspeed', 'despeed', 'ambumaxspeed', 'ambuinitspeed'):
            trafficGroup.layout().addWidget(self.options[widget])
        self.scenarioChanged(self.scenarioOption.combo.currentIndex())
        gridLayout.addWidget(trafficGroup,0,1)
        # VANET
        vanetGroup = QGroupBox('VANET Settings')
        vanetGroup.setLayout(QVBoxLayout())
        vanetGroup.layout().setSpacing(0)
#        self.options['prate'] = SimpleSpinOption('prate','Penetration Rate of VANET (%)',100,True)
#        self.options['prate'].setRange(0,100)
        self.options['prate'] = 0 # start with 0
        self.options['pw'] = SimpleSpinOption('pw','Transmission Power (dBm)',21.5)
        self.options['pw'].setRange(10,50)
        #for widget in ('prate','pw'):
        for widget in ('pw',):
            vanetGroup.layout().addWidget(self.options[widget])
        gridLayout.addWidget(vanetGroup,1,0)
        # BATCH SETTINGS
        batchGroup = QGroupBox("Batch Settings")
        batchGroup.setLayout(QVBoxLayout())
        self.gapPrateOption = SimpleSpinOption('gapPrate', 'VANET percentage rate gap', 10, integer=True)
        self.sameSimuTimesOption = SimpleSpinOption('sameSimuTimes', 'How many times the same simulation', 100, integer=True)
        batchGroup.layout().setSpacing(0)
        batchGroup.layout().addWidget(self.gapPrateOption)
        batchGroup.layout().addWidget(self.sameSimuTimesOption)
        gridLayout.addWidget(batchGroup,1,1)
        # START SIMU
        centralLayout.addWidget(gridWidget)
        self.startButton = QPushButton('START')
        self.startButton.clicked.connect(self.startSimu)
        centralLayout.addWidget(self.startButton)
        self.progressBar    = QProgressBar()
        centralLayout.addWidget(self.progressBar)
        self.shutdownWhenDone = QCheckBox('Shutdown when done')
        self.actionWhenDone = QComboBox()
        self.actionWhenDone.addItems(['When finished... do nothing', 'When finished... shutdown the computer', 'When finished... Re-run the simulations!'])
        self.actionWhenDone.setCurrentIndex(int(QSettings().value('actionWhenDone', 0)))
        centralLayout.addWidget(self.actionWhenDone)
        self.infoLabel = QLabel()
        centralLayout.addWidget(self.infoLabel)
        # LOG
        self.logText = QTextBrowser()
        self.logText.setFont(QFont('Century Gothic', 7))
        centralLayout.addWidget(self.logText)
        self.setWindowTitle('Nishimura Lab | Highway Simulation')
        #self.resize(520,len(self.options)*60+100)
        #self.resultFile = open('/home/thomas/Dropbox/Keio/research/results/summary.txt', 'a')
        #self.resultFile = os.path.join(self.pathOption.getValue(), 'summary.txt')
        self.logFile = os.path.join(self.pathOption.getValue(), 'results_'+os.uname()[1]+'.log')
    @Slot(int)
    def scenarioChanged(self, index):
        #print index
        scenar1options = ['gap', 'vel1', 'dis', 'flow1', 'std1','spstd', 'maxflow']
        scenar2options = ['avgdist', 'avgspeed', 'despeed', 'ambumaxspeed', 'ambuinitspeed']
        if index==0: # first scenario
            scenar1 = True
            scenar2 = False
        else:
            scenar1 = False
            scenar2 = True
        for option in scenar1options:
            self.options[option].setVisible(scenar1)
        for option in scenar2options:
            self.options[option].setVisible(scenar2)
    def log(self, txt):
        toLog = '%s | %s' % (datetime.now(), txt)
        with open(self.logFile, 'a') as logFile:
            logFile.write(toLog+'\n')
        self.logText.append(toLog)
    def blockUi(self):
        self.startButton.setEnabled(False)
        self.scenarioOption.setEnabled(False)
        for option in self.options:
            if option!='prate':
                self.options[option].setEnabled(False)
    def releaseUi(self):
        self.startButton.setEnabled(True)
        self.scenarioOption.setEnabled(True)
        self.startButton.setText('START')
        for option in self.options:
            if option!='prate':
                self.options[option].setEnabled(True)
    def startSimu(self):
        self.log("=== SIMULATIONS START ===")
        self.logText.clear()
        self.startTime = datetime.now()
        self.simulations = []
        #self.nextPrate = 0
        self.gapPrate  = self.gapPrateOption.getValue()
        self.sameSimuTimes = self.sameSimuTimesOption.getValue()
        #self.nextSimu   = 0
        self.blockUi()
        self.simulationsDone = 0
        #output = self.pathOption.getValue() + dateToFilename(d) + '_results.txt'
        pRate = 0
        self.simulationsTotal = 0
#        print 'sameSimuTimes: %d'%self.sameSimuTimes
#        print 'gapPrate: %d'%self.gapPrate
        while pRate <= 100:
            simu = 0
            self.options['prate'] = pRate
            while simu<self.sameSimuTimes:
                waf = WafThread(self.options, self.pathOption.getValue(), self.scenarioOption.getName())
                waf.setAutoDelete(True)
                waf.simuDone.connect(self.wafDone)
                self.simulations.append(waf)
                QThreadPool.globalInstance().start(waf)
                self.simulationsTotal += 1
                simu += 1
            pRate += self.gapPrate
        runningSimulations = 'Running %d Simulations...' % self.simulationsTotal
        self.startButton.setText(runningSimulations)
        self.log(runningSimulations)
        self.progressBar.setRange(0,self.simulationsTotal)
        self.progressBar.setValue(0)
        # 300 seconds per task average
        roughTime = self.simulationsTotal*self.resultsWidget.averageSimulationTime/QThreadPool.globalInstance().maxThreadCount()
        self.infoLabel.setText('Rough time estimation: %s' % formatTimeLeft(roughTime))
    @Slot(str)
    def wafDone(self, outputPath):
        #print 'thread done!\nReceived:'
        self.simulationsDone += 1
        simulationsLeft = self.simulationsTotal-self.simulationsDone
        with open(outputPath,'r') as out:
            r = json.loads(out.read())
            out.close()
            if 'timeToReachDest' in r['results']:
                try:
                    result = "%3.3d\t%f" % (int(r['settings']['prate']),float(r['results']['timeToReachDest']))
                except TypeError, e:
                    result = 'PYTHON ERROR: %s | File: %s' % (e, outputPath)
                    print result
                    print r
            else: