def __init__(self, modelset=None, modelset_path=None): '''Vytvori hlavne okno, nacita konfiguracny subor a nastavy velkost''' path = join(os.path.dirname(os.path.abspath(__file__)), 'glade') gtklib.ObjGetter.__init__(self, join(path, 'main.glade'), self.get_signals()) self.config = configparser.ConfigParser() self.config.read(expanduser('~/.config/hmmlab.conf')) self.window.set_default_size(int(self.config['mainwindow']['width']), int(self.config['mainwindow']['height'])) self.file_context_id = self.statusbar.get_context_id("Načítavanie súboru") self.MODEL_WIDTH = int(self.config['model']['width']) self.MODEL_HEIGHT = int(self.config['model']['height']) self.MODEL_CHECK = cairo.ImageSurface.create_from_png(join(path, 'check.png')) self.MODEL_UNCHECK = cairo.ImageSurface.create_from_png(join(path, 'uncheck.png')) self.mice = {'mouse_down':False, 'x': 0, 'y': 0, 'drag' : False} self.selection_rectangle = {'x1' : 0, 'y1' : 0, 'x2' : 0, 'y2' : 0} self.modelset = modelset self.modelset_path = modelset_path self.data_table = FilesTab(modelset, self) self.modelset_modified = False self.visual_win = VisualWindow(self, self.modelset) if self.modelset is not None: self.fill_models() self.models_sidebar.set_sensitive(True) self.opened() self.edited = False self.models_canvas = [] self.models_selected = [] self.models_windows = [] self.treeview1.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.COPY) self.drawarea.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY) self.treeview1.drag_source_add_text_targets() self.drawarea.drag_dest_add_text_targets() self.window.show()
class MainWindow(gtklib.ObjGetter): '''Trieda hlavneho okna''' def __init__(self, modelset=None, modelset_path=None): '''Vytvori hlavne okno, nacita konfiguracny subor a nastavy velkost''' path = join(os.path.dirname(os.path.abspath(__file__)), 'glade') gtklib.ObjGetter.__init__(self, join(path, 'main.glade'), self.get_signals()) self.config = configparser.ConfigParser() self.config.read(expanduser('~/.config/hmmlab.conf')) self.window.set_default_size(int(self.config['mainwindow']['width']), int(self.config['mainwindow']['height'])) self.file_context_id = self.statusbar.get_context_id("Načítavanie súboru") self.MODEL_WIDTH = int(self.config['model']['width']) self.MODEL_HEIGHT = int(self.config['model']['height']) self.MODEL_CHECK = cairo.ImageSurface.create_from_png(join(path, 'check.png')) self.MODEL_UNCHECK = cairo.ImageSurface.create_from_png(join(path, 'uncheck.png')) self.mice = {'mouse_down':False, 'x': 0, 'y': 0, 'drag' : False} self.selection_rectangle = {'x1' : 0, 'y1' : 0, 'x2' : 0, 'y2' : 0} self.modelset = modelset self.modelset_path = modelset_path self.data_table = FilesTab(modelset, self) self.modelset_modified = False self.visual_win = VisualWindow(self, self.modelset) if self.modelset is not None: self.fill_models() self.models_sidebar.set_sensitive(True) self.opened() self.edited = False self.models_canvas = [] self.models_selected = [] self.models_windows = [] self.treeview1.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.COPY) self.drawarea.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY) self.treeview1.drag_source_add_text_targets() self.drawarea.drag_dest_add_text_targets() self.window.show() def get_signals(self): signals = {"about" : self.about, "destroy" : self.destroy, "drawarea_button_press_event_cb" : self.drawarea_button_press_event, "drawarea_button_release_event_cb" : self.drawarea_button_release_event, "drawarea_draw_cb" : self.draw, "drawarea_drag_data_received_cb" : self.drawarea_drag_data_received, "drawarea_motion_notify_event_cb" : self.drawarea_motion_notify_event, "export_activate" : self.export_activate, "gnuplot" : self.gnuplot, "gnuplot3d" : self.gnuplot3D, "load_data" : self.load_data, "models_drag_get" : self.models_drag_get, "open_activate" : self.open_activate, "save_activate" : self.save_activate, "save_as_activate" : self.save_as_activate, "open_data_table" : self.open_data_table, "add_model" : self.add_model, "remove_model" : self.remove_model, "graphviz" : self.graphviz, "new_modelset" : self.new_modelset} return signals def destroy(self, widget = None, event=None): if widget is not None and self.modelset is not None and self.edited: dialog = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Uložiť zmeny do súboru '%s' pred zatvorením?" % self.modelset.name) dialog.format_secondary_text("Ak neuložíte, zmeny budú stratené.") response = dialog.run() if response == Gtk.ResponseType.YES: #bude treba otvorit save okno pass dialog.destroy() self.config['mainwindow']['width'] = str(self.window.get_allocated_width()) self.config['mainwindow']['height'] = str(self.window.get_allocated_height()) with open(expanduser('~/.config/hmmlab.conf'), 'w') as configfile: self.config.write(configfile) Gtk.main_quit() def draw(self, drawarea, cr): if self.modelset is not None: for model in self.models_canvas: if model in self.models_selected: cr.set_source_rgba(0,80,0,0.5) else: cr.set_source_rgba(0,0,0,0.6) gtklib.cairo_rounded_rectangle(cr, model.x, model.y, self.MODEL_WIDTH, self.MODEL_HEIGHT, 1, self.MODEL_HEIGHT/10) cr.fill_preserve() cr.fill() cr.select_font_face("Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) cr.set_font_size(12.0) extents = cr.text_extents(model.model.name) x = model.x + self.MODEL_WIDTH / 2 - extents[2] / 2 - extents[0] y = model.y + self.MODEL_HEIGHT / 2 - extents[3] / 2 - extents[1] cr.move_to(x, y) cr.set_source_rgb(255,255,255) cr.show_text(model.model.name) if model.checked: cr.set_source_surface(self.MODEL_CHECK, model.x+1, model.y+1) else: cr.set_source_surface(self.MODEL_UNCHECK, model.x+1, model.y+1) cr.paint() if self.mice['mouse_down'] and not self.mice['drag']: cr.set_source_rgba(0,0,180,0.1) cr.rectangle(self.selection_rectangle['x1'], self.selection_rectangle['y1'], self.selection_rectangle['x2'] - self.selection_rectangle['x1'], self.selection_rectangle['y2'] - self.selection_rectangle['y1']) cr.fill() cr.set_source_rgba(0,0,180,0.5) cr.rectangle(self.selection_rectangle['x1'], self.selection_rectangle['y1'], self.selection_rectangle['x2'] - self.selection_rectangle['x1'], self.selection_rectangle['y2'] - self.selection_rectangle['y1']) cr.stroke() def opened(self): self.imagemenuitem3.set_sensitive(True) self.imagemenuitem4.set_sensitive(True) self.imagemenuitem11.set_sensitive(True) self.action1.set_sensitive(True) self.action2.set_sensitive(True) self.action3.set_sensitive(True) self.modelset_modified = False def save_activate(self, item): if self.modelset_modified: if self.modelset is None: self.save('xml') else: self.modelset.save(self.modelset_path, 'xml') def save_as_activate(self, item=None): self.save('xml') self.modelset_modified = False def export_activate(self, item=None): self.save('htk') def save(self, file_format): dialog = Gtk.FileChooserDialog("Vyberte súbor", self.window, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dialog.set_do_overwrite_confirmation(True) self.add_filters(dialog, file_format) response = dialog.run() if response == Gtk.ResponseType.OK: filename = dialog.get_filename() dialog.destroy() self.modelset.save(filename, file_format) else: dialog.destroy() def load_data(self, item): dialog = Gtk.FileChooserDialog("Vyberte súbor", self.window, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filter_wav = Gtk.FileFilter() filter_wav.set_name("WAV súbor") filter_wav.add_pattern('*.wav') dialog.add_filter(filter_wav) dialog.set_select_multiple(True) response = dialog.run() if response == Gtk.ResponseType.OK: filenames = dialog.get_filenames() self.modelset.load_data(filenames) self.visual_win.refresh() dialog.destroy() def open_data_table(self, item): self.data_table.modelset = self.modelset self.data_table.load_data() self.data_table.window.show() def open_activate(self, item): dialog = Gtk.FileChooserDialog("Vyberte súbor", self.window, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) self.add_filters(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: filename = dialog.get_filename() file_type = filename[filename.index('.')+1:] dialog.destroy() self.statusbar.push(self.file_context_id,'Načítavam súbor '+filename) if self.modelset is not None: self.modelset.destroy() self.modelset = libhmm.ModelSet(filename, file_type) self.visual_win.set_modelset(self.modelset) self.statusbar.pop(self.file_context_id) self.window.set_title('HMMLab - '+self.modelset.name) self.drawarea.queue_draw() self.fill_models() self.models_sidebar.set_sensitive(True) self.opened() else: dialog.destroy() def add_filters(self, dialog, file_format=None): if file_format == 'htk' or file_format is None: filter_hmm = Gtk.FileFilter() filter_hmm.set_name("HTK HMM súbor") filter_hmm.add_pattern('*.hmm') dialog.add_filter(filter_hmm) if file_format == 'xml' or file_format is None: filter_xml = Gtk.FileFilter() filter_xml.set_name("XML súbory") filter_xml.add_mime_type("text/xml") dialog.add_filter(filter_xml) filter_any = Gtk.FileFilter() filter_any.set_name("Všetky súbory") filter_any.add_pattern("*") dialog.add_filter(filter_any) def fill_models(self): if self.modelset is not None: self.models_store.clear() for model in self.modelset.models: self.models_store.append([model.name]) def models_drag_get(self, widget, drag_context, data, info, time): if self.modelset is not None: model, it = self.treeview1.get_selection().get_selected() item = self.models_store.get_value(it, 0) data.set_text(item, -1) def drawarea_drag_data_received(self, widget, drag_context, x, y, data, info, time): if self.modelset is not None: model_name = data.get_text() model = self.modelset.get_model(model_name) m = None for modelm in self.models_canvas: if modelm.x <= x <= modelm.x + self.MODEL_WIDTH and modelm.y <= y <= modelm.y + self.MODEL_HEIGHT: m = modelm if m is not None: joined_model = m.model.join_model(model) self.models_canvas.remove(m) self.models_selected = [] self.models_canvas.append(CanvasModel(joined_model, m.x, m.y, self.modelset.reset_pos_gauss)) else: self.models_canvas.append(CanvasModel(model, x, y, self.modelset.reset_pos_gauss)) self.modelset.drawarea_models_append(model) self.modelset_modified = True self.drawarea.queue_draw() def drawarea_button_press_event(self, eb, event): if self.modelset is not None: model = self.get_model_at(event.x, event.y) if model is None: self.models_selected = [] self.mice['drag'] = False self.selection_rectangle['x1'] = event.x self.selection_rectangle['y1'] = event.y self.selection_rectangle['x2'] = event.x self.selection_rectangle['y2'] = event.y else: if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3: self.open_menu(event, model) elif event.type == Gdk.EventType._2BUTTON_PRESS: if model.model.name not in [mw.model.name for mw in self.models_windows]: mw = ModelWindow(model, self) self.models_windows.append(mw) else: for mw in self.models_windows: if model.model.name == mw.model.name: mw.window.present() break if model not in self.models_selected: self.models_selected = [model] if model.x <= event.x <= model.x + self.MODEL_CHECK.get_width(): if model.y <= event.y <= model.y + self.MODEL_CHECK.get_height(): model.checked = not model.checked model.gaussians() for mw in self.models_windows: if model.model.name == mw.model.name: mw.fill_states_table() self.visual_win.refresh() self.mice['drag'] = True self.mice['mouse_down'] = True self.mice['x'] = event.x self.mice['y'] = event.y self.drawarea.queue_draw() def drawarea_button_release_event(self, eb, event): if self.modelset is not None: self.mice['mouse_down'] = False self.mice['x'] = event.x self.mice['y'] = event.y if not self.mice['drag']: self.update_selected_models() self.mice['drag'] = False for k in self.selection_rectangle: self.selection_rectangle[k] = -1 if len(self.models_selected) == 1: m = None for model in self.models_canvas: if model.x <= event.x <= model.x + self.MODEL_WIDTH and model.y <= event.y <= model.y + self.MODEL_HEIGHT: if model != self.models_selected[0]: m = model break if m is not None: joined_model = m.model.join_model(self.models_selected[0].model) self.models_canvas.remove(m) self.models_canvas.remove(self.models_selected[0]) self.models_selected = [] self.models_canvas.append(CanvasModel(joined_model, m.x, m.y, self.modelset.reset_pos_gauss)) self.drawarea.queue_draw() def drawarea_motion_notify_event(self, eb, event): if self.modelset is not None: if self.mice['mouse_down']: alloc = self.drawarea.get_allocation() if self.mice['drag']: for model in self.models_selected: model.x = max(0, min(alloc.width - self.MODEL_WIDTH, model.x - self.mice['x'] + event.x)) model.y = max(0, min(alloc.height - self.MODEL_HEIGHT, model.y - self.mice['y'] + event.y)) if len(self.models_selected) > 0: self.drawarea.queue_draw() elif len(self.models_selected) == 0: self.selection_rectangle['x2'] = max(0, min(alloc.width - self.MODEL_WIDTH,event.x)) self.selection_rectangle['y2'] = max(0, min(alloc.height - self.MODEL_HEIGHT, event.y)) self.drawarea.queue_draw() self.mice['x'] = event.x self.mice['y'] = event.y def update_selected_models(self): self.models_selected = [] for model in self.models_canvas: if self.selection_rectangle['x1'] > self.selection_rectangle['x2']: if self.selection_rectangle['x1'] >= (model.x+self.MODEL_WIDTH) and self.selection_rectangle['x2'] <= model.x: self.models_selected.append(model) else: if self.selection_rectangle['x2'] >= (model.x+self.MODEL_WIDTH) and self.selection_rectangle['x1'] <= model.x: self.models_selected.append(model) def get_model_at(self, x, y): for model in self.models_canvas: if model.x <= x <= model.x + self.MODEL_WIDTH and model.y <= y <= model.y + self.MODEL_HEIGHT: return model return None def about(self, item): resp = self.aboutdialog.run() if resp == Gtk.ResponseType.DELETE_EVENT or resp == Gtk.ResponseType.CANCEL: self.aboutdialog.hide() def gnuplot(self, item): Select2DWindow(self.modelset, self.window) def gnuplot3D(self, item): SelectDraw2DWindow(self.modelset, self) def open_window_from_gauss(self, gauss): for model in self.modelset.get_models_with_gaussian(gauss): mw = None if model.name not in [mw.model.name for mw in self.models_windows]: mw = ModelWindow(model, self) self.models_windows.append(mw) else: for mwin in self.models_windows: if model.name == mwin.model.name: mwin.window.present() mw = mwin break if mw is not None: for i, state in enumerate(model.states): if state.has_gaussian(gauss): selection = mw.states_view.get_selection() if selection is not None: selection.select_path(i) mw.load_state(state) for j, data in enumerate(mw.gaussians_store): if data[2] == gauss.name: selection = mw.gaussians_view.get_selection() if selection is not None: selection.select_path(j) def add_model(self, button): trans_mat = libhmm.TransMatrix(self.modelset.get_unique_name("trans_mat"), self.modelset, 3, 1.0) m = libhmm.Model(self.modelset.get_unique_name("model"), self.modelset) m.trans_mat = trans_mat s = libhmm.State("%s_state_1" % m.name, self.modelset) for i, stream in enumerate(s.streams): g = libhmm.Gaussian(stream.name + "_gaussian0", self.modelset, i, 1) dimension = self.modelset.streams_distribution[i] g.mean = libhmm.SVector(g.name+"_mean", self.modelset, dimension, 0.0) g.mean.randomize() g.covariance = libhmm.SMatrix(g.name+"_covariance", self.modelset, dimension, dimension, 0.0) g.inv_covariance = libhmm.SMatrix(g.covariance.name+"_inv", self.modelset, dimension, dimension, 0.0); g.covariance.randomize() for i in range(dimension): for j in range(dimension): if i != j: g.covariance(i, j, 0.0) else: g.inv_covariance(i, j, 1.0 / g.covariance(i,j)) g.calc_gconst() stream.add_gaussian(g, 1.0) s.inc_ref_num() m.states.append(s) self.modelset.add_model(m) self.modelset.drawarea_models_append(m) alloc = self.drawarea.get_allocation() model = CanvasModel(m, randint(20, alloc.width - 20), randint(20, alloc.height - 20), self.modelset.reset_pos_gauss) self.models_canvas.append(model) mw = ModelWindow(model, self) self.models_windows.append(mw) self.fill_models() def remove_model(self, button): _, it = self.treeview1.get_selection().get_selected() m = self.modelset.get_model(self.models_store[it][0]) self.modelset.remove_model(m) self.fill_models() def open_menu(self, event, model): menu = Gtk.Menu() if model.model.is_joined(): menu_item = Gtk.MenuItem('Rozdeliť model') menu.append(menu_item) menu_item.show() menu_item.connect("activate", self.disjoint_model, model) else: menu_item = Gtk.MenuItem('Zmazať z plochy') menu.append(menu_item) menu_item.show() menu_item.connect("activate", self.remove_model_from_drawarea, model) menu.popup(None, None, lambda menu, data: (event.get_root_coords()[0], event.get_root_coords()[1], True), None, event.button, event.time) def disjoint_model(self, widget, model): model_list = model.model.disjoint_model() alloc = self.drawarea.get_allocation() self.models_canvas.remove(model) for m in model_list: self.models_canvas.append(CanvasModel(m, randint(self.MODEL_WIDTH, alloc.width - self.MODEL_WIDTH), randint(model.y - 10, model.y + 10), self.modelset.reset_pos_gauss)) self.modelset.drawarea_models_append(m) self.drawarea.queue_draw() def remove_model_from_drawarea(self, widget, model): self.models_canvas.remove(model) self.modelset.drawarea_models.erase(model.model) model.model.unselect_gaussians() self.modelset.reset_pos_gauss() self.drawarea.queue_draw() def graphviz(self, item): for s in self.modelset.stream_areas: s.graphviz = item.get_active() def new_modelset(self, item): if self.modelset is None: NewModelsetWin(self)