2007年12月18日

I’v finished a plugin, called Canvas Test, and the functionality is simple now, and the mainly idea is that I want to learn graphic drawing, and want to test some API easily, so I developed this plugin, and you can write graphic drawing code directly, and then see the result.

You can see the screen shots at http://www.haokanbu.com/story/4522/

The steps are:

  1. Update the lastest code from svn
  2. Check casvas_test_plugin and restart UliPad
  3. Run [Tool]->[Canvas Test]
  4. In Canvas Test window, write down graphic API. You’ll see there already has two lines:

    import wx
    dc = wx.PaintDC(self)

    these lines are used to enable code completion support.

  5. Write down your code after dc = wx.PaintDC(self)
  6. Then click the refresh button

Hope you like it.

2007年12月15日

这几天看到Cody Precord(他是editra编辑器的作者)在wxPython邮件列表发布了一个PlatButton的控件。我下载看了一下,还是挺不错的。结果引来不少人的评论,其中Robin Dunn发现了不少建议,其中谈到如何写一个wxPython的控件,其中谈到了几个需要遵守的原则:

1. Derive from wx.PyControl. This enables reflection of some pertinent C++ virtual methods to Python methods in the derived class.(从wx.PyControl派生)

2. Call SetInitialSize from the __init__ method, passing the size passed to __init__. This helps set things up properly for sizers, and also sets the size of the control appropriately (using either the size given or the best size.)(在__init__方法中调用SetInitialSize方法)

3. Call InheritAttributes from the __init__ method. If the parent has non-standard font or colors then it will set them for your control.(在__init__方法中调用InheritAttributes)

4. Implement a DoGetBestSize method, returning the wx.Size that would best fit your control based on current font, label or other content, etc.(实现DoGetBestSize方法)

5. Implement an AcceptsFocus method, returning True if the control is meant to receive the keyboard focus.(实现AcceptsFocus方法)

特别是Robin Dunn还给出了他在2004年的PyCon大会上的一个发言。挺不错的,可以看一看。

其实在UliPad中我也实现过一个类似的控件,可以有弹出菜单等功能,有兴趣可以看一看,不过功能可能没有这个丰富。

2007年12月12日

It’s a bug fix version:

  1. Remove profile invoke(big mistake)
  2. Fix svn plugin checkout bug

UliPad has been ported to code.google.com, so you can visit the new project site at: http://code.google.com/p/ulipad, and also visit the new svn address. Recommends using source version.

Source Code: http://ulipad.googlecode.com/files/ulipad.3.8.1.zip
Win Execute Code: http://ulipad.googlecode.com/files/ulipad.3.8.1.exe

If you have any suggestion or question, please subscribe the ulipad
mailling list: http://groups.google.com/group/UliPad

2007年12月06日

What’s new in 3.8

New Features and Changes:

  1. Add mako template syntax highlight support
  2. Add new option in preference, [Python]->Automatically save modified file when running Python program, if it’s checked, it’ll automatically save the modified file.
  3. Add Shift+Delete => Cut, Shift+Insert => Paste
  4. Upgrade winpdb to lastest version
  5. Now you can set pythonpath option in config.ini/[default], and UliPad will insert it into the sys.path. pythonpath can be a string or a string list of directory.
  6. Svn support, you should install pysvn first, and also support proxy.
  7. Change long line indicator default is true.
  8. Add doctest support, you can run the doctest of current document in UliPad
  9. Add time stamp info in debug and error file
  10. Replace the shell window popup menu, and add Copy Without Prompts and Paste and Run menu items. And if the result cann’t be convert to unicode, then display the result as repr().
  11. Script Manager can find menu name from the script content, you can define it as a comment line, format is: #s*name:(.*)$
  12. Add Run in Shell menu item in Editor context menu
  13. Add script and shell key binding. Change Shell to External Tool
  14. Change Find in Files dialog to panel
  15. Using meide module to create Preference dialog
  16. Add an option to control if show the docstring in class browser window.
  17. Don’t create a tmp file again, directly save the file
  18. Improve Find in Files process with thread
  19. Add some config.ini options support in Preference Dialog
  20. Refactor Find & Replace with pane, but not dialog
  21. Made Open Command Here work in Linux
  22. Add dropfile plugin. thanks Tyberius Prime. Now you can drop files on toolbar, then UliPad will open it. Just like drop files on Directory Browser window.
  23. Add new custom lexer class and refactor related lexer process
  24. Upgrade FlatNotebook.py to lastest version, thanks to swordsp
  25. Improve default identifiers process, add type judgement
  26. Add pylint plugin

Bug fix:

  1. Fix print bug, add print line number functionality
  2. Fix snippet template indent bug(when using tab mode, the ‘t’ in template will be replaced with spaces). And you can press Alt+Q to cancel current snippet.
  3. Fix press Ctrl+B jump position is not correct bug.
  4. Fix that when you change the file type, the icon in directory and dynamic menu don’t change bug
  5. Fix line number margin width, and find back End-of-line Marker menu
  6. Fix adding empty directory error
  7. Fix open un-exists file will popup two message dialog bug
  8. Fix line end mix checking bug also including twice prompt dialog bug
  9. Fix webbrowser bug. Thanks Tom Eubank
  10. Fix message console postion bug, thanks for swordsp

UliPad has been ported to code.google.com, so you can visit the new project site at: http://code.google.com/p/ulipad, and also visit the new svn address. Recommends using source version.

Source Code: http://ulipad.googlecode.com/files/ulipad.3.8.zip
Win Execute Code: http://ulipad.googlecode.com/files/ulipad.3.8.exe

If you have any suggestion or question, please subscribe the ulipad

mailling list: http://groups.google.com/group/UliPad

Update: 2007/12/12 Please use 3.8.1 version

2007年09月24日

I’v written an article about how to use layout, and you can find it at here.

And I also made a Source code and Screenshots gallery wiki page, so you can share your UI source code and screenshot with others. You can visit the page here.

For now, there is a simplest example:

And the code is:

#You can create a gallery folder under meide project so that sys.path.insert(0, ‘..’) can find the meide module.

import wx
import sys

sys.path.insert(0, ‘..’)

class wxApp(wx.App):
    def OnInit(self):
        return True

class Frame(wx.Frame):
    def __init__(self):
        super(Frame, self).__init__(None, -1)
        self.init()
       
    def init(self):
        import meide as ui
       
        self.box = box = ui.VBox()
        box.add(ui.Button(‘Hello’), flag=wx.ALIGN_CENTER)
       
        ui.create(self, box, fit=2)
       
if __name__ == ‘__main__’:
    wxApp = wxApp(0)
    frame = Frame()
    frame.Show()
    wxApp.SetTopWindow(frame)
    wxApp.MainLoop()

2007年09月21日

I’v finished the refactor of Find & Replace Dialog, now Find and
Replace is a panel and will appear at the bottom of document area. The
key binding is not changed. Hope you like it.

You can open it just press Ctrl+F(Find) or Ctrl+H(Find and Replace),
you should know the shortcuts will be enabled only when the focus is
in a document. And you can swith between Find and Find & Replace, just
click the Open Replcae image button which is next to Close image
button.

2007年09月18日

I’v created a project db-dump on code.google.com, you can visit it at: http://code.google.com/p/db-dump/

And db_dump.py is used for dump and restore database of django. And it can also support some simple situations for Model changes, so it can also be used in importing data after the migration of Model.

So if you like it or want to try it, you can download it from http://db-dump.googlecode.com/files/db_dump2.1.zip

And if you have any idea about it just write a issue or send me an email, I’ll try my best to change it.

If you want to run it, just extract it to project directory, you should put it with the settings.py together, and run it according to the document of the project site.

2007年09月17日

meide supports two kinds of creation fashions. One way I called "Lazy Creation", that means you create a layout first, and don’t create the underlying wx widgets, till you invoke module function create() method. At this time, all the real underlying wx widgets will be created. For example:

 import meide as ui
    
 self.box = box = ui.VBox()
 btn = box.add(ui.Button(‘Hello’), flag=wx.ALIGN_CENTER|wx.ALL)
 btn.bind(‘click’, self.OnClickHello)

 ui.create(self, box, fit=2)

For lazy creation, event binding also be lazy creation.

The other way I called "Immediately Creation", that means you create a wrap layout object then invoke its create() method, then the underlying wx sizer object will be created. Then you add other element, but this time the underlying element will be also created immediately, so you don’t need to invoke module function create() any more. For example:

import meide as ui

self.box = box = ui.VBox().create(self).auto_layout()
btn = box.add(ui.Button(‘Hello’), flag=wx.ALIGN_CENTER|wx.ALL)
btn.bind(‘click’, self.OnClickHello)
box.auto_fit(2)

This time the event binding is also immediately. The create(win) method of a layout object only create the underlying wx widgets, so if you want to set the sizer to the window object and set auto layout you can invoke auto_layout() method. And at the end of creation, you may want to invoke auto_fit(fit) to resize the window.

Below is recently updates since (08/28):

  1. Add script and shell commands shortcut binding. For scripts you can bind shortcuts from Ctrl+0 to Ctrl+9, and for shell commands you can bind shortcuts from Alt+0 to Alt+9.
  2. Update pyflakes module to trunk version
  3. Change Find in Files Dialog to Panel, and using thread to do the process, it’s a big change I think
  4. Improve preference dialog creation with meide module
  5. Add a new option to control whether showing the docstring when you navigating in class browser window
  6. If save file failed, then invoke save as, and don’t create a tmp first, but save the file directly

Bugs fix:

  1. Fix adding empty directory to directory browser window bug
  2. Fix open un-exists file will popup two message dialog bug
  3. Fix directory browser refresh bug
  4. Fix directory browser insert node bug
  5. Fix shortcuts from 1-based bug
2007年09月08日

Here is a dialog code which I want to get a filename:

import wx

class MyFileEntry(wx.Dialog):    def __init__(self, parent, title, message, defaultvalue):        wx.Dialog.__init__(self, parent, -1, style = wx.DEFAULT_DIALOG_STYLE, title = title)

        box = wx.BoxSizer(wx.VERTICAL)        stext = wx.StaticText(self, -1, label=message)        box.Add(stext, 0, wx.ALIGN_LEFT|wx.ALL, 5)        box1 = wx.BoxSizer(wx.HORIZONTAL)        self.text = wx.TextCtrl(self, -1, defaultvalue)        self.text.SetSelection(-1, -1)        box1.Add(self.text, 1, wx.EXPAND|wx.ALL, 5)        self.ID_BROWSER = wx.NewId()        self.btnBrowser = wx.Button(self, self.ID_BROWSER, tr("Browser"), size=(50, -1))        box1.Add(self.btnBrowser, 0, wx.ALL, 5)        box.Add(box1, 1, wx.EXPAND, 5)        box2 = wx.BoxSizer(wx.HORIZONTAL)        btnOK = wx.Button(self, wx.ID_OK, tr("OK"))        btnOK.SetDefault()        box2.Add(btnOK, 0, wx.ALIGN_RIGHT|wx.RIGHT, 5)        btnCancel = wx.Button(self, wx.ID_CANCEL, tr("Cancel"))        box2.Add(btnCancel, 0, wx.ALIGN_LEFT|wx.LEFT, 5)        box.Add(box2, 0, wx.ALIGN_CENTER|wx.BOTTOM, 5)

        wx.EVT_BUTTON(self.btnBrowser, self.ID_BROWSER, self.OnBrowser)

        self.SetSizer(box)        self.SetAutoLayout(True)        box.Fit(self)

        self.value = defaultvalue

    def GetValue(self):        return self.text.GetValue()

    def OnBrowser(self, event):        dlg = wx.FileDialog(self, tr("Select A File"), "", "", tr("All file (*.*)|*.*"), wx.OPEN|wx.HIDE_READONLY)        if dlg.ShowModal() == wx.ID_OK:            filename = dlg.GetPath()            self.text.SetValue('%s' % filename)

Even if the code is very simple, but the code is very tedious. And now I change it with meide:

import meide as ui

class MyFileEntry(ui.SimpleDialog):    def __init__(self, parent, title, message, defaultvalue, fit=1):        box = ui.SimpleGrid()        box.add(message, ui.OpenFile(defaultvalue), name='filename')        super(MyFileEntry, self).__init__(parent, box, title, fit=fit, size=(400, -1))

    def GetValue(self):        return self.layout.GetValue()['filename']

The MyFileEntry inherits from SimpleDialog, so it’ll automatically create a Ok and Cancel buttons for you.