From c7800ebea0603d238f73cf38086b724f98edc80b Mon Sep 17 00:00:00 2001 From: Stepan Bahnik Date: Sat, 9 Aug 2014 22:30:00 +0200 Subject: [PATCH] new parameters, features in comments & batch time --- Stuff/Modules/cm.py | 5 ++++ Stuff/Modules/comment.py | 41 ++++++++++++++++++++++---------- Stuff/Modules/controller.py | 2 +- Stuff/Modules/explorer.py | 56 +++++++++++++++++++++++++++++--------------- Stuff/Modules/filestorage.py | 5 +++- Stuff/Modules/parameters.py | 21 ++++++++++++++--- Stuff/Modules/processor.py | 9 ++++++- Stuff/Modules/showtracks.py | 13 +++++++++- Stuff/Modules/starter.py | 2 +- Stuff/Modules/tools.py | 52 ++++++++++++++++++++++++++++++++++------ Stuff/Modules/version.py | 2 +- Stuff/Modules/window.py | 2 +- 12 files changed, 162 insertions(+), 48 deletions(-) diff --git a/Stuff/Modules/cm.py b/Stuff/Modules/cm.py index b99481a..5088382 100644 --- a/Stuff/Modules/cm.py +++ b/Stuff/Modules/cm.py @@ -764,6 +764,11 @@ def getSpeedAfterShock(self, time = 20, startTime = 0, after = 25, absolute = Fa else: return format(median(angles), "0.2f") + + def countReflections(self, time = 20, startTime = 0): + "used in processor as a parameter" + reflections = self.findReflections(time = time, startTime = startTime) + return reflections[0] + reflections[1] def findReflections(self, time = 20, startTime = 0, results = "both"): diff --git a/Stuff/Modules/comment.py b/Stuff/Modules/comment.py index 9f4049f..fa825bc 100644 --- a/Stuff/Modules/comment.py +++ b/Stuff/Modules/comment.py @@ -27,41 +27,58 @@ class Comment(Toplevel): "class used to adding and viewing comments" - def __init__(self, root, filename): + def __init__(self, root, files, correct = True): super().__init__(root) - + self.root = root self.fileStorage = self.root.fileStorage - placeWindow(self, 574, 190) + placeWindow(self, 574, 215) self.title("Comment") self.grab_set() self.focus_set() - self.file = filename - self.comment = self.fileStorage.comments[self.file] + if type(files) is str: + files = [files] + self.files = files + if len(self.files) == 1: + filename = self.files[0] + self.comment = self.fileStorage.comments[filename] + self.name = ttk.Label(self, text = filename) + else: + self.comment = "" + self.name = ttk.Label(self, text = "{} files selected".format(len(self.files))) - self.name = ttk.Label(self, text = filename) self.okBut = ttk.Button(self, text = "Ok", command = self.okFun) self.closeBut = ttk.Button(self, text = "Close", command = self.destroy) self.text = Text(self, height = 8, wrap = "word", width = 70) - self.okBut.grid(column = 2, row = 2, pady = 2, padx = 10) - self.closeBut.grid(column = 1, row = 2, pady = 2, padx = 10) + self.okBut.grid(column = 2, row = 3, pady = 2, padx = 10) + self.closeBut.grid(column = 1, row = 3, pady = 2, padx = 10) self.name.grid(column = 0, row = 0, columnspan = 4, pady = 3, padx = 5) - self.text.grid(column = 0, row = 1, columnspan = 4, pady = 2, padx = 5, + self.text.grid(column = 0, row = 2, columnspan = 4, pady = 2, padx = 5, sticky = (N, S, E, W)) + if not correct: + warning = "Warning: This file is not the one currently displayed!" + self.warning = ttk.Label(self, text = warning) + self.warning.grid(column = 0, row = 1, columnspan = 4, pady = 3, padx = 5) + self.columnconfigure(0, weight = 1) self.columnconfigure(3, weight = 1) - self.rowconfigure(1, weight = 1) + self.rowconfigure(2, weight = 1) self.text.insert("1.0", self.comment) self.text.bind("<3>", lambda e: self.popUp(e)) + self.text.focus_set() def okFun(self): "saves the comment in filestorage" - comment = self.text.get("1.0", "end") - self.fileStorage.comments[self.file] = comment.strip() + comment = self.text.get("1.0", "end").strip() + for file in self.files: + if self.fileStorage.comments[file] and len(self.files) > 1: + self.fileStorage.comments[file] += "\n" + comment + else: + self.fileStorage.comments[file] = comment self.root.refresh() self.destroy() diff --git a/Stuff/Modules/controller.py b/Stuff/Modules/controller.py index 7f096d1..5872deb 100644 --- a/Stuff/Modules/controller.py +++ b/Stuff/Modules/controller.py @@ -47,7 +47,7 @@ def __init__(self): results = 'both')"""], ["Outside Points", """countOutsidePoints(time = time, startTime = startTime, distance = optionGet('OutsidePointsDistance', - 1, ['int', 'float']))"""], + 1, 'int'))"""], ["Bad Points", "countBadPoints(time = time, startTime = startTime)"] ] diff --git a/Stuff/Modules/explorer.py b/Stuff/Modules/explorer.py index c7d8074..3871240 100644 --- a/Stuff/Modules/explorer.py +++ b/Stuff/Modules/explorer.py @@ -260,6 +260,9 @@ def __init__(self, root): self.saveWhatCombo.grid(column = 1, row = 0) self.saveWhichFilesCombo.grid(column = 1, row = 1) + # statusBar binding + self.statusBar.bind("", self._statusBarDoubleclick) + # parametersLF popUp menu bindings self.parametersLF.bind("", self.parametersPopUp) for child in self.parametersLF.winfo_children(): @@ -269,7 +272,7 @@ def __init__(self, root): for number, gType in enumerate(getGraphTypes()): ttk.Radiobutton(self.graphLF, text = gType[0], variable = self.graphTypeVar, command = self.changedGraph, value = gType[1])\ - .grid(row = number, pady = 2, padx = 1, sticky = (W)) + .grid(row = number, pady = 1, padx = 1, sticky = (W)) # bindings self.bind("", lambda e: self.fileFrame.nextFun()) @@ -733,9 +736,15 @@ def initializeFile(self, filename, new = True, timeReset = True): 100 + self.minTime)) self._changeButtonStatuses() - - self.initialized = True + self._showComment(filename) + self.initialized = True + if new and timeReset: + self.curTime.set(0) + self.timeVar.set(self._timeFormat(self.minTime)) + + + def _showComment(self, filename): if self.fileStorage.comments[filename]: comment = self.fileStorage.comments[filename].replace("\n", "\t") if len(comment) > 150: @@ -743,12 +752,14 @@ def initializeFile(self, filename, new = True, timeReset = True): self.status.set(comment) else: self.status.set("") - - if new and timeReset: - self.curTime.set(0) - self.timeVar.set(self._timeFormat(self.minTime)) + def _statusBarDoubleclick(self, e): + "opens comment window after doubleclick to status bar" + if self.fileFrame.selected: + Comment(self.fileFrame, self.fileFrame.selected, True) + + def _loadData(self, filename): try: if filename in self.fileStorage.pairedfiles: @@ -1158,6 +1169,7 @@ def __init__(self, root): self.tree.bind("<1>", lambda e: self.click(e)) self.tree.bind("<3>", lambda e: self.popUp(e)) + self.tree.bind("", lambda e: self.doubleclick(e)) self.tree.tag_configure("comment", background = commentColor()) # previous and next buttons @@ -1233,7 +1245,15 @@ def click(self, event): if not self.root.animate: self.root.stopFun() self.root.playFun() - + + + def doubleclick(self, event): + "called when item in tree is doubleclicked" + item = self.tree.identify("item", event.x, event.y) + file = self.files[int(item)] + if file == self.selected: + Comment(self, file, True) + def previousFun(self): "shows previous file" @@ -1268,17 +1288,14 @@ def nextFun(self): def orderByNames(self): "orders files by names" if self.files: - selected = self.files[eval(self.tree.selection()[0])] self.files.sort() - self.drawTree(selected = selected) + self.drawTree(selected = self.selected) def orderByTag(self): "order files by tags" if self.files: - selected = self.files[eval(self.tree.selection()[0])] - self.files.sort(key = lambda i: (i in self.fileStorage.tagged), - reverse = True) - self.drawTree(selected = selected) + self.files.sort(key = lambda i: (i in self.fileStorage.tagged), reverse = True) + self.drawTree(selected = self.selected) def drawTree(self, selected = None): @@ -1290,8 +1307,8 @@ def drawTree(self, selected = None): tag = "x" if file in self.fileStorage.tagged else "" values = (tag) comment = "comment" if self.fileStorage.comments[file] else "withoutComment" - self.tree.insert("", "end", str(count), text = returnName( - file, self.files), values = values, tag = comment) + self.tree.insert("", "end", str(count), text = returnName(file, self.files), + values = values, tag = comment) if selected: self.index = self.files.index(selected) @@ -1305,8 +1322,8 @@ def drawTree(self, selected = None): def refresh(self): "refreshes the tree after adding a comment" - selected = self.files[eval(self.tree.selection()[0])] - self.drawTree(selected = selected) + self.root._showComment(self.selected) + self.drawTree(selected = self.selected) def popUp(self, event): @@ -1315,7 +1332,8 @@ def popUp(self, event): menu = Menu(self, tearoff = 0) file = self.files[int(item)] if item: - menu.add_command(label = "Add comment", command = lambda: Comment(self, file)) + correct = True if file == self.selected else False + menu.add_command(label = "Add comment", command = lambda: Comment(self, file, correct)) if file in self.fileStorage.tagged: menu.add_command(label = "Remove tag", command = lambda: self.untagFun(index = int(item))) diff --git a/Stuff/Modules/filestorage.py b/Stuff/Modules/filestorage.py index bec265a..3944b11 100644 --- a/Stuff/Modules/filestorage.py +++ b/Stuff/Modules/filestorage.py @@ -392,9 +392,12 @@ def popUp(self, event): else: menu.add_command(label = "Add tag", command = lambda: self.tagFun(item)) menu.add_command(label = "Add comment", command = lambda: Comment(self, item)) + selection = self.filesTree.selection() + if len(selection) > 1 and any([item == file for file in selection]): + menu.add_command(label = "Add comments", command = lambda: Comment(self, selection)) menu.add_separator() if self.filesTree.identify("column", event.x, event.y) == "#0" and m.files == "pair": - menu.add_command(label = "Open room file", + menu.add_command(label = "Open paired file", command = lambda: self.openRoomFile(item)) menu.add_separator() menu.add_command(label = "Show track", command = lambda: self.showTracks(item)) diff --git a/Stuff/Modules/parameters.py b/Stuff/Modules/parameters.py index d56caa3..9bba1a9 100644 --- a/Stuff/Modules/parameters.py +++ b/Stuff/Modules/parameters.py @@ -107,6 +107,12 @@ def __init__(self): "borderPercentSize": (Opt('borderPercentSizeStrategies', 50, ['int', 'float']), "Annulus width [in percents]") }) + self["Bad points"] = Par("countBadPoints", "info", {}) + self["Reflections"] = Par("countReflections", "info", {}) + self["Outside points"] = Par("countOutsidePoints", "info", { + "distance": (Opt('OutsidePointsDistance', 1, 'int'), + "Distance from margin counted [in pixels]"), + }) #self.findParameters() @@ -145,7 +151,10 @@ def __init__(self): "Proportion of time moving", "Mean distance from center", "Real minimum time", - "Real maximum time"} + "Real maximum time", + "Bad points", + "Reflections", + "Outside points"} for name, parameter in ParametersCM().items(): if name in mwm: self[name] = parameter @@ -194,7 +203,10 @@ def __init__(self): "Proportion of time moving", "Mean distance from center", "Real minimum time", - "Real maximum time"} + "Real maximum time", + "Bad points", + "Reflections", + "Outside points"} for name, parameter in ParametersCM().items(): if name in of: self[name] = parameter @@ -231,7 +243,10 @@ def __init__(self): "Maximum time of immobility", "Proportion of time moving", "Real minimum time", - "Real maximum time"} + "Real maximum time", + "Bad points", + "Reflections", + "Outside points"} for name, parameter in ParametersCM().items(): if name in ra: self[name] = parameter diff --git a/Stuff/Modules/processor.py b/Stuff/Modules/processor.py index d6c1a3e..a53a213 100644 --- a/Stuff/Modules/processor.py +++ b/Stuff/Modules/processor.py @@ -67,7 +67,7 @@ def __init__(self, root): variable = self.useBatchTimeVar, command = self.toggledUseBatchTime) self.setBatchTimeBut = ttk.Button(self.timeLabFrame, text = "Set", width = 3, - command = lambda: SetBatchTime(self)) + command = self.setBatchTime) # labels self.statusBar = ttk.Label(self, textvariable = self.status) @@ -302,6 +302,13 @@ def toggledUseBatchTime(self): self.timeFrame.totalTime.state(["!disabled"]) self.timeFrame.startTime.state(["!disabled"]) + + def setBatchTime(self): + SetBatchTime(self) + if not self.useBatchTimeVar.get(): + self.useBatchTimeVar.set(True) + self.toggledUseBatchTime() + def checkProcessing(self): "method updating page after change of notebook tab" diff --git a/Stuff/Modules/showtracks.py b/Stuff/Modules/showtracks.py index 7e0d901..2f0a9f5 100644 --- a/Stuff/Modules/showtracks.py +++ b/Stuff/Modules/showtracks.py @@ -344,6 +344,7 @@ def __init__(self, root, files, controlled = False): self.tree.configure(yscrollcommand = self.scrollbar.set) self.tree.bind("<1>", lambda e: self.click(e)) + self.tree.bind("", lambda e: self.doubleclick(e)) self.tree.bind("<3>", lambda e: self.popUp(e)) self.tree.tag_configure("comment", background = commentColor()) @@ -499,6 +500,13 @@ def click(self, event): self.root.drawTracks(new = True) self.checkTag() + + def doubleclick(self, event): + "called when item in tree is clicked" + item = self.tree.identify("item", event.x, event.y) + if item and self.index == int(item): + Comment(self, self.files[eval(self.tree.selection()[0])]) + def previousFun(self): "shows previous file" @@ -594,7 +602,10 @@ def popUp(self, event): menu = Menu(self, tearoff = 0) if item: file = self.files[int(item)] - menu.add_command(label = "Add comment", command = lambda: Comment(self, file)) + if int(item) == self.index: + menu.add_command(label = "Add comment", command = lambda: Comment(self, file)) + else: + menu.add_command(label = "Add comment", command = lambda: Comment(self, file, False)) if file in self.fileStorage.tagged: menu.add_command(label = "Remove tag", command = lambda: self.untagFun(index = int(item))) diff --git a/Stuff/Modules/starter.py b/Stuff/Modules/starter.py index e89f2d6..cd41e99 100644 --- a/Stuff/Modules/starter.py +++ b/Stuff/Modules/starter.py @@ -51,7 +51,7 @@ def __init__(self): self.after(250, lambda: print(self.winfo_width())) self.after(250, lambda: print(self.winfo_height())) ''' - x, y = 1010, 813 + x, y = 1010, 774 self.minsize(x, y) placeWindow(self, x, y) diff --git a/Stuff/Modules/tools.py b/Stuff/Modules/tools.py index 76f49fd..4e8b0bb 100644 --- a/Stuff/Modules/tools.py +++ b/Stuff/Modules/tools.py @@ -21,6 +21,7 @@ from tkinter import ttk from tkinter.filedialog import askopenfilename, asksaveasfilename from tkinter import messagebox +from decimal import Decimal import pickle import os @@ -103,6 +104,7 @@ def __init__(self, root): # frames self.buttonFrame = ttk.Frame(self) + self.splittingFrame = ttk.Frame(self) self.removeFrame = ttk.Frame(self) self.timeFrame = TimeFrame(self, observe = False) @@ -115,6 +117,17 @@ def __init__(self, root): self.resetBut = ttk.Button(self.removeFrame , text = "Reset", command = self.resetFun) self.clearBut = ttk.Button(self.removeFrame , text = "Clear", command = self.clearFun) + # splitting buttons + self.split2 = ttk.Button(self.splittingFrame, text = "Split in 2", + command = lambda: self.splitTime(2), width = 9) + self.split3 = ttk.Button(self.splittingFrame, text = "Split in 3", + command = lambda: self.splitTime(3), width = 9) + self.split5 = ttk.Button(self.splittingFrame, text = "Split in 5", + command = lambda: self.splitTime(5), width = 9) + self.split2.grid(column = 0, row = 0) + self.split3.grid(column = 0, row = 1) + self.split5.grid(column = 0, row = 2) + # text self.text = Text(self, height = 5, wrap = "word", width = 73) self.text.insert("1.0", self.batchTime) @@ -124,10 +137,14 @@ def __init__(self, root): self.text["background"] = self._color() else: self.addBut["state"] = "disabled" + self.split2["state"] = "disabled" + self.split3["state"] = "disabled" + self.split5["state"] = "disabled" self.removeLastBut["state"] = "disabled" # adding to grid self.buttonFrame.grid(column = 1, row = 0, sticky = W, pady = 2) + self.splittingFrame.grid(column = 2, row = 0, pady = 2, sticky = W) self.removeFrame.grid(column = 3, row = 0, pady = 3) self.timeFrame.grid(column = 0, row = 0) @@ -149,7 +166,7 @@ def __init__(self, root): width = 3).grid(column = 0, row = 1) ttk.Button(self.buttonFrame, text = "+10", command = lambda: self.addTime(10), width = 3).grid(column = 1, row = 1) - + def _color(self): return "grey94" @@ -215,6 +232,9 @@ def enableManualChange(self): self.text["state"] = "normal" self.text["background"] = "white" self.addBut["state"] = "disabled" + self.split2["state"] = "disabled" + self.split3["state"] = "disabled" + self.split5["state"] = "disabled" self.removeLastBut["state"] = "disabled" def _checkText(self): @@ -250,6 +270,9 @@ def disableManualChange(self): self.text["state"] = "disabled" self.text["background"] = self._color() self.addBut["state"] = "normal" + self.split2["state"] = "normal" + self.split3["state"] = "normal" + self.split5["state"] = "normal" self.removeLastBut["state"] = "normal" def addTime(self, x): @@ -257,13 +280,28 @@ def addTime(self, x): start = int(self.timeFrame.startTimeVar.get()) + x end = int(self.timeFrame.timeVar.get()) + x self.timeFrame.startTimeVar.set(str(start)) - self.timeFrame.timeVar.set(str(end)) - - - - - + self.timeFrame.timeVar.set(str(end)) + + def splitTime(self, x): + "splits all time bins in x new bins" + newSlots = [] + for slot in self.batchTime: + start = Decimal(slot[0]) + end = Decimal(slot[1]) + diff = (end - start) / x + for i in range(x): + newSlots.append((start + i*diff, start + (i+1)*diff)) + self.batchTime = [(self._roundDecimal(slot[0]), + self._roundDecimal(slot[1])) for slot in newSlots] + self._updateText() + def _roundDecimal(self, d): + "helper function for splitTime" + if d == round(d): + return int(d) + else: + return round(float(d), 3) + diff --git a/Stuff/Modules/version.py b/Stuff/Modules/version.py index 62bb6ca..f8e3bcd 100644 --- a/Stuff/Modules/version.py +++ b/Stuff/Modules/version.py @@ -21,7 +21,7 @@ def version(): return ['0', '4', '0'] def date(): - return "5 August 2014" + return "9 August 2014" def copyleft(): return "2013, 2014" diff --git a/Stuff/Modules/window.py b/Stuff/Modules/window.py index 3e1e095..09c9e77 100644 --- a/Stuff/Modules/window.py +++ b/Stuff/Modules/window.py @@ -22,5 +22,5 @@ def placeWindow(window, windowWidth = 200, windowHeight = 300, xShift = 0, yShif screenWidth = window.winfo_screenwidth() screenHeight = window.winfo_screenheight() xPosition = int((screenWidth - windowWidth) / 2) + xShift - yPosition = int((screenHeight - windowHeight) / 2) + yShift + yPosition = max(int((screenHeight - windowHeight) / 2) + yShift, 10) window.geometry("+" + str(xPosition) + "+" + str(yPosition))