""" Property Editor Dialog """ # Copyright (C) 2004 Henning Jacobs # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # $Id: PropertyEditor.py 93 2004-11-28 16:05:34Z henning $ from Tkinter import * import Pmw import ToolTip from InputWidgets import AbstractSingleVarEdit, TextEdit, MemoEdit, CheckboxEdit PADX = PADY = 2 class MemoPropEdit(Pmw.Group): def __init__(self, master, title, descr): Pmw.Group.__init__(self, master, tag_text = title) master = self.interior() self.edtMemo = MemoEdit(master) master.columnconfigure(0, weight=1) master.rowconfigure(0, weight=1) self.edtMemo.grid(sticky=W+E+S+N, padx=PADX, pady=PADY) ToolTip.ToolTip(self.edtMemo, descr) def bindto(self, var): self.edtMemo.bindto(var) def add_save_hook(self, save_hook): self.edtMemo.add_save_hook(save_hook) class TextPropEdit(TextEdit): def __init__(self, master, title, descr): TextEdit.__init__(self, master) ToolTip.ToolTip(self, descr) class CheckboxPropEdit(CheckboxEdit): def __init__(self, master, title, descr): CheckboxEdit.__init__(self, master) ToolTip.ToolTip(self, descr) class ImagePropEdit(Pmw.Group, AbstractSingleVarEdit): def __init__(self, master, title, descr): Pmw.Group.__init__(self, master, tag_text = title) AbstractSingleVarEdit.__init__(self) # imagedata is base64 encoded! self._imagedata = "" self._imageformat = "" master = self.interior() ToolTip.ToolTip(master, descr) self.btnLoad = Button(master, text='Load...', command=self.loadImageFromFile) self.btnLoad.grid(column=0, columnspan=2, row=0, sticky=W+E+S+N, padx=PADX, pady=PADY) ToolTip.ToolTip(self.btnLoad, "Load Image from file") self.btnSave = Button(master, text='Save...', command=self.saveImageToFile) self.btnSave.grid(column=2, columnspan=2, row=0, sticky=W+E+S+N, padx=PADX, pady=PADY) ToolTip.ToolTip(self.btnSave, "Save Image to file") self.lblSize = Label(master) self.lblSize.grid(columnspan=3, row=1, sticky=W+E, padx=PADX, pady=PADY) self.btnClear = Button(master, text="Clear", command=self.clearImage, padx=0, pady=0) self.btnClear.grid(column=3, row=1, padx=PADX, pady=PADY) ToolTip.ToolTip(self.btnClear, "Clear Image (remove)") self.updateLabel() def clearImage(self): self.clear() self.save() self.updateLabel() def updateLabel(self): if not self._imageformat and hasattr(self._var, 'params'): # get vCard specific parameters tempset = self._var.params.get('type') if tempset and len(tempset) > 0: self._imageformat = tempset[0] else: self._imageformat = "UNKNOWN" size = len(self._imagedata) if size > 0: self.lblSize["text"] = "%d Bytes (base64 encoded %s)" % (size, self._imageformat) else: self.lblSize["text"] = "" def get(self): return self._imagedata def clear(self): self._imagedata = "" self._imageformat = "" def set(self, data): self._imagedata = data self.updateLabel() def loadImageFromFile(self): import tkFileDialog, base64 dlg = tkFileDialog.Open(self.interior(), filetypes=[("Image Files", "*.jpg *.jpeg *.png *.gif"), ("All Files", "*")]) fname = dlg.show() if fname: # determine image format import os fbase, fext = os.path.splitext(fname) fext = fext.lower() if fext == '.jpg' or fext == '.jpeg': self._imageformat = 'JPEG' elif fext == '.png': self._imageformat = 'PNG' elif fext == '.gif': self._imageformat = 'GIF' else: self._imageformat = 'UNKNOWN' self.set(base64.encodestring(open(fname, "rb").read())) if hasattr(self._var, 'params'): # set vCard specific parameters import Set self._var.params.set('encoding', Set.Set('b')) self._var.params.set('type', Set.Set(self._imageformat)) self.save() def saveImageToFile(self): import tkFileDialog, base64 dlg = tkFileDialog.SaveAs(self.interior(), filetypes=[("Image Files", "*.jpg *.jpeg *.png *.gif"), ("All Files", "*")]) fname = dlg.show() if fname: fd = open(fname, "wb") fd.write(base64.decodestring(self.get())) fd.close() class PropertyEditor(Pmw.Dialog): # propdefs = [(type, title, descr)] def __init__(self, master, propdefs, **kws): Pmw.Dialog.__init__(self, master=master, title=kws.get('title', ''), buttons=('Close',), defaultbutton='Close') self.master = master self.propdefs = propdefs self._save_hook = kws.get('save_hook') self._editclasses = kws.get('editclasses', {}) self._addcolon = kws.get('addcolon', ':') self.notebook = None self.createWidgets() def createWidgets(self): self.propwidgets = [] row = 1 page = self.interior() self.interior().columnconfigure(0, weight=1) for type, title, descr in self.propdefs: if type == "Page": row = 0 if not self.notebook: self.interior().rowconfigure(row, weight=1) self.notebook = Pmw.NoteBook(self.interior()) self.notebook.grid(row=row, columnspan=2, sticky=W+E+S+N, padx=PADX, pady=PADY) page = self.notebook.add(title) page.columnconfigure(0, weight=1) page.columnconfigure(1, weight=2) continue elif type == "Label": lbl = Label(page, text=descr) lbl.grid(row=row, column=0, columnspan=2, padx=PADX, pady=PADY) else: if type == "Memo": page.rowconfigure(row, weight=1) widget = MemoPropEdit(page, title, descr) widget.grid(row=row, columnspan=2, sticky=W+E+N+S, padx=PADX, pady=PADY) elif type == "Image": page.rowconfigure(row, weight=1) widget = ImagePropEdit(page, title, descr) widget.grid(row=row, columnspan=2, sticky=W+E+N+S, padx=PADX, pady=PADY) else: lbl = Label(page, text=title+self._addcolon) lbl.grid(row=row, column=0, padx=PADX, pady=PADY) if type == "Text": widget = TextPropEdit(page, title, descr) elif type == "Checkbox": widget = CheckboxPropEdit(page, title, descr) else: widget = self._editclasses[type](page, title, descr) widget.grid(row=row, column=1, sticky=W+E, padx=PADX, pady=PADY) if self._save_hook: widget.add_save_hook(self._save_hook) self.propwidgets.append(widget) row += 1 if self.notebook: self.notebook.setnaturalsize() def bindto(self, varlist): for var, widget in zip(varlist, self.propwidgets): widget.bindto(var) _firstshow = 1 def show(self): if self._firstshow: self.centerWindow() else: self.deiconify() self._firstshow = 0 def centerWindow(self, relx=0.5, rely=0.3): "Center the Window on Screen" widget = self master = self.master widget.update_idletasks() # Actualize geometry information if master.winfo_ismapped(): m_width = master.winfo_width() m_height = master.winfo_height() m_x = master.winfo_rootx() m_y = master.winfo_rooty() else: m_width = master.winfo_screenwidth() m_height = master.winfo_screenheight() m_x = m_y = 0 w_width = widget.winfo_reqwidth() w_height = widget.winfo_reqheight() x = m_x + (m_width - w_width) * relx y = m_y + (m_height - w_height) * rely if x+w_width > master.winfo_screenwidth(): x = master.winfo_screenwidth() - w_width elif x < 0: x = 0 if y+w_height > master.winfo_screenheight(): y = master.winfo_screenheight() - w_height elif y < 0: y = 0 widget.geometry("+%d+%d" % (x, y)) widget.deiconify() # Become visible at the desired location if __name__ == "__main__": import InputWidgets propdefs = [ ("Text", "Test", "Test Descr"), ("Text", "Color", "Choose Color"), ("Label", "", "Here comes a DateEdit:"), ("Date", "Date", "My Date Edit"), ("Memo", "Your Ideas", "Please enter your Ideas")] class MyDateEdit(InputWidgets.DateEdit): def __init__(self, master, title, descr): InputWidgets.DateEdit.__init__(self, master) tk = Tk() dlg = PropertyEditor(tk, propdefs, title="Property Editor Test", editclasses={"Date":MyDateEdit}) dlg.show() tk.mainloop()