Hello Ed,

is great - it's the first useful python app. for windows CE that I've seen - awesome. MANY MANY thanks for your work.

It's been such a pain coding with pocket notepad !
I've noticed the problem with selection as well - I guess it's a problem with the WinCE port of Tk. The best you can do is fix the keybindings to the cursor keys, so that selection can be done with the shift-arrow keys. Maybe even implement ctrl-something-or-other to select a block at a time !


Anyway - I have a bit of a wish list for IdleCE. *Mainly* related to key bindings, but not entirely. If you could bear these in mind, I would be personally very grateful.

In order of importance :

max 1 edit and file menu open at a time
key bindings to ctrl-c, ctr-x, ctrl-a, ctrl-v, ctrl-s (copy, cut, select all, paste, save)
Also shift-<arrow keys> for selection


tab for indenting selected area
ctrl-[ and ctrl-] for indenting/unindenting selected area

tab is four spaces rather than tab
(and/or a spaces to tabs/tabs to spaces option)

comment in/comment out areas - with key bindings


As I said though... I already use IdleCE and am grateful for your work. Do you want this put online somewhere ? Contact me off-list if you do.


Regards,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml



Ed Blake wrote:

I've managed to get popup menus that work.  Highlight some text, tap the
selection and a menu will appear.  It is equivalent to the edit menu/window
but seems to work better for cut/copy.  I have a problem with this though on
my own device (HP Ipaq, WinCE 2003).  When I try to highlight text the
selection flickers and changes, like the selection is being made over and
over.  If anyone can figure out what causes this I would be interested in
hearing about it.

RE the license:  I think the example code I based most of this app on was
released GPL so unless I can track down the example again and verify its
license...  I suppose if I verify that the example was other than GPL I
should use the python license as that is the license used on IDLE.

------------------------------------------------------------------------

#IdleCE

import sys
sys.path.append('\\Program Files\\Python\\lib\\Python23.zip\\lib-tk')
import sys
import os
import re
from Tkinter import *
import tkMessageBox
import tkFileDialog

import keyword
from string import ascii_letters, digits, punctuation

OS = os.name.lower() #Should be 'ce' on WinCE

class idle:
"""The base class for the mini idle."""
def __init__(self,root):
self.root = root
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
frame = Frame(root)
frame.grid(row=0,column=0,sticky=N+W)
btn = Button(frame,text="file",command=self.file_dialog)
btn.pack(side=LEFT)
btn = Button(frame,text="edit",command=self.edit_dialog)
btn.pack(side=LEFT)
btn = Button(frame,text="about",command=self.about_dialog)
btn.pack(side=LEFT)
self.editor = SyntaxHighlightingText(root)
self.editor.grid(row=1,column=0,columnspan=2,sticky=N+S)
panbar = Scrollbar(root,orient=HORIZONTAL)
panbar.grid(row=2,column=0,columnspan=2,sticky=E+W)
scrollbar = Scrollbar(root)
scrollbar.grid(row=1,column=2,sticky=N+S)
self.editor.configure(xscrollcommand=panbar.set)
self.editor.configure(yscrollcommand=scrollbar.set)
scrollbar.config(command=self.editor.yview)
panbar.config(command=self.editor.xview)


       self.root.protocol("WM_DELETE_WINDOW", self.exit)

   def file_dialog(self):
       """Used instead of a menu since menus don't work on WinCE."""
       top = Toplevel(padx=20)
       top.title("file")
       top.resizable(0,0)
       top.focus_set()

       btn_task = Button(top, text="New",command=self.new)
       btn_task.pack(fill=X)

       btn_task = Button(top, text="Open",command=self.open)
       btn_task.pack(fill=X)

btn_task = Button(top, text="Save",command=self.save)
btn_task.pack(fill=X)
btn_task = Button(top, text="Save As",command=self.saveas)
btn_task.pack(fill=X)


       btn = Button(top, text="Exit", command=self.exit)
       btn.pack(fill=X)

   def edit_dialog(self):
       """These buttons all work on the desktop, but don't seem to work right
on WinCE.  Luckly copy and paste are accessable via mouse clicks."""
       top = Toplevel(padx=20)
       top.title("edit")
       top.resizable(0,0)
       top.focus_set()

       btn_undo = Button(top, text="Undo",command=self.editor.edit_undo)
       btn_undo.pack(fill=X)

       btn_redo = Button(top, text="Redo",command=self.editor.edit_redo)
       btn_redo.pack(fill=X)

       btn_task = Button(top, text="Cut",command=self.editor.cut)
       btn_task.pack(fill=X)

       btn_task = Button(top, text="Copy",command=self.editor.copy)
       btn_task.pack(fill=X)

       btn_task = Button(top, text="Paste",command=self.editor.paste)
       btn_task.pack(fill=X)

       btn = Button(top, text="Dismiss", command=top.destroy)
       btn.pack(fill=X)

   def about_dialog(self):
       """Sillyness"""
       top = Toplevel()
       top.title("about")
       top.resizable(0,0)
       top.focus_set()

       about = """

       IdleCE v0.6

   A miniaturized imitation of
   the python ide: idle.

   This software is distibuted
   under the Gnu-GPL. Please Visit
   http://www.gnu.org/licenses/gpl.txt
   to see the license.
       """
       info = Label(top,text=about)
       info.pack(side=TOP,padx=6)

       button = Button(top, text="Dismiss", command=top.destroy)
       button.pack(side=BOTTOM,fill=X)

   def open(self):
       # Opens a file and colorizes it
       self.filename = tkFileDialog.askopenfilename()
       if OS == 'ce': # Just passing filename fails...
           self.filename = self.filename.replace('/','\\')
       try:
           file = open(self.filename)
           self.editor.delete("1.0",END)
           text = file.readlines()
           file.close()
           for i in range(len(text)-1):
               self.editor.insert(END,text[i])
               self.editor.colorize(i+1,len(text[i])) 
#colorize(textline,lastcolumn)
           self.editor.see("1.0")
       except IOError:
           print self.filename

   def saveas(self):
       # Called if no filename is set or Saveas is picked
       self.filename = tkFileDialog.asksaveasfilename()
       if OS == 'ce':
           self.filename = self.filename.replace('/','\\')
       try:
           file = open(self.filename,'w')
           text = self.editor.get("1.0",END)
           file.write(text)
           file.flush()
           file.close()
       except Exception, info:
           tkMessageBox.showerror('Exception!',info)

   def save(self):
       try:
           file = open(self.filename,'w')
           text = self.editor.get("1.0",END)
           file.write(text)
           file.flush()
           file.close()
       except:
           self.saveas() # If no file has been accessed

   def new(self):
       if len(self.editor.get("1.0",END)) >= 2:
           if tkMessageBox.askokcancel("New File","Discard current file?"):
               self.editor.delete("1.0",END)
               self.filename = ""
       else:
           self.editor.delete("1.0",END)
           self.filename = ""

def exit(self):
# End the program firmly.
root.destroy()
root.quit()
class SyntaxHighlightingText(Text):
"""A syntax highlighting text widget from the web customized with
some methods from Idle and some special methods."""
tags = {'com':'#C00', #comment
'str':'#0A0', #string
'kw': 'orange', #keyword
'obj':'#00F', #function/class name
'int': 'blue' #integers
}


   def __init__(self, root):
       if OS == 'ce':
           w = 40
           h = 10
       else:
           w = 80
           h = 25
       
Text.__init__(self,root,wrap=NONE,bd=0,width=w,height=h,undo=1,maxundo=50)
       # Non-wrapping, no border, undo turned on, max undo 50
       self.text = self # For the methods taken from IDLE
       self.root = root
       self.config_tags()
       self.characters = ascii_letters + digits + punctuation
       self.tabwidth = 8    # for IDLE use, must remain 8 until Tk is fixed
       self.indentwidth = 4 # Should perhaps be 2 due to the small screen??
       self.indention = 0   # The current indention level
       self.set_tabwidth(self.indentwidth) # IDLE...

       # create a popup menu
       self.menu = Menu(root, tearoff=0)
       self.menu.add_command(label="Undo", command=self.edit_undo)
       self.menu.add_command(label="Redo", command=self.edit_redo)
       #self.menu.add_command(type="separator")
       self.menu.add_command(label="Cut", command=self.cut)
       self.menu.add_command(label="Copy", command=self.copy)
       self.menu.add_command(label="Paste", command=self.paste)

       self.bind('<Key>', self.key_press)      # For scanning input
       self.bind('<Return>',self.autoindent)   # Overides default binding
       self.bind('<Tab>',self.autoindent)      # increments self.indention
       self.bind('<BackSpace>',self.autoindent)# decrements self.indention
       self.bind('<Double-Button-1>',self.paste)# decrements self.indention
       self.tag_bind(SEL,'<Button-1>',self.popup)

   def popup(self, event):
       """Edit popup menu with a special attribute for cut and copy."""
       Selection=self.get_selection_indices()
       if len(Selection)>0:
           SelectedText = self.get(Selection[0],Selection[1])
       self.sel_store = list(Selection)
       self.sel_store.extend([SelectedText])
       self.menu.post(event.x_root, event.y_root)

def get_tabwidth(self):
# From IDLE
current = self['tabs'] or 5000
return int(current)
def set_tabwidth(self, newtabwidth):
# From IDLE
text = self
if self.get_tabwidth() != newtabwidth:
pixels = text.tk.call("font", "measure", text["font"],
"-displayof", text.master,
"n" * newtabwidth)
text.configure(tabs=pixels)
def config_tags(self):
# Sets up the tags and their colors
for tag, val in self.tags.items():
self.tag_config(tag, foreground=val)


   def remove_tags(self, start, end):
       for tag in self.tags.keys():
           self.tag_remove(tag, start, end)

   def get_selection_indices(self):
        # If a selection is defined in the text widget, return (start,
       # end) as Tkinter text indices, otherwise return (None, None)
       try:
           first = self.text.index("sel.first")
           last = self.text.index("sel.last")
           return first, last
       except TclError:
           return None, None

   def cut(self,event=0):
       self.clipboard_clear()
       if self.sel_store: # Sent by the popup
           self.delete(self.sel_store[0],self.sel_store[1])
           self.clipboard_append(self.sel_store[2])
           self.sel_store = []
       else: # Sent by menu
           Selection=self.get_selection_indices()
           if len(Selection)>0:
               SelectedText = self.get(Selection[0],Selection[1])
           self.delete(Selection[0],Selection[1])
           self.clipboard_append(SelectedText)

   def copy(self,event=0):
       self.clipboard_clear()
       if self.sel_store: # Sent by the popup
           self.clipboard_append(self.sel_store[2])
           self.sel_store = []
       else: # Sent by menu
           Selection=self.get_selection_indices()
           if len(Selection)>0:
               SelectedText = self.get(Selection[0],Selection[1])
           self.clipboard_append(SelectedText)

   def paste(self,event=0):
       # This should call colorize for the pasted lines.
       SelectedText = self.root.selection_get(selection='CLIPBOARD')
       self.insert(INSERT, SelectedText)
       return "break"

def autoindent(self,event):
if event.keysym == 'Return':
self.edit_separator() # For undo/redo
index = self.index(INSERT).split('.')
print index
line = int(index[0])
column = int(index[1])
if self.get('%s.%d'%(line, column-1)) == ':':
self.indention += 1
print '\n',
print '\t'*self.indention
self.insert(INSERT,'\n')
self.insert(INSERT,'\t'*self.indention)
return 'break' # Overides standard bindings
elif event.keysym == 'Tab':
self.edit_separator()
self.indention += 1
print self.indention
elif event.keysym == 'BackSpace':
self.edit_separator()
index = self.index(INSERT).split('.')
print index
line = int(index[0])
column = int(index[1])
if self.get('%s.%d'%(line, column-1)) == '\t':
self.indention -= 1
def key_press(self, key):
"""This function was origonaly the home of the colorize code.
Now it is mostly useless unless you want to watch for a certain character."""
if key.char in ' :[(]),"\'':
self.edit_separator() # For undo/redo


       cline = self.index(INSERT).split('.')[0]
       lastcol = 0
       char = self.get('%s.%d'%(cline, lastcol))
       while char != '\n':
           lastcol += 1
           char = self.get('%s.%d'%(cline, lastcol))

       self.colorize(cline,lastcol)

   def colorize(self,cline,lastcol):
       """Not so simple syntax highlighting."""
       buffer = self.get('%s.%d'%(cline,0),'%s.%d'%(cline,lastcol))
       tokenized = buffer.split(' ')

       self.remove_tags('%s.%d'%(cline, 0), '%s.%d'%(cline, lastcol))

       quotes = 0
       start = 0
       for i in range(len(buffer)):
           if buffer[i] in ['"',"'"]: # Doesn't distinguish between single and 
double quotes...
               if quotes:
                  self.tag_add('str', '%s.%d'%(cline, start), '%s.%d'%(cline, 
i+1))
                  quotes = 0
               else:
                   start = i
                   quotes = 1
           elif buffer[i] == '#':
               self.tag_add('com', '%s.%d'%(cline, i), '%s.%d'%(cline, 
len(buffer)))
               break

       start, end = 0, 0
       obj_flag = 0
       for token in tokenized:
           end = start + len(token)
           if obj_flag:
               self.tag_add('obj', '%s.%d'%(cline, start), '%s.%d'%(cline, end))
               obj_flag = 0
           if token.strip() in keyword.kwlist:
               self.tag_add('kw', '%s.%d'%(cline, start), '%s.%d'%(cline, end))
               if token.strip() in ['def','class']:
                   obj_flag = 1
           else:
               for index in range(len(token)):
                   try:
                       int(token[index])
                   except ValueError:
                       pass
                   else:
                       self.tag_add('int', '%s.%d'%(cline, start+index))

           start += len(token)+1

if __name__ == '__main__':
   root = Tk()
   root.title('IdleCE')
   if OS is 'ce':
        root.maxsize(240,320)
   app = idle(root)
   root.mainloop()



------------------------------------------------------------------------

_______________________________________________
PythonCE mailing list
PythonCE@python.org
http://mail.python.org/mailman/listinfo/pythonce



_______________________________________________ PythonCE mailing list PythonCE@python.org http://mail.python.org/mailman/listinfo/pythonce

Reply via email to