<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1971774800846849097</id><updated>2011-07-08T04:47:27.243+03:00</updated><title type='text'>Luc's Lino Blog</title><subtitle type='html'>Get the hottest news about what I'm doing on Lino.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-4589454552208175401</id><published>2010-02-02T09:11:00.000+02:00</published><updated>2010-02-02T09:11:49.556+02:00</updated><title type='text'>Adieu wysiwyg blogging</title><content type='html'>I started to blog on Lino's &lt;a href="http://code.google.com/p/lino/wiki/WikiBlog"&gt;WikiBlog&lt;/a&gt;, and it seems that I like it better than Blogger's wysiwyg editor. Such a self-made WikiBlog is probably less easily readable, but more easily writable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-4589454552208175401?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/4589454552208175401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2010/02/adieu-wysiwyg-blogging.html#comment-form' title='37 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/4589454552208175401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/4589454552208175401'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2010/02/adieu-wysiwyg-blogging.html' title='Adieu wysiwyg blogging'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>37</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-2492264023013717830</id><published>2010-01-12T15:54:00.002+02:00</published><updated>2010-01-12T16:04:00.353+02:00</updated><title type='text'>Why doesn't  Blogger support any wiki format?</title><content type='html'>Blogger isn't really my thing because I hate to blog when the blog server doesn't support wiki format.&lt;br /&gt;So today I misused the &lt;a href="http://code.google.com/p/lino/wiki/20100112"&gt;Lino wiki&lt;/a&gt; for blogging.&lt;br /&gt;Result: I write more.&lt;br /&gt;But then I read &lt;a href="http://coevolving.com/blogs/index.php/archive/is-wiki-markup-dead/"&gt;Wiki markup is dead...&lt;/a&gt;&lt;br /&gt;Hmm...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-2492264023013717830?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/2492264023013717830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2010/01/why-doesnt-blogger-support-any-wiki.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/2492264023013717830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/2492264023013717830'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2010/01/why-doesnt-blogger-support-any-wiki.html' title='Why doesn&apos;t  Blogger support any wiki format?'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-7456540668811606876</id><published>2010-01-07T10:51:00.003+02:00</published><updated>2010-01-07T22:33:26.385+02:00</updated><title type='text'>New ideas for Lino.do_action()</title><content type='html'>Working on &lt;a href="http://code.google.com/p/lino/issues/detail?id=61"&gt;issue 61&lt;/a&gt;. Some of my thoughts...&lt;br /&gt;&lt;br /&gt;Lino.do_action() does an AJAX call on the specified URL. This URL defines the action that runs on the server. Lino.do_action() then reacts according to the response.&lt;br /&gt;The action may return a "job" (response.job, previously response.call) to be executed by the client.&lt;br /&gt;Maybe "reaction" would be a better name than "job". But let's call it a job because that name is not yet used in Lino's source, and after all this thing becomes a "job" for the client in the meaning that it will continue to run until some other action asks to stop it.&lt;br /&gt;&lt;br /&gt;For example a report action, on the server, will check whether the user is allowed to see this data, will load window_config, and then return a Job that will create the Ext.Window with all its components and also call the show() method. The close() method of that job just closes this window.&lt;br /&gt;&lt;br /&gt;If response.job is defined, it must be a string of JS code that defines a constructor function.The client will instantiate a new object using this constructor.&lt;br /&gt;The constructor must initialize the new object so that it implements the Job interface:&lt;br /&gt;- stop()&lt;br /&gt;- refresh()&lt;br /&gt;- selected_rows()&lt;br /&gt;&lt;br /&gt;Note that there is no start() method. This is because the Job is supposed to start it's work during instantiation.&lt;br /&gt;&lt;br /&gt;Lino.do_action() will need a new parameter "caller" (the Job who requests this action), and the parameters reload, close_dialog and job_params can go away since the caller contains them.&lt;br /&gt;The parameter caller may be undefined if the action is called from a main menu item.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Lino.grid_action(), Lino.form_action() and Lino.show_detail() can then go away&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-7456540668811606876?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/7456540668811606876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2010/01/new-ideas-for-linodoaction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/7456540668811606876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/7456540668811606876'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2010/01/new-ideas-for-linodoaction.html' title='New ideas for Lino.do_action()'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-7291608630761679789</id><published>2009-12-16T16:59:00.002+02:00</published><updated>2009-12-16T17:09:58.266+02:00</updated><title type='text'>Implement report windows as actions</title><content type='html'>Hier ist nochmal ein Bild der aktuellen Situation.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_zt7B6VI3Ah4/SyjvvD8jp_I/AAAAAAAABKs/oV2Iq1JhVX4/s1600-h/20091216.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_zt7B6VI3Ah4/SyjvvD8jp_I/AAAAAAAABKs/oV2Iq1JhVX4/s320/20091216.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Oberflächliche Probleme:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Submit in PersonDetail funktioniert nicht. Traceback "field 'name' may not be null. Das kommt, seit ich django.db.field.to_python für die Konvertierung benutze.&lt;/li&gt;&lt;li&gt;The comboBoxes of ForeignKeys don't display the values.&lt;/li&gt;&lt;li&gt;Focussing problems: after closing a window, the previous window should get keyboard focus. When a Window with a Grid gets focus, it should forward the focus to it's grid.&lt;/li&gt;&lt;li&gt;links.Link should provide a virtual column that offers clickable display of the url, as well as drag&amp;amp;amp;drop to update it.&lt;/li&gt;&lt;li&gt;Number of rows displayed in a grid should be as much as fits into the window. Or the window should adapt its size to its grid.&lt;/li&gt;&lt;li&gt;PageLayout.layout_for instead of Report.page_layouts&lt;/li&gt;&lt;/ul&gt;Aber einige dieser Punkte sind wahrscheinlich verknüpft mit einem fundamentalen Problem, das ich deshalb wahrscheinlich als nächstes in Angriff nehme: &lt;b&gt;Implement report windows as actions&lt;/b&gt;.&lt;br /&gt;Das bedeutet, dass die Reports nicht mehr wie momentan alle als statische Funktionen im JS vordefiniert sind, sondern dass beim Klick auf einen entsprechenden Menübefehl ein AJAX-Request rausgeht, den der Server mit der Definition des zu öffnenden Fensters beantwortet.&lt;br /&gt;&lt;br /&gt;Also statt z.B. der folgenden Funktion, ...&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;var projects_ProjectTypes = new function() {&lt;br /&gt;&amp;nbsp; this.main_grid = new function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var main_cols = new Ext.grid.ColumnModel({ columns: [ { header: 'ID', width: 45, editable: false, sortable: true, dataIndex: 'id' }, { header: 'name', sortable: true, editor: { xtype: 'textfield', fieldLabel: 'name', allowBlank: false, maxLength: 200, anchor: '100%', name: 'name' }, width: 180, editable: true, dataIndex: 'name' } ] });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var buttons = [ { text: 'Delete', handler: Lino.grid_action(this,'lino_DeleteSelected','/grid_action/projects/ProjectTypes/lino_DeleteSelected') }, { text: 'Detail', handler: Lino.show_detail(this,'projects_ProjectTypes2') } ];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var keys = [ { shift: false, alt: false, handler: Lino.grid_action(this,'lino_DeleteSelected','/grid_action/projects/ProjectTypes/lino_DeleteSelected'), key: 46, ctrl: false }, { shift: false, alt: false, handler: Lino.show_detail(this,'projects_ProjectTypes2'), key: 13, ctrl: true } ];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.comp = new Ext.grid.EditorGridPanel({ clicksToEdit: 2, colModel: main_cols, tbar: new Ext.PagingToolbar({ prependButtons: false, items: buttons, pageSize: 10, store: projects_ProjectTypes_store, displayInfo: true }), viewConfig: { showPreview: true, scrollOffset: 200, emptyText: 'Nix gefunden!' }, selModel: new Ext.grid.RowSelectionModel({singleSelect:false}), enableColLock: false, store: projects_ProjectTypes_store, emptyText: 'Nix gefunden...' });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.comp.on('afteredit', Lino.grid_afteredit(this,'/grid_afteredit/projects/ProjectTypes','id'));&lt;br /&gt;&amp;nbsp; }();&lt;br /&gt;&amp;nbsp; this.show = function(btn,event,unused_master,master_grid) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(this.comp) { this.comp.show() ; return; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.comp = new Ext.Window( { width: 400, layout: 'fit', maximizable: true, title: 'ProjectTypes - List', closeAction: 'hide', items: this.main_grid.comp, tools: [ { handler: Lino.save_window_config('/save_win/projects_ProjectTypes'), id: 'save' } ], id: 'projects_ProjectTypes', height: 300 } );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; projects_ProjectTypes_store.load();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.comp.show();&lt;br /&gt;&amp;nbsp; };&lt;br /&gt;}();&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;..., die momentan im Menübefehl mit projects_ProjectTypes.show() aufgerufen wird, ruft der Menübefehl die existierende Lino.do_action(), und diese action gibt dann eine JS-Expression "new ext.Window(...).show()" zurück, die die gleiche Wirkung hat. Wobei die "..." natürlich ziemlich lang werden können.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-7291608630761679789?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/7291608630761679789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/12/implement-report-windows-as-actions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/7291608630761679789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/7291608630761679789'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/12/implement-report-windows-as-actions.html' title='Implement report windows as actions'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_zt7B6VI3Ah4/SyjvvD8jp_I/AAAAAAAABKs/oV2Iq1JhVX4/s72-c/20091216.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-8463297734442539828</id><published>2009-11-25T04:42:00.000+02:00</published><updated>2009-11-25T04:42:37.525+02:00</updated><title type='text'>Fenstergrößen und -positionen jetzt speicherbar</title><content type='html'>Gestern Abend vor dem Schlafengehen grübelte ich noch über das Problem nach, wie abartig es doch ist, dass ich die Größe eines Ext.Window anhand seiner Komponenten selber zu ermitteln versuche. Heute morgen suchte ich zuerst nochmal nach, ob Ext.Window tatsächlich keine fertige Methode "sizeToFit()" oder so hat. Hat er scheinbar nicht.&lt;br /&gt;&lt;br /&gt;Aber dann fiel mir ein, dass man ja sowieso die Fenstergrößen und -positionen manuell speichern können muss. Wenn das gemacht wäre, wäre es egal, dass Fenster par défaut immer in der Mitte stehen und alle die gleiche Höhe haben. Also machte ich mich an die Implementierung dieses Features. Keine zwei Stunden Arbeit, und alles funktioniert wie gehabt:&lt;br /&gt;neuer tool-Button "save" in allen Fensterrahmen. Wenn man darauf klickt, wird per AJAX die Position und Größe des Fensters gespeichert. Auf dem Server wohlgemerkt. Einfach mit pickle in eine Datei "window_configs.pck". Momentan also immer global für alle Benutzer. Und ich glaube, dass das bis auf weiteres reicht, denn das sind Parameter, die anwendungsspezifisch verwaltet werden. und alle Benutzer sollen das gleiche Erscheinungsbild haben.&lt;br /&gt;&lt;br /&gt;ActionContext kann jetzt mit *args und **kw instanziert werden. Was für die neue SaveWindowConfigAction gebraucht wird.&lt;br /&gt;&lt;br /&gt;Und noch eine geniale (interne) Neuerung nebenbei: wenn py2js() einen callable kriegt, dann muss das ein Iterator sein, der einzelne JS-Zeilen liefert. Dadurch konnte ich folgenden Code schreiben:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; def save():&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield "function(event,toolEl,panel,tc) {"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield "&amp;nbsp; console.log(panel.id,panel.getSize(),panel.getPosition());"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield "var pos = panel.getPosition();"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield "var size = panel.getSize();"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; url = '/save_win/' + self.name&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield "&amp;nbsp; Lino.do_action(%r,%r,{x:pos[0],y:pos[1],\&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; h:size['height'],w:size['width']});" % (url,url)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield "}"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.options.update(tools=[dict(id='save',handler=save)])&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So, und jetzt schlaf ich vielleicht noch mal was...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-8463297734442539828?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/8463297734442539828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/11/fenstergroen-und-positionen-jetzt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/8463297734442539828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/8463297734442539828'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/11/fenstergroen-und-positionen-jetzt.html' title='Fenstergrößen und -positionen jetzt speicherbar'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-1878792527686610682</id><published>2009-11-23T09:54:00.000+02:00</published><updated>2009-11-23T09:54:03.181+02:00</updated><title type='text'>Dialogs and Actions</title><content type='html'>Wow! Issues 12 and 38 are solved! It is again possible to log in and out, and this is done using Actions and Layouts which are rendered using ExtJS. Here is a code summary:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;class Login(layouts.DialogLayout):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; text = layouts.StaticText("Please enter your username and &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; password to authentificate.")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; username = layouts.Input(fieldLabel=_("Username"),maxLength=75)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; password = layouts.Input(fieldLabel=_("Password"),&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; maxLength=75,inputType='password')&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; main = """&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; text&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; username&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; password&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cancel ok&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ok = LoginAction()&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;class LoginAction(actions.OK):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; label = _("Login")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def run(self,context):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; username = context.request.POST.get('username')&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; password = context.request.POST.get('password')&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if username and password:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; user = authenticate(username=username, password=password)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if user is None:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise actions.ValidationError(&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _("Please enter a correct username and password. &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Note that both fields are case-sensitive."))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; elif not user.is_active:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise actions.ValidationError(&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _("This account is inactive."))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; login(context.request, user)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lino.log.info("User %s logged in.",user)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.refresh_menu()&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;class Logout(actions.OK):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; label = _("Log out")&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def run(self,context):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.confirm(_("Are you sure you want to log out?"))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logout(context.request)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.refresh_menu()&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;/span&gt;&lt;br /&gt;These things are then integrated into the main menu as follows:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = lino.add_menu("auth",_("~Authentificate"))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; m.add_action(Login(),can_view=perms.is_anonymous)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; m.add_action(Logout(),can_view=perms.is_authenticated)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Isn't that beautiful? I won't show you a screenshot right now because of &lt;a href="http://code.google.com/p/lino/issues/detail?id=47"&gt;issue 47&lt;/a&gt;. But just remember the screenshot of my &lt;a href="http://lsaffre.blogspot.com/2009/11/first-results-with-dialoglayout.html"&gt;previous post&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-1878792527686610682?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/1878792527686610682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/11/dialogs-and-actions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1878792527686610682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1878792527686610682'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/11/dialogs-and-actions.html' title='Dialogs and Actions'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-1382502083349078184</id><published>2009-11-18T18:49:00.002+02:00</published><updated>2009-11-18T21:25:42.666+02:00</updated><title type='text'>First results with DialogLayout</title><content type='html'>This week I started to implement dialog windows that are defined using Layout. A first visible result is the Login dialog box. Here is the code used to define it:&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;class Login(layouts.DialogLayout):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; username = models.CharField(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; verbose_name=_("Username"), max_length=75)&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; password = models.CharField(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; verbose_name=_("Password"), max_length=75)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; main = """&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; text&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; username&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; password&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cancel ok&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ok = LoginAction&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; text = layouts.StaticText("Please enter your username and password to authentificate.")&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;And here is how it looks:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_zt7B6VI3Ah4/SwQjBLdpERI/AAAAAAAAA24/_4vr83gdnFw/s1600/20091118b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_zt7B6VI3Ah4/SwQjBLdpERI/AAAAAAAAA24/_4vr83gdnFw/s400/20091118b.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;For the moment nothing happens when you click on ok. That's for tomorrow.&lt;br /&gt;Interesting to notice: Lino uses django.db.models.Field instances to define the form's fields, not django.forms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-1382502083349078184?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/1382502083349078184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/11/first-results-with-dialoglayout.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1382502083349078184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1382502083349078184'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/11/first-results-with-dialoglayout.html' title='First results with DialogLayout'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_zt7B6VI3Ah4/SwQjBLdpERI/AAAAAAAAA24/_4vr83gdnFw/s72-c/20091118b.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-6896595706947281684</id><published>2009-11-09T16:48:00.001+02:00</published><updated>2009-11-09T16:51:38.045+02:00</updated><title type='text'>A patch for Django ticket  #11696</title><content type='html'>Django &lt;a href="http://code.djangoproject.com/ticket/11696"&gt;ticket&amp;nbsp; #11696&lt;/a&gt; is still not solved in Revision 11724. I didn't manage to apply the patch posted by anonymous on 09/13/09 18:08:56. Now I wrote &lt;a href="http://code.google.com/p/lino/source/browse/patches/20091107.diff?spec=svn18645239b542cf3fbbdf9525609c81ebf052a739&amp;amp;r=18645239b542cf3fbbdf9525609c81ebf052a739"&gt;my own patch &lt;/a&gt;which works for me, and I document it here as far as possible for now.&lt;br /&gt;&lt;br /&gt;To install the patch, download the file 20091107.diff into you django's working copyand then type "patch -p0 &amp;lt; 20091107.diff", which should result in something like this: &lt;br /&gt;&lt;blockquote&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;(Stripping trailing CRs from patch.)&lt;br /&gt;patching file django/db/models/loading.py&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;Yes I should write some test cases, when I have more time... for now I just write down the situation. I have a site with about 10 applications, and the models.py of one of them tries to import a non-existing module. This situation is stored in &lt;a href="http://code.google.com/p/lino/source/detail?r=18645239b542cf3fbbdf9525609c81ebf052a739"&gt;Lino 841&lt;/a&gt; and &lt;a href="http://code.google.com/p/lino-igen/source/detail?r=d31b8c0187175a0d53598b58b6e8c5391164fed1"&gt;igen 2&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here is what happens without my patch:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;T:\hgwork\igen\src\igen\demo&amp;gt;python manage.py validate&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;&amp;nbsp; File "manage.py", line 16, in &lt;module&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; execute_manager(settings)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\core\management\__init__.py", line 440, in execute_manager&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; utility.execute()&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\core\management\__init__.py", line 380, in execute&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.fetch_command(subcommand).run_from_argv(self.argv)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\core\management\base.py", line 195, in run_from_argv&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.execute(*args, **options.__dict__)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\core\management\base.py", line 223, in execute&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; output = self.handle(*args, **options)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\core\management\base.py", line 352, in handle&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return self.handle_noargs(**options)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\core\management\commands\validate.py", line 9, in handle_noargs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.validate(display_num_errors=True)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\core\management\base.py", line 250, in validate&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; num_errors = get_validation_errors(s, app)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\core\management\validation.py", line 28, in get_validation_errors&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (app_name, error) in get_app_errors().items():&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 131, in get_app_errors&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self._populate()&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 58, in _populate&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.load_app(app_name, True)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 74, in load_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; models = import_module('.models', app_name)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\utils\importlib.py", line 35, in import_module&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __import__(name)&lt;br /&gt;&amp;nbsp; File "c:\drives\t\hgwork\lino\src\lino\modlib\contacts\models.py", line 29, in &lt;module&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; countries = models.get_app('countries')&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 114, in get_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self._populate()&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 58, in _populate&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self.load_app(app_name, True)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 74, in load_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; models = import_module('.models', app_name)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\utils\importlib.py", line 35, in import_module&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __import__(name)&lt;br /&gt;&amp;nbsp; File "c:\drives\t\hgwork\lino\src\lino\modlib\ledger\models.py", line 26, in &lt;module&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; journals = reports.get_app('journals')&lt;br /&gt;&amp;nbsp; File "c:\drives\t\hgwork\lino\src\lino\reports.py", line 44, in get_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = models.get_app(app_label)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 125, in get_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise ImproperlyConfigured, "App with label %s could not be found" % app_label&lt;br /&gt;django.core.exceptions.ImproperlyConfigured: App with label journals could not be found &lt;br /&gt;&lt;/module&gt;&lt;/module&gt;&lt;/module&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Which is a completely useless error message. &lt;br /&gt;And here is what happens after applying my patch: &lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; (...)&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 156, in get_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self._populate()&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 96, in _populate&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; len(self.postponed),msg))&lt;br /&gt;django.core.exceptions.ImproperlyConfigured: Failed to import 3 applications:&lt;br /&gt;lino.modlib.sales:&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 112, in load_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; models = import_module('.models', app_name)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\utils\importlib.py", line 35, in import_module&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __import__(name)&lt;br /&gt;&amp;nbsp; File "c:\drives\t\hgwork\lino\src\lino\modlib\sales\models.py", line 49, in &lt;module&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from lino.modlib.contacts import models as contacts&lt;br /&gt;ImportError: cannot import name models&lt;br /&gt;lino.modlib.finan:&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 112, in load_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; models = import_module('.models', app_name)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\utils\importlib.py", line 35, in import_module&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __import__(name)&lt;br /&gt;&amp;nbsp; File "c:\drives\t\hgwork\lino\src\lino\modlib\finan\models.py", line 32, in &lt;module&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from lino.modlib.contacts import models as contacts&lt;br /&gt;ImportError: cannot import name models&lt;br /&gt;lino.modlib.journals:&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\db\models\loading.py", line 112, in load_app&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; models = import_module('.models', app_name)&lt;br /&gt;&amp;nbsp; File "l:\snapshot\django\django\utils\importlib.py", line 35, in import_module&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __import__(name)&lt;br /&gt;&amp;nbsp; File "c:\drives\t\hgwork\lino\src\lino\modlib\journals\models.py", line 30, in &lt;module&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from lino.apps.documents import models as documents&lt;br /&gt;ImportError: No module named apps.documents&lt;/module&gt;&lt;/module&gt;&lt;/module&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-6896595706947281684?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/6896595706947281684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/11/patch-for-django-ticket-11696.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/6896595706947281684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/6896595706947281684'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/11/patch-for-django-ticket-11696.html' title='A patch for Django ticket  #11696'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-8943668169077458032</id><published>2009-11-07T22:11:00.000+02:00</published><updated>2009-11-07T22:11:59.393+02:00</updated><title type='text'>Umstrukturierungen nach Abtrennung von dsbe und igen</title><content type='html'>Lino (bzw. &lt;a href="http://code.google.com/p/lino-igen/"&gt;igen&lt;/a&gt; und &lt;a href="http://code.google.com/p/lino-dsbe/"&gt;dsbe&lt;/a&gt;) ist &lt;a href="http://code.google.com/p/lino/source/detail?r=bc7e390bce53332f535dae214593b0392572a8b4"&gt;momentan&lt;/a&gt; nicht lauffähig, weil die Umstrukturierungen nach der Abtrennung der beiden ersten Anwendungen noch interessante Lawineneffekte hatten. Ich hatte z.B. mal wieder den Effekt, dass Django einen Fehler beim Importieren eines models-Moduls in in manchen Fällen stillschweigend ignoriert und die betreffende Anwendung dann schlicht nicht da ist. Ich habe unter anderem einen &lt;a href="http://code.google.com/p/lino/source/browse/patches/20091107.diff?spec=svn2c298c053786c4383572b5c75787d9cf52119a2a&amp;amp;r=2c298c053786c4383572b5c75787d9cf52119a2a#"&gt;Patch&lt;/a&gt; geschrieben, damit Django abbricht, wenn ein models-Modul zwar existiert aber auch beim zweiten Versuch nicht importiert werden kann.&lt;br /&gt;&lt;br /&gt;Was da noch hapert, habe ich im &lt;a href="http://code.google.com/p/lino/issues/detail?id=40"&gt;Issue 40&lt;/a&gt; festgehalten. Das muss jetzt aber ein paar Tage warten.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-8943668169077458032?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/8943668169077458032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/11/umstrukturierungen-nach-abtrennung-von.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/8943668169077458032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/8943668169077458032'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/11/umstrukturierungen-nach-abtrennung-von.html' title='Umstrukturierungen nach Abtrennung von dsbe und igen'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-8914015911707147791</id><published>2009-11-06T18:05:00.000+02:00</published><updated>2009-11-06T18:05:27.332+02:00</updated><title type='text'>Detached "lino-dsbe" and "lino-igen" from lino</title><content type='html'>I created two new Google projects "lino-dsbe" and "lino-igen", one for each of these two early Lino applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-8914015911707147791?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/8914015911707147791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/11/detached-lino-dsbe-and-lino-igen-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/8914015911707147791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/8914015911707147791'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/11/detached-lino-dsbe-and-lino-igen-from.html' title='Detached &quot;lino-dsbe&quot; and &quot;lino-igen&quot; from lino'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-227649919577376088</id><published>2009-11-04T17:23:00.002+02:00</published><updated>2009-11-04T17:28:32.084+02:00</updated><title type='text'>Anonymous classes in JavaScript</title><content type='html'>I opened &lt;a href="http://code.google.com/p/lino/issues/detail?id=39"&gt;issue 39&lt;/a&gt; and worked on it. I won't finish this today, but the new structure of the generated JavaScript code becomes tangible. It will use a JS feature which I'd call "anonymous classes". Here is a snippet I wrote to see whether it is possible. It creates three nested instances of an anonymous class:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;window.onload = function () {&lt;br /&gt;&amp;nbsp; var foo = new function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.bar = 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.baz = new function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.bar = 2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.baz = new function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.bar = 3;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }();&lt;br /&gt;&amp;nbsp; }();&lt;br /&gt;&amp;nbsp; document.write(foo.bar+" "+foo.baz.bar+" "+foo.baz.baz.bar);&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And yes, it works, it writes "1 2 3" into your document.&lt;br /&gt;&lt;br /&gt;An anonymous class is used only once to instantiate a single object, and then we forget their definition because we don't need it any more.&lt;br /&gt;I will use this technique because it will be more straightforward to generate such code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-227649919577376088?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/227649919577376088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/11/anonymous-classes-in-javascript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/227649919577376088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/227649919577376088'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/11/anonymous-classes-in-javascript.html' title='Anonymous classes in JavaScript'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-3503153131574229951</id><published>2009-11-04T08:59:00.004+02:00</published><updated>2009-11-04T09:16:36.777+02:00</updated><title type='text'>Luc was in Belgium</title><content type='html'>In case you wonder why I didn't post anything for more than 2 weeks: I was in Belgium where I mainly installed a new &lt;a href="http://code.google.com/p/tim/"&gt;TIM&lt;/a&gt; that will run on a site with about 10 users. TIM, despite its age and oldfashionedness, is still being used and maintained, and is my primary source of income. So don't complain when Lino must sometimes wait because of TIM!&lt;br /&gt;&lt;br /&gt;Here is a snapshot made with freshly installed TIM and some of the new users:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_zt7B6VI3Ah4/SvEoNWg6m1I/AAAAAAAAAfU/SNP_azrbS34/s1600-h/200910-23_1110-49.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_zt7B6VI3Ah4/SvEoNWg6m1I/AAAAAAAAAfU/SNP_azrbS34/s320/200910-23_1110-49.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;But note that Lino wasn't completely asleep. I also had a meeting with the people who are probably going to be the first Lino users of the world:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_zt7B6VI3Ah4/SvEowEPqF4I/AAAAAAAAAfc/jThzpj-ixcQ/s1600-h/200910-27_1053-50.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_zt7B6VI3Ah4/SvEowEPqF4I/AAAAAAAAAfc/jThzpj-ixcQ/s320/200910-27_1053-50.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Enough for know. Today is the first day after my travel where I will probably work on Lino again!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-3503153131574229951?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/3503153131574229951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/11/luc-was-in-belgium.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/3503153131574229951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/3503153131574229951'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/11/luc-was-in-belgium.html' title='Luc was in Belgium'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SvEoNWg6m1I/AAAAAAAAAfU/SNP_azrbS34/s72-c/200910-23_1110-49.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-4307934069223714359</id><published>2009-10-17T19:45:00.000+03:00</published><updated>2009-10-17T19:45:20.915+03:00</updated><title type='text'>Finally satisfied with logging</title><content type='html'>I pushed &lt;a href="http://code.google.com/p/lino/source/detail?r=fabc7a1c89b58d5110cf83ba1750b4af9c0ff7bf"&gt;changeset 825:fabc7a1c89b5 &lt;/a&gt;to Google. Now I'm finally satisfied about how Lino uses the standard Python logging module.&lt;br /&gt;&lt;br /&gt;In short: Code that runs on a LinoSite can simply import lino_site and use lino_site.log as logger. LinoSite's default logging behaviour is to render the bare messages (without any meta info) to sys.stderr and write complete records (with timestamp, module and  level) to a file lino.log. The detailed messages in lino.log don't contain the logger's name (because that would be always the same) but do include the module's name.&lt;br /&gt;If you don't want this behaviour, then just configure yourself the logging module before instantiating LinoSite. &lt;br /&gt;But before I write more about this, let's wait whether my satisfaction stays ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-4307934069223714359?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/4307934069223714359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/10/finally-satisfied-with-logging.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/4307934069223714359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/4307934069223714359'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/10/finally-satisfied-with-logging.html' title='Finally satisfied with logging'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-525571730752681190</id><published>2009-10-15T10:39:00.002+03:00</published><updated>2009-10-15T18:06:05.535+03:00</updated><title type='text'>When your Django doctests never fail...</title><content type='html'>Grr... don't believe the Django test runner when it claims that your doctests pass! I was eagerly working on &lt;a href="http://code.google.com/p/lino/issues/detail?id=1"&gt;issue #1&lt;/a&gt; and wrote a new test application called &lt;a href="http://code.google.com/p/lino/source/browse/src/lino/test_apps/20091014/models.py"&gt;20091014&lt;/a&gt;, (the lino.test_apps package is a convenient way to write such quick standalone Django tests: I just change INSTALLED_APPS = ( 'lino.test_apps.20091014',&amp;nbsp; ) in my settings.py and then I can do "python manage.py test"). This usually works fine, but now I noticed that after the last changes it says:&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Lino version 0.0.1&lt;br /&gt;Creating test database...&lt;br /&gt;Creating table 20091014_a&lt;br /&gt;Creating table 20091014_b&lt;br /&gt;----------------------------------------------------------------------&lt;br /&gt;Ran 0 tests in 0.000s&lt;br /&gt;OK&lt;br /&gt;Destroying test database...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Which means that it actually ignored the whole doctest string, as if there were no test at all. I read &lt;a href="http://jki.posterous.com/how-to-get-django-doctests-to-work-again"&gt;here&lt;/a&gt; and &lt;a href="http://www.naffziger.net/blog/fix-its-how-tos-info/django-testing-gotchas/"&gt;there&lt;/a&gt; about other people who had had similar problems. It still took me some time to discover my mistake. Afterwards I made the following experiment in a file tmp.py: &lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;"""&lt;br /&gt;First test:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;gt;&amp;gt;&amp;gt; 9+2&lt;br /&gt;&amp;nbsp; 11&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;gt;&amp;gt;&amp;gt; foo() #doctest: +IGNORE_EXCEPTION_DETAIL&lt;br /&gt;&amp;nbsp; Traceback (most recent call last):&lt;br /&gt;&amp;nbsp; (...)&lt;br /&gt;&amp;nbsp; NameError: name 'foo' is not defined&amp;nbsp; &lt;br /&gt;&amp;nbsp; &lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; import doctest&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; doctest.testmod() &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;python tmp.py says nothing, which means that all tests passed. Then I removed one space in front of the word "Traceback". This is in fact the syntax error I had introduced by mistak into my lino.test_app docstring. Here is how Python reacts in such a case:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Traceback (most recent call last):&lt;br /&gt;&amp;nbsp; File "tmp.py", line 16, in &lt;module&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; doctest.testmod()&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 1814, in testmod&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for test in finder.find(m, name, globs=globs, extraglobs=extraglobs):&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 839, in find&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self._find(tests, obj, name, module, source_lines, globs, {})&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 881, in _find&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; test = self._get_test(obj, name, module, globs, source_lines)&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 965, in _get_test&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; filename, lineno)&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 594, in get_doctest&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return DocTest(self.get_examples(string, name), globs,&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 608, in get_examples&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return [x for x in self.parse(string, name)&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 570, in parse&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; self._parse_example(m, name, lineno)&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 640, in _parse_example&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lineno + len(source_lines))&lt;br /&gt;&amp;nbsp; File "c:\Python25\lib\doctest.py", line 726, in _check_prefix&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (lineno+i+1, name, line))&lt;br /&gt;ValueError: line 8 of the docstring for __main__ has inconsistent leading whitespace: ' Traceback (most recent call last&lt;br /&gt;):'&lt;br /&gt;&lt;/module&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The Django test runner ignores such docstring syntax errors without any warning.&lt;br /&gt;I'm using today's Django development version (revision 11624).&lt;br /&gt;&lt;br /&gt;Django in fact has already a &lt;a href="http://code.djangoproject.com/ticket/11436%20"&gt;ticket #11436&lt;/a&gt; which reveals that they are waiting for Python &lt;a href="http://bugs.python.org/issue1521051"&gt;issue 1521051&lt;/a&gt; to be fixed... for me that's enough to forgive them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-525571730752681190?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/525571730752681190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/10/when-your-django-doctests-never-fail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/525571730752681190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/525571730752681190'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/10/when-your-django-doctests-never-fail.html' title='When your Django doctests never fail...'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-6245421073509740064</id><published>2009-10-09T22:09:00.000+03:00</published><updated>2009-10-09T22:09:52.703+03:00</updated><title type='text'>Wochenende</title><content type='html'>Es hat sich diese Woche so viel getan, dass ich mit dem Dokumentieren nicht nachkomme. Ich versuche wenigstens die &lt;a href="http://code.google.com/p/lino/issues/list"&gt;Tickets&lt;/a&gt; à jour zu halten. aber jetzt haben wir erst mal Wochenende.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-6245421073509740064?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/6245421073509740064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/10/wochenende.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/6245421073509740064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/6245421073509740064'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/10/wochenende.html' title='Wochenende'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-5051745636019454774</id><published>2009-09-30T09:24:00.000+03:00</published><updated>2009-09-30T09:24:46.957+03:00</updated><title type='text'>Noch mehr Fenster</title><content type='html'>Hier meine Notizen von gestern vormittag. Erst heute kann ich endlich daran weiter arbeiten. Morgen kommt leider schon wieder eine Unterbrechung, weil ich nach Tallinn muss. Und am Freitag kommen Kristiina und Juta Äpfel pressen, wenn ich Pech habe muss ich ihnen helfen und kann auch dann nicht weiter programmieren. Oje. Aber ich hoffe doch noch, dass ich für Ende Oktober einen zeigbaren Prototypen hinkriege!&lt;br /&gt;&lt;br /&gt;Aber zur Sache.&lt;br /&gt;&lt;br /&gt;Momentan ist das Detail-Fenster eines Contact so groß, dass es nicht in den Viewport passt.&lt;br /&gt;Ich habs zwar geschafft, dem Viewport Scrollbars zu verpassen (besser gesagt dem Panel in dessen Mitte), aber dadurch scrollen die Windows noch nicht mit. Das ist also keine Lösung.&lt;br /&gt;Sowieso hat es keinen Zweck, eine Art scrollbaren Desktop zu produzieren, sondern die Fenster müssen schon eine sinnvolle Größe haben.&lt;br /&gt;&lt;br /&gt;"List" und "Detail" mit einem TabPanel in ein einziges Window zu packen, ist wohl nicht so toll, denn wenn man umschaltet, muss sich ja die Fenstergröße ändern. Tut sie sogar automatisch, aber das ist irritierend. Ich muss wohl besser separate Windows für die beiden machen. Vielleicht sogar bei mehreren Details auch diese jeweils in ein eigenes Fenster.&lt;br /&gt;&lt;br /&gt;Bei so vielen Fenstern muss ich ja wohl dafür sorgen, dass man per Tastatur hin und her schalten kann! Oho: die keys property eines panels enthält einen KeyMap. Ich kann also eine Aktion "detail" machen und ihr die Tastenkombination Ctrl+Enter zuweisen. Das funktioniert jetzt für DELETE. Super. ExtJS ist cool!&lt;br /&gt;&lt;br /&gt;Jetzt muss ich mir im action framework einen trick ausdenken, um das Detail-Fenster zu öffnen. wahrscheinlich ActionContext.open_window() Und das Layout ist ja jetzt nicht mehr im TabPanel, sondern muss wohl im action handler instanziert werden. Oho, es geht rund...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-5051745636019454774?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/5051745636019454774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/noch-mehr-fenster.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/5051745636019454774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/5051745636019454774'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/noch-mehr-fenster.html' title='Noch mehr Fenster'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-8611350377526721128</id><published>2009-09-25T14:00:00.001+03:00</published><updated>2009-09-25T17:11:54.208+03:00</updated><title type='text'>Working on issue 9.  (with Screenshots)</title><content type='html'>First results of &lt;a href="http://code.google.com/p/lino/issues/detail?id=9" rel="nofollow"&gt;issue 9&lt;/a&gt; are visible: &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lino.googlecode.com/hg/docs/images/screenshots/20090925.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://lino.googlecode.com/hg/docs/images/screenshots/20090925.jpg" width="420" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Remember how it looked two days ago:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lino.googlecode.com/hg/docs/images/screenshots/20090923.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="279" src="http://lino.googlecode.com/hg/docs/images/screenshots/20090923.jpg" width="420" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Todo:&lt;br /&gt;- Scrollbars for the ViewPort and the List panel&lt;br /&gt;- load data to Detail panel&lt;br /&gt;- PagingToolbar on Detail panels.&lt;br /&gt;- Generate html response for index() once and serve it statically.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-8611350377526721128?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/8611350377526721128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/working-on-issue-9-with-screen-shot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/8611350377526721128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/8611350377526721128'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/working-on-issue-9-with-screen-shot.html' title='Working on issue 9.  (with Screenshots)'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-321706044632331383</id><published>2009-09-24T22:11:00.001+03:00</published><updated>2009-09-24T22:12:36.150+03:00</updated><title type='text'>Gedanken zu Ticket  #9</title><content type='html'>I'm working on &lt;a href="http://code.google.com/p/lino/issues/detail?id=9"&gt;issue 9&lt;/a&gt;. Here are some of my thoughts.&lt;br /&gt;&lt;br /&gt;Die neue Klasse extjs.Window scheint der richtige Weg. Ein extjs.Window instanziert einen self.store (den "master data store") und eine Liste von Layouts (self.layouts). Und kennt natürlich seinen self.report. &lt;br /&gt;extjs.Window wird wahrscheinlich im JS nicht nur ein "new Ext.Window" machen, sondern eine user-defined class machen. &lt;a href="http://articles.sitepoint.com/article/oriented-programming-1"&gt;Dieser Artikel hier&lt;/a&gt; &lt;a href="http://code.google.com/p/lino/w/edit/Dieser"&gt;&lt;/a&gt; war gut für mich.&lt;br /&gt;&lt;br /&gt;Ich bin noch nicht sicher was passieren soll, wenn Layout.create_element() eine slave_grid macht. Der dazu gehörige Store muss vielleicht im Window registriert werden.&lt;br /&gt;&lt;br /&gt;Layouts werden nicht mehr in Report, sondern in Window instanziert werden. Und das Fenster, in dem sie stehen (ihren owner) dann alls self.window kennen. Layout braucht dann kein self.report mehr sondern kann stattdessen self.window.report benutzen. &lt;br /&gt;&lt;br /&gt;Also jedes mögliche Fenster einer Anwendung kriegt beim Hochfahren des Servers seine Window-Instanz. Und momentan gibt es erstmal genau ein Window pro MenuItem des Hauptmenüs. &lt;br /&gt;&lt;br /&gt;Wo werden die RowLayouts von slave reports instanziert? &lt;br /&gt;&lt;br /&gt;Und wie soll ich das F11 von TIM implementieren? Also dass man in einem Report eine konfigurierbare Liste von "verwandten" Reports hat, zwischen denen man hin und her schalten kann. Soll dann vielleicht jedesmal ein neues Fenster geöffnet werden? Genau. Das hat hier jezt also nic hts zu sagen. &lt;br /&gt;&lt;br /&gt;Gibt es pro Report ein einziges Window? oder mehrere? Wie soll das Umschalten zwischen Vollbild- und Listenansicht gehen?&lt;br /&gt;&lt;br /&gt;Vielleicht könnte auch die Grid mit ins TabPanel kommen. Also immer nur ein Layout auf einmal sichtbar. Aber ich muss irgendwie dafür sorgen, dass Stores von SlaveGrids nur dann geloaded werden, wenn ihr Grid auch sichtbar ist. Wenn die master grid nicht immer sichtbar ist, müssen die PageLayouts wieder eine PagingToolbar kriegen. Das wird auch jetzt klappen, wo der Store für beide gemeinsam im Window gespeichert ist.&lt;br /&gt;&lt;br /&gt;Viewport wird nur noch für index() benutzt. Das Hauptmenü braucht nicht in den Unterfenstern zu erscheinen, wird also weiterhin nur im Viewport gerendert.&lt;br /&gt;&lt;br /&gt;"/" wird die einzige url sein, die noch mit html antwortet.&lt;br /&gt;"/json" antwortet mit json (so wie JsonStore es verlangt).&lt;br /&gt;"/action" antwortet auch in json, aber nicht für JsonStore, sondern ein Objekt mit den properties success, msg, confirm usw. (mein "action framework")&lt;br /&gt;&lt;br /&gt;Sollen mehrere Fenster sich einen Store teilen können? Ich glaube nicht.&lt;br /&gt;&lt;br /&gt;Der ganze Code aus menus.py kann übrigens bei Gelegnehit (in konvertierter Form) nach extjs.py rüber. MenuItem und Menu wären dann Unterklassen von extjs.Components. Das wäre eleganter. Ist aber nicht dringend.&lt;br /&gt;&lt;br /&gt;Wenn ich alles Javascript statisch (d.h. unabhängig vom request) generieren will, müssen die Zugrifffsberechtigungen im Javascript geprüft werden. Das wird noch lustig.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-321706044632331383?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/321706044632331383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/im-working-on-issue-9.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/321706044632331383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/321706044632331383'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/im-working-on-issue-9.html' title='Gedanken zu Ticket  #9'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-6746035997880825963</id><published>2009-09-23T18:00:00.001+03:00</published><updated>2009-09-23T18:07:57.424+03:00</updated><title type='text'>jaama.dyndns.org has done her work</title><content type='html'>Oops, the new igen demo server announced &lt;a href="http://lsaffre.blogspot.com/2009/09/new-igen-demo-server-is-online.html"&gt;2 days ago&lt;/a&gt; was never visible to the outside world. I noticed it yesterday when Gerd tried it. And today, with Dirk's help, I found the probable reason: Elion (my internet provider) blocks these requests. Understandable: they want to be able to sell me more service for more money. I tried with port 1234 and 8080 instead of the well-known 80, but this also doesn't work.&lt;br /&gt;&lt;br /&gt;That's not a problem because I've seen what I needed to see: even on a quick server and inside a LAN, the igen application looks too slow. I opened &lt;a href="http://code.google.com/p/lino/issues/detail?id=9"&gt;issue 9&lt;/a&gt; and will probably a few intensive days on this.&lt;br /&gt;&lt;br /&gt;Updated the old demo site &lt;a href="http://igen.saffre-rumma.ee/"&gt;igen.saffre-rumma.ee&lt;/a&gt; where you can admire actions mostly working.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-6746035997880825963?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/6746035997880825963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/jaamadyndnsorg-has-done-her-work.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/6746035997880825963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/6746035997880825963'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/jaamadyndnsorg-has-done-her-work.html' title='jaama.dyndns.org has done her work'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-5314067410731130629</id><published>2009-09-21T17:15:00.001+03:00</published><updated>2009-09-21T21:06:14.421+03:00</updated><title type='text'>New igen demo server is online</title><content type='html'>The new igen demo server is online: &lt;a href="http://jaama.dyndns.org/"&gt;http://jaama.dyndns.org&lt;/a&gt;&lt;br /&gt;Note that this machine won't be always up and running, so if you get no response on that address, then try again later or send me a mail, asking to switch it on.&lt;br /&gt;&lt;br /&gt;I also started a Wiki entry about &lt;a href="http://code.google.com/p/lino/wiki/HowToInstall"&gt;Installation&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-5314067410731130629?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/5314067410731130629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/new-igen-demo-server-is-online.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/5314067410731130629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/5314067410731130629'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/new-igen-demo-server-is-online.html' title='New igen demo server is online'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-1874480585985841427</id><published>2009-09-21T14:06:00.000+03:00</published><updated>2009-09-21T14:06:12.960+03:00</updated><title type='text'>Preparing a new igen demo server</title><content type='html'>I'd like to see igen's performance on a normal Web server. I have a Debian machine here, called Jaama, waiting for this job. The router of my local LAN has a built-in DynDNS client, so I just needed to create a free host account at &lt;a href="http://www.dyndns.com/"&gt;dyndns.com&lt;/a&gt; to get a name for my dynamic IP address. &lt;br /&gt;&lt;br /&gt;The only problem is: how to let the router know that it should forward HTTP requests to Jaama?&lt;br /&gt;&lt;br /&gt;Jaama was also configured as a DHCP client. &lt;br /&gt;&lt;br /&gt;File /etc/networking/interfaces, change the line &lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;iface eth1 inet dhcp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;into&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;iface eth1 inet static&lt;br /&gt;&amp;nbsp; address 192.168.1.100&lt;br /&gt;&amp;nbsp; netmask 255.255.255.0&lt;br /&gt;&amp;nbsp; network 192.168.1.0&lt;br /&gt;&amp;nbsp; broadcast 192.168.1.255&lt;br /&gt;&amp;nbsp; gateway 192.168.1.254&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; dns-nameservers 194.126.115.18, 194.126.101.34&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Result: Jaama's apache2 is now responding on &lt;a href="http://jaama.dyndns.org/"&gt;http://jaama.dyndns.org/&lt;/a&gt;&lt;br /&gt;Todo: install Lino on Jaama.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Web pages that helped me:&lt;br /&gt;&lt;a href="http://wiki.debian.org/NetworkConfiguration"&gt;http://wiki.debian.org/NetworkConfiguration&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cyberciti.biz/tips/howto-ubuntu-linux-convert-dhcp-network-configuration-to-static-ip-configuration.html"&gt;http://www.cyberciti.biz/tips/howto-ubuntu-linux-convert-dhcp-network-configuration-to-static-ip-configuration.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-1874480585985841427?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/1874480585985841427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/preparing-new-igen-demo-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1874480585985841427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1874480585985841427'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/preparing-new-igen-demo-server.html' title='Preparing a new igen demo server'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-2676203405552353328</id><published>2009-09-16T22:11:00.000+03:00</published><updated>2009-09-16T22:11:31.003+03:00</updated><title type='text'>Grid now editable</title><content type='html'>It is now possible to edit data using the Grid. Double-click on a cell to edit it. ForeignKey columns have a combobox. These were quite some hours of work, with some avalanches of internal changes.&lt;br /&gt;&lt;br /&gt;To do next:&lt;br /&gt;- make it possible to add rows&lt;br /&gt;- add action buttons e.g. (DocumentsToSend.sign and SalesDocument.print)&lt;br /&gt;- enhance performance &lt;br /&gt;&lt;br /&gt;- layout problems&lt;br /&gt;- make use of Ext.Windows rather than a Viewport?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-2676203405552353328?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/2676203405552353328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/grid-now-editable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/2676203405552353328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/2676203405552353328'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/grid-now-editable.html' title='Grid now editable'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-3027558041022793371</id><published>2009-09-07T12:25:00.000+03:00</published><updated>2009-09-07T12:25:27.683+03:00</updated><title type='text'>Tuning the grid's columns</title><content type='html'>The ColumnModels and Stores generated by Lino had just plain fields so far, relying on the automatic formatting. Now I started to work on this.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;BooleanColumn now uses new attribute Report.boolean_texts&lt;/li&gt;&lt;li&gt; DateColumn now uses new attribute Report.date_format&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/li&gt;&lt;li&gt; Numeric columns are now displayed right-aligned&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;li&gt;MethodElement now displays correctly using the method's 'return_type' attribute&lt;/li&gt;&lt;/ol&gt;The 'return_type' attribute of a Model's method (which was called 'field' so far, but I thought that it deserves a more complicated name). Is used to specify at model level how a method's return value is to be displayed. Example is sales.SalesDocument.total_incl()&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-3027558041022793371?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/3027558041022793371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/tuning-grids-columns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/3027558041022793371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/3027558041022793371'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/tuning-grids-columns.html' title='Tuning the grid&apos;s columns'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-1006940839189562477</id><published>2009-09-06T00:34:00.001+03:00</published><updated>2009-09-06T00:37:18.601+03:00</updated><title type='text'>Layout tuning</title><content type='html'>Today (or rather yesterday) I worked less than 2 hours on &lt;a href="http://code.google.com/p/lino/"&gt;Lino&lt;/a&gt; :&lt;br /&gt;&lt;br /&gt;1) Activated autoLoad for ForeignKey Store. This increases the server load, but at least it gives a more pleasant impression for people who have a look at &lt;a href="http://igen.saffre-rumma.ee%20/"&gt;igen&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2) &lt;a href="http://igen.saffre-rumma.ee/"&gt;http://igen.saffre-rumma.ee&lt;/a&gt;&amp;nbsp; is, by the way, currently so slow that you may get timeouts. In this case just reload.&lt;br /&gt;&lt;br /&gt;3) Solved: The "Emitted Invoices" tab of an Order (&lt;a href="http://127.0.0.1:8000/r/OrdersByJournal?master=ORD"&gt;http://127.0.0.1:8000/r/OrdersByJournal?master=ORD&lt;/a&gt;) did not show the list of emitted invoices. It even had a traceback at the beginning, which I changed into a warning "invoice_set : 'RelatedManager' object is not callable", then modified the PageLayout to solve the problem.&lt;br /&gt;&lt;br /&gt;4)  The Detail panel in Configuration / Accounts (&lt;a href="http://127.0.0.1:8000/r/Accounts"&gt;http://127.0.0.1:8000/r/Accounts&lt;/a&gt;) was too small. This was because it uses the default PageLayout, so there was no Element with a width specified. There was also a warning "Could not compute width for PageLayout ledger.PageLayout" printed at the server console. A quick solution would have been to write a PageLayout for the Accounts report, but I want default PageLayouts also get rendered reasonably. But &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Element.width&lt;/span&gt; contains the manually specified width. It is important that this value remains None to indicate this fact, even when it might be computed (e.g. deducing it from the container's width). Remember also that widths specified in Layouts and Reports use always "characters" as unit.So I introduced a new attribute &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Element.preferred_width&lt;/span&gt; which is used at certain places when &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Element.width&lt;/span&gt; is None.&lt;br /&gt;&lt;br /&gt;5) todo: after change (4), Detail panel of a Contact is no longer rendered correctly: the display width of text fields with max_length over 15 should get expanded so that they fill up their container's width.&lt;br /&gt;&lt;br /&gt;6) todo: BooleanFieldElement has now a get_column_options() wich sets xtype='booleancolumn', but this doesn't have any effect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-1006940839189562477?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/1006940839189562477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/work-report.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1006940839189562477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1006940839189562477'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/work-report.html' title='Layout tuning'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-2962686661784088129</id><published>2009-09-05T00:12:00.003+03:00</published><updated>2009-09-05T01:07:30.019+03:00</updated><title type='text'>Ext.form.ComboBox show value instead of displayField</title><content type='html'>ComboBoxes in a Ext.FormPanel sometimes show their value (and not their display_field) after load().&lt;br /&gt;&lt;br /&gt;Here is an example (which may change in the future, and if it works it requires you to log in using username "root" and password "1234"):&lt;br /&gt;&lt;a href="http://igen.saffre-rumma.ee/r/InvoicesByJournal?master=INV%20"&gt;http://igen.saffre-rumma.ee/r/InvoicesByJournal?master=INV &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.form.ComboBox"&gt;ExtJS documentation&lt;/a&gt; says "A ComboBox works in a similar manner to a traditional HTML select field. The difference is that to submit the &lt;a ext:cls="Ext.form.ComboBox" ext:member="valueField" href="http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-valueField"&gt;valueField&lt;/a&gt;, you must specify a &lt;a ext:cls="Ext.form.ComboBox" ext:member="hiddenName" href="http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-hiddenName"&gt;hiddenName&lt;/a&gt; to create a hidden input field to hold the value of the valueField. The &lt;i&gt;&lt;a ext:cls="Ext.form.ComboBox" ext:member="displayField" href="http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-displayField"&gt;displayField&lt;/a&gt;&lt;/i&gt; is shown in the text field which is named according to the &lt;a ext:cls="Ext.form.ComboBox" ext:member="name" href="http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-name"&gt;name&lt;/a&gt;."&lt;br /&gt;&lt;br /&gt;In an Invoice entry form I have a ComboBox field to select the customer for this invoice. Configuration options of this field:&lt;br /&gt;&lt;br /&gt;name: customer&lt;br /&gt;hiddenName: customerHidden&lt;br /&gt;valueField: id&lt;br /&gt;store: a JsonStore on Customer table with fields:['id','__unicode__']&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;BasicForm.load() gets the following JSON response:&lt;br /&gt;&lt;br /&gt;&lt;div class="netInfoResponseText netInfoText " selected="true"&gt;&lt;pre&gt;&lt;code&gt;{"count": 6, "rows": [ {&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;  "total_incl": "59.85",&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;&lt;code&gt;&amp;nbsp; "customerHidden"&lt;/code&gt;&lt;code&gt;: 100,&amp;nbsp;&lt;/code&gt;&lt;/div&gt;&lt;div class="netInfoResponseText netInfoText " selected="true"&gt;&lt;code&gt;&amp;nbsp; "customer": "Mets ja Puu O\u00dc",&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;  (...)&lt;/code&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;}]}&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;And the ComboBox then shows "100", not "Mets ja Puu OÜ".&lt;br /&gt;When I then trigger the selection list, it contains correctly all customers, and is positioned on "Mets ja Puu".&lt;br /&gt;Note that triggering&amp;nbsp; the selection list has loaded the choices store.&lt;br /&gt;Once the store is loaded, customer names are displayed correctly, also when I page to other invoices.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This shows that BasicForm.load() ignores the &lt;code&gt;"customer" &lt;/code&gt;data, it only reads customerHidden and then asks its store each time.&lt;br /&gt;&lt;br /&gt;It would be nice if it did, because then we would gain performance in the situation where a user just skips through invoices, wanting to see the customer names but never triggering the combobox.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-2962686661784088129?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/2962686661784088129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/extformcombobox-show-value-instead-of.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/2962686661784088129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/2962686661784088129'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/extformcombobox-show-value-instead-of.html' title='Ext.form.ComboBox show value instead of displayField'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1971774800846849097.post-1758083242534464284</id><published>2009-09-04T21:41:00.000+03:00</published><updated>2009-09-04T22:25:26.281+03:00</updated><title type='text'>Splitting TIM-Tools away from Lino</title><content type='html'>The statement "Lino is the common code repository for two relatively non-related projects" can soon go away. I created a new project "timtools" on Google code, then made a clone of Lino ("hg clone lino timtools"), removed a bunch of files from my timtools working copy, did "hg ci", and now am trying to push it back to Google. But since it is a big push, I'm getting:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;T:\hgwork\timtools&gt;hg push timtools&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;pushing to https://luc.saffre:***@timtools.googlecode.com/hg&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;searching for changes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;abort: error: Software caused connection abort&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This reminds me issue &lt;a href="http://code.google.com/p/support/issues/detail?id=2716"&gt;2716&lt;/a&gt; which I had when I converted Lino to google.code. Only that now it is not "broken pipe". But let's try a manual version of the solution proposed by &lt;span class="author"&gt;by  &lt;a style="white-space: nowrap;" href="http://code.google.com/u/qian.qiao/"&gt;qian.qiao&lt;/a&gt;&lt;/span&gt;,  &lt;span class="date" title="Sun Jun 14 00:35:58 2009"&gt;Jun 14, 2009:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;T:\hgwork\timtools&gt;hg push -r 10 timtools&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;pushing to https://luc.saffre:***@timtools.googlecode.com/hg&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;searching for changes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;... and after about 10 minutes it says "Success.", so Issue 2716 can also appear with "abort: error: Software caused connection abort" instead of "Broken pipe".&lt;br /&gt;&lt;br /&gt;Now since I am on Windows, I created a file "push.bat" with one line:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;for /L %%i in (50,10,780) do hg push -r %%i timtools&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The file is now running:&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;&lt;br /&gt;T:\hgwork\timtools&gt;hg push -r 50 timtools&lt;br /&gt;pushing to https://luc.saffre:***@timtools.googlecode.com/hg&lt;br /&gt;searching for changes&lt;br /&gt;no changes found&lt;br /&gt;&lt;br /&gt;T:\hgwork\timtools&gt;hg push -r 60 timtools&lt;br /&gt;pushing to https://luc.saffre:***@timtools.googlecode.com/hg&lt;br /&gt;searching for changes&lt;br /&gt;Success.&lt;br /&gt;&lt;br /&gt;T:\hgwork\timtools&gt;hg push -r 70 timtools&lt;br /&gt;pushing to https://luc.saffre:***@timtools.googlecode.com/hg&lt;br /&gt;searching for changes&lt;br /&gt;Success.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Very well. I can now continue on Lino while this is running.&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1971774800846849097-1758083242534464284?l=lsaffre.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lsaffre.blogspot.com/feeds/1758083242534464284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://lsaffre.blogspot.com/2009/09/splitting-tim-tools-away-from-lino.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1758083242534464284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1971774800846849097/posts/default/1758083242534464284'/><link rel='alternate' type='text/html' href='http://lsaffre.blogspot.com/2009/09/splitting-tim-tools-away-from-lino.html' title='Splitting TIM-Tools away from Lino'/><author><name>Luc Saffre</name><uri>http://www.blogger.com/profile/16598440820544071679</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_zt7B6VI3Ah4/SqTYgJ3AK0I/AAAAAAAAAeY/6497tOYF28o/S220/ich20070916.jpg'/></author><thr:total>0</thr:total></entry></feed>
