Hello: In my process of learning python + gtk, I've created a zim mock up to try out a concept. The idea is to make creation of notes a bit faster, to achieve mind-map speed, but keeping the current treeview used in zim. This is how it works:
* Use arrows to move in the treeview, enter to select a note and control+space to switch to the editor and back, as usual * Use alt+arrows to create notes within the TreeView, using the editable property of this widget. (alt+left for children, alt+down for sibling) * When there are children of the Template folder, if a new note is created, you might type the template name and hit enter. Then the text from the template is copied to the new note, and the cell will become editable one more time so that you can introduce the real name of this note. There are two files attached (unless trimmed by the mail manager, in which case you can copy and paste the files at the end of the email). It is run by writing: python zimmindmap.py The other file was generated by glade: it is a gtkbuilder file and it doesn't need any libraries. It has a mock up menu which is totally useless, and probably in spanish. The template part should really be better with autocompletion, and maybe it should use grandchildren of the Templates folder into, but anyway this is just a mockup. Do you like this way of creating notes, and/or using Templates? Regards ------------------------------- zimmindmap.py ------------------------------- import sys import gtk class ZimMindMap(object): """ mock up of zim to test an idea """ temptitle = 'Title' templatechar = '.' def __init__ (self): """ Class initialiser """ self.notes={} self.current_note = None self.builder = gtk.Builder() self.builder.add_from_file("zimmindmap.glade") self.window = self.builder.get_object("mainwindow") self.noteeditor = self.builder.get_object("noteeditor") self.noteindex = self.builder.get_object("index") self.datamodel = gtk.TreeStore(str) self.cellrender=gtk.CellRendererText() # renderer para la primera columna self.title_column = gtk.TreeViewColumn('Notes') self.title_column.pack_start(self.cellrender,True) self.title_column.add_attribute(self.cellrender, "text", 0) self.noteindex.append_column(self.title_column) uno = self.newnote('Hello1') dos = self.newnote('Hello2') self.newnote('Hello11',uno) self.newnote('Hello12',uno) self.newnote('Hello21',dos) self.newnote('Hello22',dos) templates_iter=self.newnote('Templates') self.templates_root = self.datamodel.get_path(templates_iter) self.noteindex.set_model(self.datamodel) self.builder.connect_signals(self) def newnote(self, title, parent=None, texto=None): it = self.datamodel.append(parent, (title,)) path = self.datamodel.get_path(it) if not texto: texto=title self.notes[path] = texto return it def delnote(self, path): iter=self.datamodel.get_iter(path) self.datamodel.remove(iter) del self.notes[path] def on_mainwindow_destroy(self,widget,data=[]): gtk.main_quit() def on_mainwindow_key_release_event(self,widget,data=[]): if data.keyval==32 and (data.state& gtk.gdk.CONTROL_MASK): #Control+space if self.noteeditor.is_focus(): self.noteindex.grab_focus() else: self.noteeditor.grab_focus() return True def on_index_key_press_event(self,widget,data=[]): #65361: left, 65362:up, 65363: right, 65364:down, 65293:Enter, 32:space if data.keyval==65363: #right current_row,current_column=widget.get_cursor() current_iter=self.datamodel.get_iter(current_row) widget.expand_row(current_row,False) if data.state & gtk.gdk.MOD1_MASK:#Alt+Left new_note_iter=self.newnote(ZimMindMap.temptitle, parent=current_iter) new_note_path=self.datamodel.get_path(new_note_iter) # widget.expand_row(new_note_path,True) #doesn't work if current_row only has just this child widget.expand_row(current_row,True) #not the right thing, but works self.cellrender.set_property('editable',True) self.cellrender.connect('edited',self.edited_cell,self.datamodel) self.noteindex.set_cursor(new_note_path, focus_column=self.title_column ,start_editing=True) elif data.keyval==65364 and (data.state& gtk.gdk.MOD1_MASK):#Alt+down current_row,current_column=widget.get_cursor() current_iter=self.datamodel.get_iter(current_row) parent_iter=self.datamodel.iter_parent(current_iter) parent_path=self.datamodel.get_path(parent_iter) if parent_iter else () new_note_iter=self.newnote(ZimMindMap.temptitle, parent=parent_iter) new_note_path=self.datamodel.get_path(new_note_iter) if parent_path: widget.expand_row(parent_path,True) #not the right thing, but works self.cellrender.set_property('editable',True) self.cellrender.connect('edited',self.edited_cell,self.datamodel) self.noteindex.set_cursor(new_note_path, focus_column=self.title_column ,start_editing=True) elif data.keyval==65361: #left current_row,current_column=widget.get_cursor() current_iter=self.datamodel.get_iter(current_row) widget.collapse_row(current_row) elif data.keyval==65293 or data.keyval==32: #Enter or space selection = widget.get_selection() model,iter = selection.get_selected() path = self.datamodel.get_path(iter) self.show_note(path) return True def on_index_cursor_changed(self,widget,data=None): pass def on_index_row_activated(self, widget, path, view_column): self.show_note(path) def edited_cell(self, cell, path, new_text, user_data): iter=self.datamodel.get_iter(path) path=self.datamodel.get_path(iter) #path is given to edited_cell in non-standard format parent=self.datamodel.iter_parent(iter) parent_path=self.datamodel.get_path(parent) #template section if parent_path!=self.templates_root: templates_iter=self.datamodel.get_iter(self.templates_root) templates=[self.datamodel.iter_nth_child(templates_iter, i) for i in range(self.datamodel.iter_n_children(templates_iter))] for iter in templates: #TODO: search subchildren template_name = self.datamodel.get_value(iter,0) if new_text==template_name: print 'Template name match: '+template_name template_path=self.datamodel.get_path(iter) self.notes[path] = ZimMindMap.templatechar+self.notes[template_path] self.noteindex.set_cursor(path, focus_column=self.title_column ,start_editing=True) return True if self.notes[path][0]==ZimMindMap.templatechar: nota=self.notes[path][1:] else: nota = new_text self.delnote(path) self.newnote(new_text, parent, nota) self.cellrender.set_property('editable',False) self.noteindex.expand_row(parent_path,True) #not the right thing, but works self.noteindex.set_cursor(path, focus_column=self.title_column ,start_editing=False) self.show_note(path) def show_note(self, path): self.save_note() try: note_text = self.notes[path] buffer = self.noteeditor.get_buffer() buffer.set_text(note_text) self.current_note=path except KeyError: buffer = self.noteeditor.get_buffer() buffer.set_text(repr(path)+' not found') def save_note(self): if self.current_note: buffer = self.noteeditor.get_buffer() start, end = buffer.get_bounds() self.notes[self.current_note] = buffer.get_text(start, end) if __name__ == "__main__": tareas = ZimMindMap() tareas.window.show() gtk.main() ------------------------------- zimmindmap.glade ------------------------------- <?xml version="1.0"?> <interface> <requires lib="gtk+" version="2.12"/> <!-- interface-naming-policy project-wide --> <object class="GtkWindow" id="mainwindow"> <signal name="destroy" handler="on_mainwindow_destroy"/> <signal name="key_release_event" handler="on_mainwindow_key_release_event"/> <child> <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> <property name="orientation">vertical</property> <child> <object class="GtkMenuBar" id="menubar1"> <property name="visible">True</property> <child> <object class="GtkMenuItem" id="menuitem1"> <property name="visible">True</property> <property name="label" translatable="yes">_Archivo</property> <property name="use_underline">True</property> <child type="submenu"> <object class="GtkMenu" id="menu1"> <property name="visible">True</property> <child> <object class="GtkImageMenuItem" id="imagemenuitem1"> <property name="label">gtk-new</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> <child> <object class="GtkImageMenuItem" id="imagemenuitem2"> <property name="label">gtk-open</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> <child> <object class="GtkImageMenuItem" id="imagemenuitem3"> <property name="label">gtk-save</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> <child> <object class="GtkImageMenuItem" id="imagemenuitem4"> <property name="label">gtk-save-as</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> <child> <object class="GtkSeparatorMenuItem" id="separatormenuitem1"> <property name="visible">True</property> </object> </child> <child> <object class="GtkImageMenuItem" id="imagemenuitem5"> <property name="label">gtk-quit</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> </object> </child> </object> </child> <child> <object class="GtkMenuItem" id="menuitem2"> <property name="visible">True</property> <property name="label" translatable="yes">_Editar</property> <property name="use_underline">True</property> <child type="submenu"> <object class="GtkMenu" id="menu2"> <property name="visible">True</property> <child> <object class="GtkImageMenuItem" id="imagemenuitem6"> <property name="label">gtk-cut</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> <child> <object class="GtkImageMenuItem" id="imagemenuitem7"> <property name="label">gtk-copy</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> <child> <object class="GtkImageMenuItem" id="imagemenuitem8"> <property name="label">gtk-paste</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> <child> <object class="GtkImageMenuItem" id="imagemenuitem9"> <property name="label">gtk-delete</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> </object> </child> </object> </child> <child> <object class="GtkMenuItem" id="menuitem3"> <property name="visible">True</property> <property name="label" translatable="yes">_Ver</property> <property name="use_underline">True</property> </object> </child> <child> <object class="GtkMenuItem" id="menuitem4"> <property name="visible">True</property> <property name="label" translatable="yes">Ay_uda</property> <property name="use_underline">True</property> <child type="submenu"> <object class="GtkMenu" id="menu3"> <property name="visible">True</property> <child> <object class="GtkImageMenuItem" id="imagemenuitem10"> <property name="label">gtk-about</property> <property name="visible">True</property> <property name="use_underline">True</property> <property name="use_stock">True</property> </object> </child> </object> </child> </object> </child> </object> <packing> <property name="expand">False</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkHPaned" id="hpane1"> <property name="visible">True</property> <property name="can_focus">True</property> <child> <object class="GtkScrolledWindow" id="scrolledwindow1"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="hscrollbar_policy">automatic</property> <property name="vscrollbar_policy">automatic</property> <child> <object class="GtkTreeView" id="index"> <property name="width_request">200</property> <property name="height_request">300</property> <property name="visible">True</property> <property name="can_focus">True</property> <signal name="key_press_event" handler="on_index_key_press_event"/> <signal name="cursor_changed" handler="on_index_cursor_changed"/> <signal name="row_activated" handler="on_index_row_activated"/> </object> </child> </object> <packing> <property name="resize">False</property> <property name="shrink">True</property> </packing> </child> <child> <object class="GtkTextView" id="noteeditor"> <property name="width_request">300</property> <property name="height_request">300</property> <property name="visible">True</property> <property name="can_focus">True</property> </object> <packing> <property name="resize">True</property> <property name="shrink">True</property> </packing> </child> </object> <packing> <property name="position">1</property> </packing> </child> </object> </child> </object> </interface>
zimmindmap.glade
Description: application/glade
import sys import gtk class ZimMindMap(object): """ mock up of zim to test an idea """ temptitle = 'Title' templatechar = '.' def __init__ (self): """ Class initialiser """ self.notes={} self.current_note = None self.builder = gtk.Builder() self.builder.add_from_file("zimmindmap.glade") self.window = self.builder.get_object("mainwindow") self.noteeditor = self.builder.get_object("noteeditor") self.noteindex = self.builder.get_object("index") self.datamodel = gtk.TreeStore(str) self.cellrender=gtk.CellRendererText() # renderer para la primera columna self.title_column = gtk.TreeViewColumn('Notes') self.title_column.pack_start(self.cellrender,True) self.title_column.add_attribute(self.cellrender, "text", 0) self.noteindex.append_column(self.title_column) uno = self.newnote('Hello1') dos = self.newnote('Hello2') self.newnote('Hello11',uno) self.newnote('Hello12',uno) self.newnote('Hello21',dos) self.newnote('Hello22',dos) templates_iter=self.newnote('Templates') self.templates_root = self.datamodel.get_path(templates_iter) self.noteindex.set_model(self.datamodel) self.builder.connect_signals(self) def newnote(self, title, parent=None, texto=None): it = self.datamodel.append(parent, (title,)) path = self.datamodel.get_path(it) if not texto: texto=title self.notes[path] = texto return it def delnote(self, path): iter=self.datamodel.get_iter(path) self.datamodel.remove(iter) del self.notes[path] def on_mainwindow_destroy(self,widget,data=[]): gtk.main_quit() def on_mainwindow_key_release_event(self,widget,data=[]): if data.keyval==32 and (data.state& gtk.gdk.CONTROL_MASK): #Control+space if self.noteeditor.is_focus(): self.noteindex.grab_focus() else: self.noteeditor.grab_focus() return True def on_index_key_press_event(self,widget,data=[]): #65361: left, 65362:up, 65363: right, 65364:down, 65293:Enter, 32:space if data.keyval==65363: #right current_row,current_column=widget.get_cursor() current_iter=self.datamodel.get_iter(current_row) widget.expand_row(current_row,False) if data.state & gtk.gdk.MOD1_MASK:#Alt+Left new_note_iter=self.newnote(ZimMindMap.temptitle, parent=current_iter) new_note_path=self.datamodel.get_path(new_note_iter) # widget.expand_row(new_note_path,True) #doesn't work if current_row only has just this child widget.expand_row(current_row,True) #not the right thing, but works self.cellrender.set_property('editable',True) self.cellrender.connect('edited',self.edited_cell,self.datamodel) self.noteindex.set_cursor(new_note_path, focus_column=self.title_column ,start_editing=True) elif data.keyval==65364 and (data.state& gtk.gdk.MOD1_MASK):#Alt+down current_row,current_column=widget.get_cursor() current_iter=self.datamodel.get_iter(current_row) parent_iter=self.datamodel.iter_parent(current_iter) parent_path=self.datamodel.get_path(parent_iter) if parent_iter else () new_note_iter=self.newnote(ZimMindMap.temptitle, parent=parent_iter) new_note_path=self.datamodel.get_path(new_note_iter) if parent_path: widget.expand_row(parent_path,True) #not the right thing, but works self.cellrender.set_property('editable',True) self.cellrender.connect('edited',self.edited_cell,self.datamodel) self.noteindex.set_cursor(new_note_path, focus_column=self.title_column ,start_editing=True) elif data.keyval==65361: #left current_row,current_column=widget.get_cursor() current_iter=self.datamodel.get_iter(current_row) widget.collapse_row(current_row) elif data.keyval==65293 or data.keyval==32: #Enter or space selection = widget.get_selection() model,iter = selection.get_selected() path = self.datamodel.get_path(iter) self.show_note(path) return True def on_index_cursor_changed(self,widget,data=None): pass def on_index_row_activated(self, widget, path, view_column): self.show_note(path) def edited_cell(self, cell, path, new_text, user_data): iter=self.datamodel.get_iter(path) path=self.datamodel.get_path(iter) #path is given to edited_cell in non-standard format parent=self.datamodel.iter_parent(iter) parent_path=self.datamodel.get_path(parent) #template section if parent_path!=self.templates_root: templates_iter=self.datamodel.get_iter(self.templates_root) templates=[self.datamodel.iter_nth_child(templates_iter, i) for i in range(self.datamodel.iter_n_children(templates_iter))] for iter in templates: #TODO: search subchildren template_name = self.datamodel.get_value(iter,0) if new_text==template_name: print 'Template name match: '+template_name template_path=self.datamodel.get_path(iter) self.notes[path] = ZimMindMap.templatechar+self.notes[template_path] self.noteindex.set_cursor(path, focus_column=self.title_column ,start_editing=True) return True if self.notes[path][0]==ZimMindMap.templatechar: nota=self.notes[path][1:] else: nota = new_text self.delnote(path) self.newnote(new_text, parent, nota) self.cellrender.set_property('editable',False) self.noteindex.expand_row(parent_path,True) #not the right thing, but works self.noteindex.set_cursor(path, focus_column=self.title_column ,start_editing=False) self.show_note(path) def show_note(self, path): self.save_note() try: note_text = self.notes[path] buffer = self.noteeditor.get_buffer() buffer.set_text(note_text) self.current_note=path except KeyError: buffer = self.noteeditor.get_buffer() buffer.set_text(repr(path)+' not found') def save_note(self): if self.current_note: buffer = self.noteeditor.get_buffer() start, end = buffer.get_bounds() self.notes[self.current_note] = buffer.get_text(start, end) if __name__ == "__main__": tareas = ZimMindMap() tareas.window.show() gtk.main()
_______________________________________________ Mailing list: https://launchpad.net/~zim-wiki Post to : zim-wiki@lists.launchpad.net Unsubscribe : https://launchpad.net/~zim-wiki More help : https://help.launchpad.net/ListHelp