Initial revision
[gnucomo.git] / src / coconf / cotkwidget.py
1 #   Copyright (C) 2002, Peter Roozemaal.
2 #
3 # GnuCoMo/CoConf is free software; you may redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2, or (at your option)
6 # any later version.  See the file COPYING.
7
8 "The widget definitions that build a form"
9
10 import string
11 import os
12 import Tkinter
13 import tkMessageBox
14 import ScrolledText
15 from textbase import txt
16
17 _id = "$Id: cotkwidget.py,v 1.1 2002-11-19 19:21:18 arjen Exp $"
18
19 _helpwins = {}
20
21 class HelpWin(Tkinter.Toplevel):
22     def __init__(self, item, text):
23         global _helpwins
24         Tkinter.Toplevel.__init__(self)
25         self.title(txt("helpon","help on")+" "+item)
26         _helpwins[item] = self
27         self.name = item
28         self.bind("<Destroy>", self.cleanup)
29         self.textwin = ScrolledText.ScrolledText(self, takefocus=0, wrap="word")
30         self.textwin.pack(side="top")
31         self.textwin.insert("1.0", text)
32         self.textwin["state"] = "disabled"
33         self.button = Tkinter.Button(self, text=txt("thanks", "Thank You"),
34                                      relief="groove", borderwidth=4,
35                                      command=self.destroy)
36         self.button.pack(side="bottom")
37     def cleanup(self, event):
38         if _helpwins.has_key(self.name):
39             del _helpwins[self.name]
40
41 class _BaseWidget:
42     widgetname = ""
43     curhelp = ""
44     defhelp = ""
45     help = {}
46
47     def cleanup(self):
48         self.destroy()
49
50     def readDom(self, dom):
51         self.widgetname = dom.getAttribute("name")
52         for i in self.translate:
53             att = dom.getAttribute(i)
54             setattr(self, "cur"+i, att)
55             setattr(self, "def"+i, att)
56             setattr(self, i, {})
57             getattr(self, i)[dom.getAttribute("language")] = att
58         el = dom.firstChild
59         while el != None:
60             if el.nodeType == el.ELEMENT_NODE:
61                 if el.tagName == "help":
62                     self.readHelp(el)
63                 elif el.tagName == "translate":
64                     self.readTrans(el)
65                 else:
66                     print self.widgetname, "bad element:", el.tagName
67             #else:
68                 #print self.widgetname, "bad xml node:", el.nodeName
69             el = el.nextSibling
70
71     def readHelp(self, dom):
72         lang = dom.getAttribute("language")
73         text = ""
74         el = dom.firstChild
75         while el != None:
76             if el.nodeType == el.TEXT_NODE:
77                 text = text + el.data
78             el = el.nextSibling
79         text = string.join(string.split(text))
80         if self.curhelp == "":
81             self.curhelp = text
82         if self.defhelp == "":
83             self.defhelp = text
84         self.help[lang] = text
85
86     def readTrans(self, dom):
87         pass
88
89     def provide_help(self):
90         if _helpwins.has_key(self.widgetname):
91             _helpwins[self.widgetname].lift()
92         elif self.curhelp:
93             HelpWin(self.widgetname, self.curhelp)
94         else:
95             tkMessageBox.showinfo(title=txt("sorry", "Sorry"),
96                                   message=txt("nohelp", "The creator of the form didn't provide a help message."))
97
98     def value_dom(self, document, parent, flags):
99         #TODO: check flags
100         node = document.createElement("variable")
101         node.setAttribute("name", self.widgetname)
102         #the next line isn't OO clean
103         node.setAttribute("value", str(self.variable.get()))
104         parent.appendChild(node)
105
106 class _ComposedWidget(_BaseWidget):
107     def readDom(self, dom):
108         self.widgetname = dom.getAttribute("name")
109         for i in self.translate:
110             att = dom.getAttribute(i)
111             setattr(self, "cur"+i, att)
112             setattr(self, "def"+i, att)
113             setattr(self, i, {})
114             getattr(self, i)[dom.getAttribute("language")] = att
115         el = dom.firstChild
116         while el != None:
117             if el.nodeType == el.ELEMENT_NODE:
118                 if el.tagName == "help":
119                     self.readHelp(el)
120                 elif el.tagName == "translate":
121                     self.readTrans(el)
122                 elif _subwidgets.has_key(el.tagName):
123                     w = _subwidgets[el.tagName](self, el)
124                     self.add_widget(w)
125                 else:
126                     print self.widgetname, "bad element:", el.tagName
127             #else:
128                 #print self.widgetname, "bad xml node:", el.nodeName
129             el = el.nextSibling
130
131 class FormWin(Tkinter.Frame, _ComposedWidget):
132     translate = ( "title", )
133     def __init__(self, master, dom):
134         Tkinter.Frame.__init__(self, master)
135         self.wlist = []
136         self.readDom(dom)
137     def cleanup(self):
138         for sub in self.wlist:
139             sub.cleanup()
140         self.destroy()
141     def add_widget(self, wid):
142         self.wlist.append(wid)
143         wid.pack(side="top", fill="x")
144     def value_dom(self, document, parent, flags):
145         if flags:
146             node = document.createElement("export")
147         else:
148             node = document.createElement("save")
149         node.setAttribute("form", self.widgetname)
150         parent.appendChild(node)
151         for sub in self.wlist:
152             sub.value_dom(document, node, flags)
153
154 class Group(Tkinter.Frame, _ComposedWidget):
155     translate = ()
156     def __init__(self, master, dom):
157         Tkinter.Frame.__init__(self, master)
158         self.wlist = []
159         self.filler = Tkinter.Frame(self, width="7m")
160         self.filler.pack(side="left", fill="y")
161         self.inner = Tkinter.Frame(self)
162         self.inner.pack(side="right", fill="both", expand=1)
163         self.readDom(dom)
164     def cleanup(self):
165         for sub in self.wlist:
166             sub.cleanup()
167         self.destroy()
168     def add_widget(self, wid):
169         self.wlist.append(wid)
170         wid.pack(side="top", fill="x", in_=self.inner)
171     def value_dom(self, document, parent, flags):
172         #TODO: check flags
173         node = document.createElement("group")
174         node.setAttribute("name", self.widgetname)
175         parent.appendChild(node)
176         for sub in self.wlist:
177             sub.value_dom(document, node, flags)
178
179 class Boolean(Tkinter.Frame, _BaseWidget):
180     translate = ( "label", )
181     def __init__(self, master, dom):
182         Tkinter.Frame.__init__(self, master)
183         self.readDom(dom)
184         self.button = Tkinter.Checkbutton(self, text=self.curlabel)
185         self.button.pack(side="left")
186         self.variable = Tkinter.BooleanVar()
187         self.button["variable"] = self.variable
188         if os.name == "posix":
189             self.button["selectcolor"] = "green"
190         self.helpbutton = Tkinter.Button(self, text=txt("lhelp", "?"),
191                                          command=self.provide_help)
192         self.helpbutton.pack(side="right")
193
194 class String(Tkinter.Frame, _BaseWidget):
195     translate = ( "label", )
196     def __init__(self, master, dom):
197         Tkinter.Frame.__init__(self, master)
198         self.readDom(dom)
199         self.label = Tkinter.Label(self, text=self.curlabel)
200         self.label.pack(side="left")
201         self.variable = Tkinter.StringVar()
202         self.veld = Tkinter.Entry(self, textvariable=self.variable)
203         self.helpbutton = Tkinter.Button(self, text=txt("lhelp", "?"),
204                                          command=self.provide_help)
205         self.helpbutton.pack(side="right")
206         self.veld.pack(side="right", fill="x")
207
208 class Ruler(Tkinter.Frame):
209     def __init__(self, master, dom):
210         Tkinter.Frame.__init__(self, master, relief="sunken", height=4,
211                                borderwidth=2)
212     def value_dom(self, document, parent, flags):
213         pass
214     def cleanup(self):
215         self.destroy()
216
217 _subwidgets = {
218     "boolean" : Boolean,
219     "group" : Group,
220     "ruler" : Ruler,
221     "string" : String
222 }