def on_view_focus_in_event(self, p_view, p_event, p_tab): """ p_view: un EditorView. p_event: un gtk.gdk.Event. p_tab: un EditorTab. Si el documento correspondiente a p_tab ha sido modificado externamente, entonces se le notifica al usuario por si desea recargarlo. """ assert (type(p_tab) == EditorTab and p_tab.get_parent() == self.__notebook) assert (p_tab.get_view() == p_view) assert (type(p_event) == gtk.gdk.Event and p_event.type == gtk.gdk.FOCUS_CHANGE) doc = p_tab.get_doc() bitwise_or = (EditorTabState.EXTERNALLY_MODIFIED_NOTIFICATION | EditorTabState.CLOSING) if not (p_tab.get_state() & bitwise_or) and \ doc.get_ask() and \ doc.was_externally_modified(): # FIXME: p_tab.__desync_with_breakpoints() ??? p_tab.set_state(EditorTabState.EXTERNALLY_MODIFIED_NOTIFICATION | p_tab.get_state()) if doc.get_modified(): msg = "has been externally modified.\nDo you want " \ "to drop your changes and reload the file?" else: msg = "has been externally modified.\nDo you want " \ "to reload the file?" window = self.get_window() dialog = Confirm(gtk.STOCK_DIALOG_WARNING, "%s\n\n%s" % (doc.get_path(), msg), "M-File:", window) if dialog.run(): doc.load(False, window) else: doc.set_ask(False) p_tab.set_state(EditorTabState.EXTERNALLY_MODIFIED_NOTIFICATION ^ p_tab.get_state())
def save(self, p_tab=None, p_path=None): """ p_tab: None o un EditorTab. p_path: None o una cadena que representa la direccion de un fichero. Retorna: True si se salvo, False en caso contrario. Trata de salvar a p_tab en el fichero indicado por p_path. Si p_tab es None la accion se realiza al EditorTab activo. Si p_path es None se utiliza la direccion del documento correspondiente a p_tab. """ assert ((p_tab == None) or (type(p_tab) == EditorTab and p_tab.get_parent() == self.__notebook)) assert ((p_path == None) or (type(p_path) == str and p_path)) if not p_tab: p_tab = self.__curtab if not p_tab: return doc = p_tab.get_doc() doc_path = doc.get_path() p_path = doc_path if (not p_path) else p_path if not p_path: return self.save_as(p_tab) window = self.get_window() if not (p_tab.get_state() & EditorTabState.CLOSING) and \ p_path == doc_path and \ doc.was_externally_modified(): msg = "has been externally modified.\nIf you save it, all " \ "the external changes could be lost. Save it anyway?" dialog = Confirm(gtk.STOCK_DIALOG_WARNING, "%s\n\n%s" % (p_path, msg), "Save to M-File:", window) if not dialog.run(): return False return doc.save(p_path, window)
def clear(self): """ Elimina todos los datos del historial de comandos y del fichero correspondiente al mismo, dejando en estos solo la fecha mas reciente. """ if not self.__project: msg = "Are you sure you want to delete your entire history?" resp = Confirm(gtk.STOCK_DIALOG_QUESTION, msg, "Command History", self.__parent).run() if not resp: return model = self.__tree date = model[model[len(model) - 1].path][0] model.clear() model.append(None, [date]) if self.__pointer["row"] != None: if model[len(model) - 1].path < self.__copy_of_history[self.__pointer["row"]]: self.__pointer["row"] = 1 else: self.__pointer["row"] = 0 self._update_copy()
def delete_project(self): """ Metodo mediante el cual se elimina fisicamente el proyecto en que se trabaja. """ if not self.__project: return msg = "Are you sure you want to delete this project?" resp = Confirm(gtk.STOCK_DIALOG_QUESTION, msg, "Close Proyect", self.__parent).run() if resp: path = self.__project.get_localization() m = os.path.join(path, "SRC") self.__mwindow.get_connection().append_command(ManageCommandPro( "rmpath (genpath ('%s'), '-begin');\n" %(m))) self.__mwindow.get_connection().append_command( ManageCommandPro('OLD_VAL_recursive = confirm_recursive_rmdir(0);\n')) self.__mwindow.get_connection().append_command( ManageCommandPro('rmdir ("%s", "s");\n' %(path))) self.__mwindow.get_connection().append_command( ManageCommandPro('confirm_recursive_rmdir(OLD_VAL_recursive);\n')) self.__mwindow.get_connection().append_command( DeleteVar('OLD_VAL_recursive')) self.close_project()
def on_button10_activate(self, p_widget): """ p_widget: representa una instancia de GtkButton. Metodo que permite la eliminacion de un shortcut seleccionado. """ selection = self.__treeview_shorcuts.get_selection() model, iter_, = selection.get_selected() if iter_: if not self.__confirmed_del: msg = "Are you sure you want to delete the selected variable?" resp = Confirm(gtk.STOCK_DIALOG_QUESTION, msg, "Confirm delete", self.__organize_shortcut, "Do not show this prompt again.").run() if resp: self.__confirmed_del = resp[0] if not resp: return text = model.get_value(iter_, 1) path = model.get_path(iter_) row = path[0] self.__container_shorcuts.set__edit_shortcut( self.__container_shorcuts.get_children()[row + 1]) self.__container_shorcuts.delete_shortcut() self.__liststore_shorcuts.remove(iter_)
def import_m_file(self, p_path): """ p_m_file: cadena de texto que representa el camino hasta el archivo m que se desea importar. Metodo mediante el cual se importa un archivo m al proyecto dado su localizacion a traves de la variable <p_path>. """ name = os.path.split(p_path)[1] path = os.path.join(self.__localization, "SRC") if not os.access(os.path.join(path, name), os.F_OK): file_util.copy_file(p_path, path) self.add_m_file(name) self.__xml_proje.save_project(self.__project_name, self.__localization, self.__m_file_list, self.__date) else: msg = os.path.join(path, name) + \ " already exists.\n Do you want to replace it?" resp = Confirm(gtk.STOCK_DIALOG_QUESTION, msg, "Import File ", None, None).run() if resp: file_util.copy_file(p_path, path) self.add_m_file(name) self.__xml_proje.save_project(self.__project_name, self.__localization, self.__m_file_list, self.__date)
def clear(self): """ Limpia el 'CommandWindow', es decir, borra todo el texto del mismo. """ if not self.__confirmed_clear: resp = Confirm( gtk.STOCK_DIALOG_WARNING, "All text will be cleared from the command window.", "EIDMAT", self.__parent, "Do not show this prompt again.").run() if not resp: return self.__confirmed_clear = resp[0] self.__conn.append_command(ClearCMDWindow())
def delete_selection(self): """ Elimina todos los archivos m seleccionados, del arbol de proyecto. Adicionalmente elimina del proyecto los ficheros seleccionados. """ paths = self.get_selection().get_selected_rows()[1] if paths: msg = "All selected files will be deleted." resp = Confirm(gtk.STOCK_DIALOG_WARNING, msg, "Project", self.__parent, None).run() if not resp: return self._delete_paths(paths)
def confirm_close_project(self, p_is_open = None): """ Metodo que lanza un mensaje de confirmacion preguntando si desea realmente cerrar el proyecto. En caso de afirmacion se invoca el metodo de cerrar el proyecto. """ msg = "Are you sure you want to close your project. Maybe you don't save ?" resp = Confirm(gtk.STOCK_DIALOG_QUESTION, msg, "Close Proyect", self.__parent).run() if resp: path = self.__project.get_localization() m = os.path.join(path, "SRC") self.__mwindow.get_connection().append_command(ManageCommandPro( "rmpath (genpath ('%s'), '-begin');\n" %(m))) self.close_project(p_is_open) return resp
def on_apply_clicked(self, p_butt): """ p_butt: el 'gtk.Button' que recibio la sennal. Se ejecuta cuando el usuario da click en el boton 'Aplicar'. Chequea si alguna de las variables a importar ya existe en el 'Workspace', en dicho caso se le informa al usuario. Si el usuario confirma todo, entonces se importan hacia el 'Workspace' las variables marcadas en los checkboxes. """ new_names = [row[2] for row in self.__model if row[0]] if not new_names: self.cancel() return old_names = [row[1] for row in self.__lvars_model] equals = [] for new in new_names: if new in old_names: equals.append(new) if len(equals) == 3: break if equals: if len(equals) == 1: msg = "A variable named\n%s\n" \ "already exist in the EIDMAT Workspace." %equals[0] elif len(equals) == 2: msg = "Variables named\n%s and %s\n" \ "already exist in the EIDMAT Workspace." %tuple(equals) else: msg = "Variables with some of these names already exist\n" \ "in the EIDMAT Workspace." msg += "\n\nAre you sure that you want to overwrite them?" if not Confirm(gtk.STOCK_DIALOG_QUESTION, msg, "Import Wizard", self).run(): return if len(new_names) == len(self.__model): self.__conn.append_command(LoadVars([], self.__path)) else: self.__conn.append_command(LoadVars(new_names, self.__path)) self.cancel()
def delete_to_selection(self): """ Elimina del historial de comandos y del fichero correspondiente al mismo todos los datos hasta la seleccion. """ paths = self.get_selection().get_selected_rows()[1] if len(paths) != 1: return resp = Confirm( gtk.STOCK_DIALOG_QUESTION, "Are you sure you want to delete all commands above the selected command?", "Command History", self.__parent).run() if resp: copy = self.__copy_of_history self._delete_paths(copy[:copy.index(paths[0])]) self._update_copy()
def delete_selection(self): """ Elimina todos los datos seleccionados, del historial de comandos y del fichero correspondiente al mismo. """ paths = self.get_selection().get_selected_rows()[1] if paths: if not self.__confirmed_del: msg = "All selected commands will be deleted." resp = Confirm(gtk.STOCK_DIALOG_WARNING, msg, "Command History", self.__parent, "Do not show this prompt again.").run() if not resp: return if resp[0]: self.__confirmed_del = True self._delete_paths(paths) self._update_copy()
def clear(self): """ Limpia el 'Workspace', es decir que elimina todas las variables del usuario. """ model = self.__tree.get_model() if not self.__confirmed_clear: resp = Confirm(gtk.STOCK_DIALOG_QUESTION, "All variables will be deleted.", "Confirm delete", self.__parent, "Do not show this prompt again.").run() if not resp: return if resp[0]: self.__confirmed_clear = True for row in model: self.__conn.append_command(DeleteVar(row[1]))
def delete(self): """ Elimina las variables seleccionadas. """ model, paths = self.__tree.get_selection().get_selected_rows() if not paths: return if not self.__confirmed_del: s = "" if len(paths) > 1: s = "s" msg = "Are you sure you want to delete the selected variable%s?" % s resp = Confirm(gtk.STOCK_DIALOG_QUESTION, msg, "Confirm delete", self.__parent, "Do not show this prompt again.").run() if not resp: return if resp[0]: self.__confirmed_del = True for path in paths: self.__conn.append_command(DeleteVar(model[path][1]))
def save(self, p_all=True, p_path=None): """ p_all: 'True' si se quieren guardar todas las variables o 'False' si solo se quieren guardar las variables seleccionadas. p_path: Contiene la localizacion directa del path donde se guardaran todas las variables del workspace utilizada en el trabajo con proyecto. Muestra un dialogo para que el usuario indique donde guardar las variables, una vez indicado el fichero, se guardan las variables en el mismo. """ parent = self.__parent current_dir = self.__current_dir ########################## BEGIN ############################### while True: if p_path: path = p_path else: path = WorkspaceSaveDialog(parent, current_dir.get_path()).run() if not path: break save = True # if (Existe el archivo): if os.access(path, os.F_OK): # if (No se puede escribir): if not os.access(path, os.W_OK): save = False stock = gtk.STOCK_DIALOG_WARNING msg = ( "is read-only on disk.", "Do you want to save to a different name or location?") # elif (No puede crearse): elif not os.access(os.path.dirname(path), os.W_OK): save = False stock = gtk.STOCK_DIALOG_QUESTION msg = ("cannot be saved to this location.", "Do you want to save to a different location?") if save: names = [] model, paths = self.__tree.get_selection().get_selected_rows() if p_all: for row in model: names.append(model.get_value(row.iter, 1)) else: for p in paths: names.append(model.get_value(model.get_iter(p), 1)) self.__conn.append_command(SaveVars(names, path)) break elif not Confirm(stock, "%s\n\n%s" % (path, "\n".join(msg)), "Save to VAR-File:", parent).run(): break
def execute(self, p_conn): """ p_conn: la 'Connection'. Guarda las variables deseadas en el fichero indicado. """ tail = p_conn.get_tail_with_priority() names = self.__names path = self.__path for pos in xrange(len(tail) - 1, -1, -1): elem = tail[pos] if elem == self and len(elem.get_names()) == len(names) and\ elem.get_path() == path: flag = True for name in elem.get_names(): if name not in names: flag = False break if flag: tail.extract(pos) ########################## BEGIN ############################### main_win = p_conn.get_mwindow() parent = main_win.get_window() curdir = main_win.get_cdirectory().get_path() while True: save = True # if (Existe el archivo): if os.access(path, os.F_OK): # if (No se puede escribir): if not os.access(path, os.W_OK): save = False stock = gtk.STOCK_DIALOG_WARNING msg = ( "is read-only on disk.", "Do you want to save to a different name or location?") # elif (No puede crearse): elif not os.access(os.path.dirname(path), os.W_OK): save = False stock = gtk.STOCK_DIALOG_QUESTION msg = ("cannot be saved to this location.", "Do you want to save to a different location?") if save: break if not Confirm(stock, "%s\n\n%s" % (path, "\n".join(msg)), "Save to VAR-File:", parent).run(True): return path = WorkspaceSaveDialog(parent, curdir).run(True) if not path: return ########################## END ################################# p_conn.get_terminal().feed_child("save -binary '%s' %s;\n" % (path, " ".join(names))) p_conn.wait_until_ready() lines = p_conn.get_terminal().buff.get_all().split("\n") pos = -2 line = lines[pos] vars_ = [] while line[0] == "w": vars_.insert(0, line[line.rfind("`") + 1:-1]) pos -= 1 line = lines[pos] if vars_: if len(vars_) == 1: msg = 'A variable named "%s"' % vars_[0] elif len(vars_) == 2: msg = 'Variables named "%s" and "%s"' % (vars_[0], vars_[1]) else: msg = "Some variables" Message(gtk.STOCK_DIALOG_WARNING, "%s could not be saved." % msg, "Saving Failed", parent).run(True)
def __init__(self, cfg): super(MultiviewProjectMainWindow, self).__init__() self.cfg = cfg # we will only use images that exist for all views imageNames = [iglob(os.path.join(cfg.imageFolder, view, '*'+cfg.imageExtension)) for view in cfg.views] imageNames = [set(map(lambda s: os.path.basename(s), l)) for l in imageNames] imageNames = set.intersection(*imageNames) # read the data; if there is none, then create a new frame for the data try: data_pixel = pd.read_csv(os.path.join(cfg.projectFolder, 'pixel-annotation-data.csv'), index_col=[0,1], header=[0,1]) data_3d = pd.read_csv(os.path.join(cfg.projectFolder, '3d-annotation-data.csv'), index_col=0, header=[0,1]) except FileNotFoundError: data_pixel = pd.DataFrame( columns=pd.MultiIndex.from_product([cfg.joints, ['u', 'v']], names=['joint', 'coordinate']), index=pd.MultiIndex(levels=[[],[]], codes=[[],[]], names=['view', 'image']) ) data_3d = pd.DataFrame( columns=pd.MultiIndex.from_product([cfg.joints, ['x','y','z']], names=['joint', 'coordinate']), index=pd.Index([], name='image') ) # in case the user has deleted images removed = set.difference(set(data_3d.index.values), imageNames) if len(removed) > 0: msg = 'The following %d images are not present in all views, and this project\'s annotation data for them will be deleted:\n%s' msg = msg%(len(removed), '\n'.join(sorted(removed))) if not Confirm(msg).exec_(): self.close() return remove_idx = pd.MultiIndex.from_product([cfg.views, removed]) # in case the user has added images added = set.difference(imageNames, set(data_3d.index.values)) if len(added) > 0: msg = 'The following %d images have been added to this project:\n%s' msg = msg%(len(added), '\n'.join(sorted(added))) if not Confirm(msg).exec_(): self.close() return add_idx = pd.MultiIndex.from_product([cfg.views, added]) # create the dataframes, including anything that has been added/removed self.data_pixel = pd.concat([ data_pixel.drop(labels=remove_idx), pd.DataFrame( columns=pd.MultiIndex.from_product([cfg.joints, ['u', 'v']], names=['joint', 'coordinate']), index=add_idx ) ]) self.data_pixel.sort_index(inplace=True) self.data_3d = pd.concat([ data_3d.drop(labels=removed), pd.DataFrame( columns=pd.MultiIndex.from_product([cfg.joints, ['x', 'y', 'z']], names=['joint', 'coordinate']), index=pd.Index(added, name='image') ) ]) self.data_3d.sort_index(inplace=True) # the project needs to have at least one image self.images = self.data_3d.index.values if len(self.images) == 0: Alert('Project must have at least one image that exists in all view folders.').exec_() self.close() return # set up UI self.ui = Ui_MultiviewProjectMainWindow() self.ui.setupUi(self) # initialize counters self.viewIdx = 0 self.imageIdx = 0 self.jointIdx = 0 # initialize which joints are displaying (all of them, to start) self.displaying = set(range(len(self.cfg.joints))) # initialize radius for annotations self.radius = 5 # initialize joint colors (I guess these aren't necessarily visually distinct, maybe there's a better way) inc = 256**3 // len(self.cfg.joints) color = 256**3-1 self.colors = [QColor(*tuple((color-inc*i).to_bytes(3, 'big'))) for i in range(len(self.cfg.joints))] # set headers above main view self.ui.label.setText('View: %s'%str(self.cfg.views[self.viewIdx])) self.ui.label_4.setText('Image: %s'%self.images[self.imageIdx]) # set up the combobox/spinbox for changing the view/frame below the main view for view in cfg.views: self.ui.comboBox.addItem(str(view)) self.ui.spinBox.setMinimum(-1) self.ui.spinBox.setMaximum(len(self.images)) self.ui.spinBox.valueChanged.connect(self.setFrame) self.ui.comboBox.currentIndexChanged.connect(self.setView) # set up the double spinbox for changing the annotation radius self.ui.doubleSpinBox.valueChanged.connect(self.setRadius) self.ui.doubleSpinBox.setValue(self.radius) # set up skip to next frame missing any/all displayed annotations self.ui.pushButton.clicked.connect(self.skipMissingAny) self.ui.pushButton_2.clicked.connect(self.skipMissingAll) # add buttons for labeling and displaying annotations self.labelingButtons = [] self.displayingButtons = [] for row, jointName in enumerate(cfg.joints): r = QRadioButton(jointName+'*', self.ui.scrollAreaWidgetContents_3) r.clicked.connect(self.setJoint(row)) # r.setStyleSheet('color: red' self.ui.gridLayout.addWidget(r, row, 0, 1, 1) self.labelingButtons.append(r) c = QCheckBox(jointName, self.ui.scrollAreaWidgetContents_2) c.clicked.connect(self.setDisplaying(row)) c.setChecked(True) self.ui.gridLayout_2.addWidget(c, row, 0, 1, 1) self.displayingButtons.append(c) self.labelingButtons[self.jointIdx].setChecked(True) self.ui.gridLayout.setRowStretch(len(cfg.joints), 1) self.ui.gridLayout_2.setRowStretch(len(cfg.joints), 1) # initialize the main view self.mainView = MainImageView(self.ui.centralwidget) self.ui.verticalLayout_2.addWidget(self.mainView) self.mainView.photoClicked.connect(self.mainImageClicked) self.mainView.photoRightClicked.connect(self.removeAnnotation) # add a miniature display for every view self.miniViews = [] for row, view in enumerate(cfg.views): w = QWidget(self.ui.scrollAreaWidgetContents) self.ui.gridLayout_3.addWidget(w, row, 0, 1, 1) vLayout = QVBoxLayout(w) l = QLabel(w) l.setText('View: %s'%str(view)) vLayout.addWidget(l) v = ImageView(w) vLayout.addWidget(v) self.miniViews.append({ 'container': w, 'layout': vLayout, 'label': l, 'view': v }) self.loadPhotos() self.loadAnnotations() # helps register keypress events self.setFocusPolicy(Qt.ClickFocus)