[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r9451 - in trunk/gnue-forms/src/uidrivers/html: . widgets
From: |
jan |
Subject: |
[gnue] r9451 - in trunk/gnue-forms/src/uidrivers/html: . widgets |
Date: |
Wed, 28 Mar 2007 07:17:11 -0500 (CDT) |
Author: jan
Date: 2007-03-28 07:17:10 -0500 (Wed, 28 Mar 2007)
New Revision: 9451
Added:
trunk/gnue-forms/src/uidrivers/html/GFController.py
trunk/gnue-forms/src/uidrivers/html/gnue.js
Modified:
trunk/gnue-forms/src/uidrivers/html/GFServer.py
trunk/gnue-forms/src/uidrivers/html/GFhtmlApp.py
trunk/gnue-forms/src/uidrivers/html/Generator.py
trunk/gnue-forms/src/uidrivers/html/ToolBar.py
trunk/gnue-forms/src/uidrivers/html/UIdriver.py
trunk/gnue-forms/src/uidrivers/html/widgets/entry.py
trunk/gnue-forms/src/uidrivers/html/widgets/form.py
Log:
update forms webfrontend to new version
- add threaded controller object
- moved javascript code into file
- switch to dojo 4.2
- various other changes
Added: trunk/gnue-forms/src/uidrivers/html/GFController.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/GFController.py 2007-03-27 18:13:56 UTC
(rev 9450)
+++ trunk/gnue-forms/src/uidrivers/html/GFController.py 2007-03-28 12:17:10 UTC
(rev 9451)
@@ -0,0 +1,319 @@
+#
+# This file is part of GNU Enterprise.
+#
+# GNU Enterprise 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, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright 2000-2007 Free Software Foundation
+#
+# FILE:
+# uidrivers/html/GFServer.py
+#
+# DESCRIPTION:
+#
+# NOTES:
+
+import pickle
+import Queue
+import threading, thread
+
+from gnue.common import events
+
+from UISplashScreen import SplashScreen
+from gnue.forms.GFInstance import GFInstance
+from gnue.common.apps import GConfig, errors
+from gnue.forms.uidrivers.html.common import textEncode, textDecode
+import Generator
+
+
+# =============================================================================
+# GNUe Forms HTML UI driver -- Session (contains one instance)
+# =============================================================================
+
+class gnueSession:
+ '''
+ Each Session is represented by a gnueSession object. A session holds the
following
+ variables:
+ identifier - session id
+ backend_state - one of (0=idle, 1=hasContenttoDeliver,
2=willshortlyDeliverContent,
+ 3=waiting_for_additional_request,
4=shutting_down
+
+ new HTML request will be delayed for a short time,
+
+ '''
+ IDLE_STATE = 0
+ LOADING_STATE = 1
+ BUSY_STATE = 2
+ WILL_DELIVER = 3
+ LATE_DELIVERY = 4
+ SHUTTING_DOWN = 9
+
+ instance = None
+ # split updates between different forms
+ _updates = []
+ _state = LOADING_STATE
+
+ _max_session_threads = 3 # maximum number of threads allowed to be
executed in the backend in parallel
+
+ def __init__(self, controller, id):
+ assert gDebug (4, "Creating new session")
+ self._id=id
+ self._controller = controller
+ self._state_lock = threading.Lock()
+ self._update_lock = threading.Lock()
+ self._usageCounter = threading.Semaphore(self._max_session_threads)
+
+ # is just one event sufficient ?
+ # TODO: check, What happens if two requests come in in parallel?
+ # use a per thread event instead?
+ self.updates_available = threading.Event()
+
+ def setup(self, baseform, userParameters):
+
+ # Create the instance that will control the loaded form(s) for this
session
+ assert gDebug (4, "Creating GFInstance object")
+ # HACK: there should be a better way to get ui and connection object
+ gfclient=self._controller.gfclient
+
+ self.instance = GFInstance (self, gfclient.connections, gfclient._ui,
+ False, userParameters)
+
+ # Assign the proper login handler based upon the user interface choice
+ # TODO: we need a login handler per session! How can we achieve this?
+ # by separate connection pools?
+ loginHandler = gfclient._ui.UILoginHandler ()
+ loginHandler.uiDriver = self.instance._uiinstance
+ gfclient.getConnectionManager ().setLoginHandler (loginHandler)
+
+ # disable standart html drivers mainloop
+ gfclient._ui.GFhtmlApp.GFhtmlApp._mainLoop = 1
+
+ self.instance.run_from_file(baseform, None)
+ self._setState(self.IDLE_STATE)
+ print "GNUe Forms Session %s setup" % self._id
+
+ assert gLeave (4)
+
+ def executeCmd(self, cmd, args):
+
+ assert self.instance != None
+ if self.getState()==self.SHUTTING_DOWN:
+ pass
+
+ self._usageCounter.acquire()
+
+ self._setState(self.WILL_DELIVER)
+
+ updates=[]
+
+ try:
+
+ if cmd == "event":
+ # id = int(args["id"])
+ event = args["event"]
+ e = events.Event(event, \
+ _form=self.instance._main_form)
+ self.instance.dispatchEvent(e)
+
+ elif cmd == "onChange":
+ id = int(args["id"])
+ text = args["text"]
+
+ gfObject = self.instance._uiinstance._WidgetToGFObj [id]
+ e = events.Event('requestREPLACEVALUE', text = text, \
+ _form=self.instance._main_form)
+ self.instance.dispatchEvent(e)
+
+
+ elif cmd == "onFocus":
+ id = int(args["id"])
+ UIObject = self.instance._uiinstance._WidgetToUIObj [id]
+ widget = self.instance._uiinstance._IdToWidget [id]
+ UIObject._focusInHandler (id)
+
+ elif cmd == "btn":
+ id = int(args["id"])
+
+ gfObject = self.instance._uiinstance._WidgetToGFObj [id]
+ gfObject._event_fire ()
+
+ else:
+ updates = [["status","","This session is invalid. Please
restart!"]]
+ except Exception, e:
+ updates = [["alert","","Error %s" % e]]
+
+ # refresh updates
+ updates.extend(self.instance._uiinstance._UIform.get_updates())
+ print "pushing updates %s" % updates
+ self._pushUpdates(updates)
+ self.updates_available.set() # inform listeners, that new updates are
available
+ self.updates_available.clear()
+ self._usageCounter.release()
+
+ def getHtml(self, form):
+ if self._state==self.LOADING_STATE:
+ return Generator.build_loading_page("Please wait until loaded")
+ else:
+ # FIXME: do we need to acquire a semaphore here?
+ self._usageCounter.acquire()
+ html = self.instance._uiinstance._UIform.get_html()
+ self._usageCounter.release()
+ return html
+
+ def getState(self):
+ return self._state
+
+ def fetchUpdates(self):
+ self._update_lock.acquire()
+ updates = self._updates
+ self._updates = []
+ print "getting updates %s" % updates
+ self._update_lock.release()
+ return updates
+
+ def _setState(self, state):
+ self._state_lock.acquire()
+ self._state=state
+ self._state_lock.release()
+
+ def _pushUpdate(self, update):
+ self._update_lock.acquire()
+ self._updates.append(update)
+ self._update_lock.release()
+
+ def _pushUpdates(self, updates):
+ self._update_lock.acquire()
+ self._updates.extend(updates)
+ self._update_lock.release()
+
+class backendThread ( threading.Thread ):
+ '''
+ This type of thread is changeing gnue forms and executing specific actions.
+
+ It is different from the frontendthread (as started by the webserver) that
it
+ will just trigger actions. The task of the frontendthread is pass commands
from
+ the client to the backendthread and to check if any UI updates or UI
commands should be
+ passed back to the frontend.
+ '''
+ shutdown = False
+ job_pool = None
+
+ def run ( self ):
+
+ while not self.shutdown:
+ job = self.job_pool.get()
+
+ if job != None:
+ print "Doing backendJob %s" % job
+ job[0].executeCmd(job[1],job[2])
+ print "Job done: %s" % job
+
+# =============================================================================
+# GNUe Forms HTML UI driver -- ComController (Singleton pattern)
+# =============================================================================
+
+
+class ComController:
+ '''
+ This controller should control how the incoming request from the web app
are computed.
+
+ A list of commands should require the form to wait for an answer and not
allow further commands or
+ input. At least Commit, Search, ... should have this behavior.
+
+ # todo: add garbage collector, add session time out to each session
+
+ '''
+
+ __single = None
+
+ max_threads = 2
+ threads = [] # create threadpool to handle jobs
+ backend_jobs = None
+
+ sessions = {} # create sessions
+ base_form = ""
+
+ def __init__( self ):
+ """
+ """
+ # Singleton pattern
+ if ComController.__single:
+ raise ComController.__single
+ ComController.__single = self
+
+ # create queue to transfer data to backend tasks
+ self.backend_jobs = Queue.Queue ( 0 )
+
+ # TODO: convert fixed size threadpool into dynamic pool, i.e. just
startup threads if required
+ x=0
+ while x<self.max_threads:
+ x+=1
+ th=backendThread()
+ self.threads.append(th)
+ th.setName("Backend_%s" % x)
+ th.job_pool = self.backend_jobs
+ th.start()
+
+ def pullHtml(self, session_id, form):
+ if not self.sessions.has_key(session_id):
+ return Generator.build_error_page("restart", "Wrong session or
Session timed out!")
+
+ # TODO: get_html call should be thread safe and shouldn't change
anything
+ if form=="base":
+ response=Generator.build_basic_dialog()
+ else:
+ return self.sessions[session_id].getHtml(form)
+
+ return response
+
+
+ def handleRequest(self, session_id, command, arguments):
+ if not self.sessions.has_key(session_id):
+ return [["status","","This session is invalid. Please restart!"]]
+
+ # TODO: check for health of thread pool, and if necessary startup new
threads or print warning
+ print "processing %s - %s" % (command, arguments)
+ self.backend_jobs.put([self.sessions[session_id], command, arguments])
+ self.sessions[session_id].updates_available.wait(5) # 5 sec
+ # return results
+ return self.pullCommands(session_id)
+
+
+ def pullCommands(self, session_id):
+ return self.sessions[session_id].fetchUpdates()
+
+ def startSession(self, session_id, params):
+ self.sessions[session_id] = gnueSession(self, session_id)
+
+ # TODO make setup to backendtasks
+ self.sessions[session_id].setup(self.base_form, params)
+ # self.backend_jobs.put([self.sessions[session_id], "setup"]
+
+
+ def delSession(self, session_id):
+ # TODO check for still working tasks, use locking
+ del self.sessions[session_id]
+ # self.gfclient.getConnectionManager ().closeAll ()
+
+ def shutdown(self, urgency):
+ '''
+
+ @param urgency: 0=high (System will shutdown at once t<10sec)
+ 1=standart (normal shutdown)
+ 2=low (system will not accept new clients, but will
shutdown
+ '''
+
+ for th in threads:
+ th.shutdown=True
Property changes on: trunk/gnue-forms/src/uidrivers/html/GFController.py
___________________________________________________________________
Name: svn:executable
+ *
Modified: trunk/gnue-forms/src/uidrivers/html/GFServer.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/GFServer.py 2007-03-27 18:13:56 UTC
(rev 9450)
+++ trunk/gnue-forms/src/uidrivers/html/GFServer.py 2007-03-28 12:17:10 UTC
(rev 9451)
@@ -32,7 +32,6 @@
from gnue.common.utils.uuid import UUID
from BaseHTTPServer import HTTPServer
from SocketServer import ThreadingMixIn
-from gnue.common.apps.GClientApp import StartupError
from gnue.common import events
@@ -40,7 +39,10 @@
from gnue.forms.GFInstance import GFInstance
from gnue.common.apps import GConfig, errors
from gnue.forms.uidrivers.html.common import textEncode, textDecode
+from Generator import build_basic_dialog
+from GFController import ComController
+
from types import UnicodeType
try:
@@ -50,8 +52,10 @@
raise ImportError
_iconpath = GConfig.getInstalledBase('form_images', 'common_images')
-_includepath = gConfigForms("htmlui_include_path")
+_includepath =
os.path.join(GConfig.getInstalledBase('common_shared'),'webfrontend')
+_gnuejs_path = os.path.dirname(__file__)
+
class ThreadingHTTPServer (ThreadingMixIn, HTTPServer):
pass
@@ -65,9 +69,17 @@
def __init__(self, gfclient):
self.splash = SplashScreen()
self.instances = {}
- self.gfclient = gfclient
+ # self.gfclient = gfclient
self.jsonenc = JSONEncoder()
+ self._controller = ComController()
+ self._controller.gfclient=gfclient
+ # assign form file from 1st free argument
+ if len (gfclient.ARGUMENTS):
+ self._controller.base_form = gfclient.ARGUMENTS [0]
+ else:
+ raise StartupError, u_("No Forms Definition File Specified.")
+
def serve(self):
print '\nGNUe Forms HTML UI driver is loaded.'
print '\n-- please point your browser to http://127.0.0.1:8000 --'
@@ -75,116 +87,21 @@
server.GFServer = self
server.serve_forever()
- def createFormsInstance(self, uid, userParameters):
- # Create the instance that will control the loaded form(s)
- assert gDebug (4, "Creating GFInstance object")
+ # TODO: overwrite finalizeRequest to pass more data (controller object) to
Requesthandler
- instance = GFInstance (self, self.gfclient.connections,
self.gfclient._ui,
- self.gfclient.disableSplash, userParameters)
+ # TODO: remove the following commands from here and directly call
controller object
- self.instances[uid]=instance
+ def createFormsInstance(self, id, userParameters):
+ self._controller.startSession(id, userParameters)
- # Assign the proper login handler based upon the user interface choice
- #FIXME: IMHO, it would be much better if the login handler would be
just a
- # function, which could be a method of the GFUserInterfae object - much
- # like _showException. -- Reinhard
- loginHandler = self.gfclient._ui.UILoginHandler ()
- loginHandler.uiDriver = instance._uiinstance
- self.gfclient.getConnectionManager ().setLoginHandler (loginHandler)
+ def displayFormsInstance(self, uuid, form):
+ return self._controller.pullHtml(uuid, form)
- # assign form file from 1st free argument
- if len (self.gfclient.ARGUMENTS):
- formfile = self.gfclient.ARGUMENTS [0]
-
- else:
- basename = os.path.basename (sys.argv [0])
-
- # If no form specified, then see if this is a symlinked form
definition
- if not basename.lower ().split ('.') [0] in ('gnue-forms',
'gfclient'):
- formfile = os.path.join (
- GConfig.getInstalledBase ('forms_appbase', 'common_appbase',
- 'install_prefix'),
- gConfigForms ('FormDir'), basename + ".gfd")
- else:
- raise StartupError, u_("No Forms Definition File Specified.")
-
- # disable standart html drivers mainloop
- self.gfclient._ui.GFhtmlApp.GFhtmlApp._mainLoop = 1
-
- instance.run_from_file(formfile, None)
- instance.activate ()
-
- print "GNUe Forms Session %s started" % uid
-
- assert gLeave (4)
-
- def displayFormsInstance(self,uuid):
- # TODO: thread safety: allow only one access to a
- # specific instance at one time
- if self.instances.has_key(uuid):
- response=self.instances[uuid]._uiinstance._UIform.get_html()
- else:
- response="""<HTML><HEAD></HEAD><BODY>
- <H1>Wrong Session or Session timed out!</H1><BR>
- <A HREF="/">Restart GNUe Forms</A></BODY></HTML>
- """
-
- return response
-
def executeCmd(self, uuid, cmd, args):
+ return self._controller.handleRequest(uuid, cmd, args)
- # TODO: thread safety: allow only one access to a
- # specific instance at one time
- if cmd == "" or not self.instances.has_key(uuid):
- updates = [["status","","This session is invalid. Please
restart!"]]
-
- elif cmd == "event":
- # id = int(args["id"])
- event = args["event"]
- e = events.Event(event, \
- _form=self.instances[uuid]._main_form)
- self.instances[uuid].dispatchEvent(e)
- updates = self.instances[uuid]._uiinstance._UIform.get_updates()
- # updates.append(["alert","","Menuitem clicked"])
- elif cmd == "onChange":
- id = int(args["id"])
- text = args["text"]
- gfObject = self.instances[uuid]._uiinstance._WidgetToGFObj [id]
- e = events.Event('requestREPLACEVALUE', text = text, \
- _form=self.instances[uuid]._main_form)
- self.instances[uuid].dispatchEvent(e)
- updates = self.instances[uuid]._uiinstance._UIform.get_updates()
-
- elif cmd == "onFocus":
- id = int(args["id"])
- UIObject = self.instances[uuid]._uiinstance._WidgetToUIObj [id]
- widget = self.instances[uuid]._uiinstance._IdToWidget [id]
- UIObject._focusInHandler (id)
-
- updates = self.instances[uuid]._uiinstance._UIform.get_updates()
-
- elif cmd == "btn":
- id = int(args["id"])
-
- gfObject = self.instances[uuid]._uiinstance._WidgetToGFObj [id]
- gfObject._event_fire ()
-
- updates = self.instances[uuid]._uiinstance._UIform.get_updates()
-
- else:
- updates = []
-
- return self.jsonenc.encode(updates)
-
- def removeFormsInstance(self, uuid):
- assert gDebug (4, "Closing all connections")
- # FIXME: close all connections for the instance self.instances[uid]
- # self.gfclient.getConnectionManager ().closeAll ()
- del self.instances[uuid]
-
-
# =============================================================================
# GNUe Forms HTML UI driver Request handler
# =============================================================================
@@ -212,20 +129,23 @@
try:
if self.path=="/":
uuid = UUID.generate_random ()
- forward_url = "session_%s.htm" % uuid
+ forward_url = "session_%s/index.html" % uuid
response = self.server.GFServer.splash.get_html(forward_url)
self.push_content(response)
self.server.GFServer.createFormsInstance(uuid, {})
-
+
elif self.path=="/splashscreen.png":
response = self.server.GFServer.splash.getPicture()
self.push_content(response,"image/png")
-
- elif self.path[0:9]=="/session_" and self.path[41:]==".htm":
+
+ # FIXME: distinguish between different forms of one session here
+ elif self.path[0:9]=="/session_" and self.path[41]=="/" and \
+ self.path[-5:]==".html":
uuid=self.path[9:41]
- response=self.server.GFServer.displayFormsInstance(uuid)
+ formname=self.path[42:-5]
+ response=self.server.GFServer.displayFormsInstance(uuid,
formname)
self.push_content(response)
-
+
elif self.path[0:9]=="/jsonrpc_" and self.path[41:42]=="?":
uuid=self.path[9:41]
# FIXME: Use standart argument parser
@@ -235,24 +155,39 @@
for i in arg_list:
z=i.split('=')
args[z[0]]=unquote(z[1]).decode("utf-8")
-
+
try:
cmd=args['cmd']
except:
cmd=""
-
- response = self.server.GFServer.executeCmd(uuid,cmd,args)
+
+ try:
+ response = self.server.GFServer.executeCmd(uuid,cmd,args)
+ except:
+ (group, name, message, detail) = errors.getException()
+ message = u"""<HTML><HEAD></HEAD><BODY><H1>Exception
occured!</H1>
+ Group: %s<BR>
+ Name: %s<BR>
+ Message: %s<BR>
+ Details: <BR><PRE>%s</PRE></BODY></HTML>
+ """ % (group, name, message, detail)
+ response = [["alert","Warning!",message]]
+ response = self.server.GFServer.jsonenc.encode(response)
self.push_content(response,"text/text")
print "JSON: %s -> %s" % (self.path,response)
-
+
+ # get gnue specific js file from source directory
+ elif self.path=="/incl/gnue.js":
+ self.deliver_file(_gnuejs_path, 'gnue.js')
+
# Include file handling for libraries
elif self.path[0:6]=="/incl/":
- self.deliver_file(_includepath, self.path[6:])
-
+ self.deliver_file(_includepath, self.path[6:])
+
# file handling for icons
elif self.path[0:6]=="/icon/":
self.deliver_file(_iconpath, self.path[6:])
-
+
else:
self.send_response(404)
self.connection.shutdown (1)
@@ -267,21 +202,21 @@
Details: <BR><PRE>%s</PRE></BODY></HTML>
""" % (group, name, message, detail)
self.push_content(message)
- print textDecode(message)
-
+ print textEncode(message)
+
# If a shutdown of the connection is requested do so, although we
assume to
# have a persistent connection.
if self.close_connection:
self.connection.shutdown (1)
-
+
def deliver_file(self, base, path):
-
+
# FIXME: implement security measures:
# 1: normalize path
# 2: remove all ".."
#
realpath=os.path.join(base, path)
-
+
if realpath[-3:]==".js":
mimetype = "text/javascript"
elif realpath[-4:]==".css":
@@ -314,10 +249,10 @@
print " the install path to gnue.conf: 'htmlui_include_path =
<path>'"
print " Currently searching for dojo.js at: '%s' " % realpath
print
"****************************************************************"
-
+
def push_content(self, response, content_type="text/html"):
if type(response)==UnicodeType:
- # FIXME: Should local encoding be used?
+ # FIXME: Should local encoding be used?
response = response.encode('utf-8')
self.send_response (200, flush = False)
Modified: trunk/gnue-forms/src/uidrivers/html/GFhtmlApp.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/GFhtmlApp.py 2007-03-27 18:13:56 UTC
(rev 9450)
+++ trunk/gnue-forms/src/uidrivers/html/GFhtmlApp.py 2007-03-28 12:17:10 UTC
(rev 9451)
@@ -76,7 +76,7 @@
def quit(self):
self.running=False
- sys.exit()
+ # sys.exit()
def textEncode(a):
return a
\ No newline at end of file
Modified: trunk/gnue-forms/src/uidrivers/html/Generator.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/Generator.py 2007-03-27 18:13:56 UTC
(rev 9450)
+++ trunk/gnue-forms/src/uidrivers/html/Generator.py 2007-03-28 12:17:10 UTC
(rev 9451)
@@ -28,93 +28,108 @@
def _on_click_event(event):
return u' onClick="sendCmd(\'event\',\'event=%s\');"' % event
-def _on_change_event(id):
- return u'onchange="sendCmd(\'onChange\',\'id=%s&text=\'+this.value)"\n' %
id
+def _on_change_event(id, what):
+ return u'onchange="sendCmd(\'onChange\',\'id=%s&text=\'+this.%s)"\n' %
(id, what)
-def _on_focus_event(id):
- return u'onfocus="sendCmd(\'onFocus\',\'id=%s&text=\'+this.value)"\n' % id
+def _on_focus_event(id, what):
+ return u'onfocus="sendCmd(\'onFocus\',\'id=%s&text=\'+this.%s)"\n' % (id,
what)
def _css_position(x,y,width,height):
return (u'style="position:absolute; top:%spx; left:%spx;'+\
u' width:%spx; height:%spx;"') % (FIX + y, x, width, height)
-def build_label(id, value, x, y, width, height):
+def build_tooltip(forid, text):
+ return (u'<span dojoType="tooltip" connectId="%s" caption="%s"
toggle="fade" '+\
+ u'toggleDuration="500"></span>\n') % (forid, text)
+
+def build_label(id, value, x, y, width, height):
return (u'<div id="%s" %s>%s</div>\n') % \
- (id, _css_position(x,y,width,height-FIX2), value)
-
-def build_entry_label(id, value, x, y, width, height):
+ (id, _css_position(x,y,width,height-FIX2), value)
+
+def build_entry_label(id, value, x, y, width, height):
return (u'<div id="%s" %s>%s</div>\n') % \
- (id, _css_position(x,y,width,height-FIX2), value)
-
-def build_entry_checkbox(id, value, label, x, y):
+ (id, _css_position(x,y,width,height-FIX2), value)
+
+def build_entry_checkbox(id, value, label, x, y):
return (u'<div style="position:absolute; top:%spx; left:%spx">\n'+\
u'<input type="checkbox" id="%s" dojoType="Checkbox" value="%s" %s
%s/>\n'+\
u'<label for="%s">%s</label></div>\n') % \
- (FIX + y, x, id, value, _on_change_event(id),
- _on_focus_event(id), id, label)
-
-def build_entry_default(id, value, x, y, width, height):
- return u'<input type="text" id="%s" value="%s" %s\n %s\n %s/>\n' % \
- (id, value, _css_position(x,y,width,height-FIX2), \
- _on_change_event(id),_on_focus_event(id))
-
+ (FIX + y, x, id, value, _on_change_event(id,"value"),
+ _on_focus_event(id, "value"), id, label)
+
+def build_entry_default(id, value, x, y, width, height, textbox_style):
+ return (u'<div %s><input dojo:type="%s" type="text" id="%s" value="%s"\n
%s\n %s ' +\
+ u'dojoOnBuild="fixCSS(this);"/></div>\n') % \
+ (_css_position(x,y,width,height-FIX2),textbox_style, id, value, \
+ _on_change_event(id,"textbox.value"),_on_focus_event(id,
"textbox.value"))
+ # dojo:type="Textbox", IntegerTextbox, DateTextbox, TimeTextbox
+
+
+
def build_entry_multiline(id, value, rowcount, x, y, width, height):
return u'<textarea id="%s" rows="%s" %s\n %s\n %s/>%s</textarea>\n' % \
(id, rowcount, _css_position(x,y,width,height-4), \
- _on_change_event(id),_on_focus_event(id), value)
-
+ _on_change_event(id, "value"),_on_focus_event(id, "value"), value)
+
def _build_choices(choices):
out = ""
for i in choices:
out+=u"<option>%s</option>\n" % i
return out
-
+
def build_entry_listbox(id, value, choices, rows, x, y, width, height):
return (u'<select id="%s" value="%s" size="%s" %s\n %s\n'+ \
u'%s>\n%s</select>\n') % \
(id, value, rows, _css_position(x,y,width,height),
- _on_change_event(id),_on_focus_event(id), _build_choices(choices))
-
+ _on_change_event(id, "value"),_on_focus_event(id, "value"),
_build_choices(choices))
+
def build_entry_combobox(id, value, choices, rows, x, y, width, height):
return (u'<select id="%s" value="%s" size="%s" dojoType="ComboBox" %s\n
%s\n'+ \
u'%s>\n%s</select>\n') % \
(id, value, rows, _css_position(x,y,width,height),
- _on_change_event(id),_on_focus_event(id),
_build_choices(choices))
-
-def build_toolbutton(id, label, event, iconpath, tooltip, enabled):
- return (u'<td><button id="%s" class="Toolbutton" widgetId="%s" '+\
- u'dojoType="Button" name="%s" %s %s>\n'+\
- u'<img src="%s">%s\n</button></td>\n') % \
- (id, id, label, _on_click_event(event), enabled,
- iconpath,"") # "<br>%s" % label)
-
- #return '<input id="%s" type="IMAGE" name="%s" src="%s" alt="%s" %s %s/>'
% \
- # (id, label, iconpath, label, _on_click_event(event), enabled)
-
-def build_toolbar(id, content):
- return u'<table class="Toolbar"><tr>\n%s\n</tr></table>' % content
- # FIXME: Use dojotype Toolbar
+ _on_change_event(id, "value"),_on_focus_event(id, "value"),
_build_choices(choices))
+def _toolbar_toogle_handler(event, event2):
+ return (u'toggleItem="true" onmousedown="if (this.isSelected()) ' +\
+ u'sendCmd(\'event\',\'event=%s\'); else sendCmd(\'event\',' +\
+ '\'event=%s\');"') % (event, event2)
+
+def build_toolbar_button(id, label, event, iconpath, tooltip, toggleItem,
enabled):
+ return (u' <img id="%s" dojo:type="ToolbarButton" name="%s"
dojo:icon="%s"'+\
+ u' %s %s %s />\n %s\n') % \
+ (id, label, iconpath, enabled, _on_click_event(event), \
+ (toggleItem and _toolbar_toogle_handler(event, toggleItem) or
""), \
+ build_tooltip(id,tooltip))
+
+
+def build_toolbar_separator(id):
+ return u' <span dojo:type="ToolbarSeparator"> </span>\n\n'
+
+def build_toolbar(id, content):
+ return (u'<div id="%s" dojo:type="ToolbarContainer">\n'+\
+ u'<div dojo:type="toolbar">\n%s\n</div>\n</div>\n\n') % (id,
content)
+
def build_button(id, label, x, y, width, height):
return u'<input id="%s" type="button" value="%s" %s %s/>\n' % \
(id, label, _css_position(x,y,width,height),
_button_on_click(id))
-
-def _button_on_click(id):
+
+def _button_on_click(id):
return u'onclick="sendCmd(\'btn\',\'id=%s\')"' % id
def build_image(id, value, x, y, width, height):
return u'<image id="%s" src="/images/%s" %s>' % \
(id, value, _css_position(x,y,width,height))
-
+
def build_box(id, label, x, y, width, height):
- return u'<div id="%s" %s border-width: 1px; border-style: solid">%s</div>'
% \
+ return u'<div id="%s" %s z-index:-5; border-width: 1px; border-style:
solid">%s</div>' % \
(id, _css_position(x,y+FIX2,width,height-FIX)[0:-1], label)
-
+
def build_page(id, pagename, content):
- return (u"<div id=\"%s\" dojoType=\"ContentPane\" label=\"%s\">\n" +\
- u" %s \n</div>\n") % (id, pagename, content)
-
+ return (u"<div id=\"%s\" dojoType=\"ContentPane\" label=\"%s\" " +\
+ u'onShow="sendCmd(\'pagechange\',\'page=%s&id=%s\');">\n' +\
+ u" %s \n</div>\n") % (id, pagename, pagename, id, content)
+
def build_splashscreen(forward_url, VERSION):
return u"""<HTML><HEAD>
<meta http-equiv="refresh" content="4; URL=%s">
@@ -129,19 +144,94 @@
<A HREF="%s"> Press here!</A>
</BODY>
</HTML>""" % (forward_url, VERSION, forward_url)
-
+
+def build_basic_dialog():
+ return u"""<table>
+ <tr>
+ <td><h1 id="basic_title">Warning!</h1></td>
+ </tr>
+ <tr>
+ <td> </td>
+ </tr>
+ <tr>
+ <td id="basic_content"></td>
+ </tr>
+ <tr>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="button" id="basic_button" value="OK"></td>
+ </tr>
+ </table>
+ </form>
+"""
+
+def build_error_dialog(msg, main, error):
+ return u"""<table>
+ <tr>
+ <td>Line 1</td>
+ <td><input type="text"></td>
+ </tr>
+ <tr>
+ <td>Location:</td>
+ <td><input type="text"></td>
+ </tr>
+ <tr>
+ <td>Description:</td>
+ <td><input type="text"></td>
+ </tr>
+ <tr>
+ <td>Location:</td>
+ <td><input type="file"></td>
+ </tr>
+ <tr>
+ <td>
+ <input type="button" id="basic_button" value="OK"></td>
+ </tr>
+ </table>
+ </form>
+"""
+
+
+def build_error_page(type, message):
+ return u"""<HTML><HEAD></HEAD><BODY>
+ <H1>%s</H1><BR>
+ %s</BODY></HTML>
+ """ % (message, (type=="restart") and '<A HREF="/">Restart GNUe
Forms</A>')
+
+def build_loading_page(message):
+ return u"""<HTML><HEAD>
+<meta http-equiv="refresh" content="4; ">
+</HEAD>
+ <BODY>
+ <CENTER>
+ <IMAGE SRC="splashscreen.png">
+ <BR>
+ </CENTER>
+ <H1 ALIGN="CENTER">%s</H1>
+ </BODY>
+</HTML>""" % (message)
+
def build_form(title, header, pages, footer):
#FIXME: use "labelPosition" in TabContainer
return u"""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta name="description" content="GNUe Forms - Interactive HTML
Frontend" />
<title>"""+title+"""</title>
<script type="text/javascript">
- var djConfig = {isDebug: true};
+ var djConfig = {
+ isDebug: true,
+ ieClobberMinimal : true,
+ debugAtAllCosts: true
+ };
// djConfig.debugAtAllCosts = true;
</script>
+ <script language="javascript" type="text/javascript"
src="/incl/firebug/firebug.js"></script>
<script type="text/javascript" src="/incl/dojo.js"></script>
<script language="JavaScript" type="text/javascript">
if (dojo==undefined) {
@@ -152,90 +242,12 @@
dojo.require("dojo.widget.ContentPane")
dojo.require("dojo.widget.TabContainer")
dojo.require("dojo.widget.ComboBox")
+ dojo.require("dojo.widget.Toolbar")
dojo.require("dojo.debug.console")
dojo.require("dojo.io")
dojo.hostenv.writeIncludes()
-
- var updates = {}
- var bindArgs = {
- url: "/jsonrpc",
- type: "text/javascript",
- load: function(type, data, evt){
- updates = eval(data)
- execUpdates()
- }
- }
- function getUid() {
- myURL = window.location.href
- x=myURL.indexOf("/session_")
- return myURL.substring(x+9,x+41)
- }
- function sendCmd(cmd, args) {
- bindArgs.url="/jsonrpc_"+getUid()+"?cmd="+cmd+"&"+args
- dojo.io.bind(bindArgs);
- }
- function execUpdates() {
- for (i in updates) {
- item=updates[i];
- try {
- if (item[0]=="alert") {
- alert(item[2])
- }
- if (item[0]=="status") {
- window.status=item[2]
- }
-
- if (item[0]=="set") {
- elem = dojo.widget.getWidgetById(item[1])
- if (elem==undefined) {
- elem = document.getElementById(item[1])
- }
- elem.value=item[2]
- }
- if (item[0]=="replace") {
- elem = document.getElementById(item[1])
- elem.innerHTML=item[2]
- }
- if (item[0]=="disable") { // disable id true/false
- elem = dojo.widget.getWidgetById(item[1])
- if (elem==undefined) {
- elem = document.getElementById(item[1])
- elem.disabled=item[2];
- } else {
- elem.setDisabled(item[2])
- }
- }
- if (item[0]=="grab_focus") {
- elem = document.getElementById(item[1])
- if (elem==undefined) {
- elem = dojo.widget.getWidgetById(item[1])
- elem.focus()
- } else {
- elem.focus()
- }
- }
- if (item[0]=="set_page") {
- elem = dojo.widget.getWidgetById(item[2])
-
- }
- if (item[0]=="close") {
- // return to main page
- window.location="/"
- }
- }
- catch(err) {
- txt="There was an error on this page.\\n\\n"
- txt+="Id: " + item[1] + "\\n"
- txt+="Value: " + item[2] + "\\n"
- txt+="Error Name: " + err.name + "\\n"
- txt+="Error Message: " + err.message + "\\n\\n"
- txt+="Click OK to continue.\\n\\n"
- // err.fileName + err.lineNumber
- alert(txt)
- }
- }
- }
</script>
+ <script type="text/javascript" src="/incl/gnue.js"></script>
<style>
html, body{
width: 100%; /* make the body expand to fill the visible window */
@@ -253,22 +265,20 @@
.dojoMenuBar2 {
border-top:1px solid #d4d4d4;
}
- .Toolbar {
- background-color: #85AEEC;
- background-image:soriaBarBg.gif;
- background-repeat:repeat-x;
- }
- .Toolbar .dojoButton {
- float: left;
- margin-right: 10px;
- }
- .dojoButton .dojoButtonContents {
- font-size: 6pt;
+ .dojoDialog {
+ background : #eee;
+ border : 1px solid #999;
+ -moz-border-radius : 5px;
+ padding : 4px;
}
</style>
</head>
- <body>""" + header + u"""
+ <body>
+ <a dojoType="dialog" id="basicDialog" toggle="wipe" toggleDuration="250"
+ executeScripts="true" href="base.html"></a>
+
+ """ + header + u"""
<div dojoType="LayoutContainer"
layoutChildPriority='top-bottom'
style="width: 100%; height: 100%;">
Modified: trunk/gnue-forms/src/uidrivers/html/ToolBar.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/ToolBar.py 2007-03-27 18:13:56 UTC
(rev 9450)
+++ trunk/gnue-forms/src/uidrivers/html/ToolBar.py 2007-03-28 12:17:10 UTC
(rev 9451)
@@ -27,8 +27,8 @@
#
from gnue.forms.uidrivers.html.widgets._base import HtmlWidget
-from gnue.forms.uidrivers.html.common import *
-from gnue.forms.uidrivers.html.Generator import build_toolbutton, build_toolbar
+from gnue.forms.uidrivers.html.common import getNextId
+from gnue.forms.uidrivers.html.Generator import *
from gnue.forms.uidrivers._commonGuiToolkit.ToolBar import ToolBar as
_BaseToolBar
from gnue.common.apps import GConfig
@@ -52,8 +52,13 @@
event = 'request' + userAction.event
label = name
tooltip = userAction.description
+ toggleItem = userAction.canToggle
+
+ # create correct event string, in case toolbutton can toggle
+ if toggleItem:
+ toggleItem = 'request' + toggleItem
- dhtml = build_toolbutton(id, label, event, "/icon/%s" % iconloc,
tooltip, "%s")
+ dhtml = build_toolbar_button(id, label, event, "/icon/%s" % iconloc,
tooltip, toggleItem, "%s")
return ToolbarWidget(self.widget, self.driver, 'TOOLBUTTON', dhtml, id)
def get_html(self):
@@ -62,7 +67,7 @@
# Add a separator
def addSeparator(self):
id = getNextId()
- dhtml = ' '
+ dhtml = build_toolbar_separator(id)
return ToolbarWidget(self.widget, self.driver, 'SEPARATOR', dhtml, id)
# Enable a menu item
Modified: trunk/gnue-forms/src/uidrivers/html/UIdriver.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/UIdriver.py 2007-03-27 18:13:56 UTC
(rev 9450)
+++ trunk/gnue-forms/src/uidrivers/html/UIdriver.py 2007-03-28 12:17:10 UTC
(rev 9451)
@@ -45,16 +45,30 @@
_WidgetToGFObj = {}
_WidgetToUIObj = {}
_IdToWidget = {}
+
- def initialize(self):
+ #
---------------------------------------------------------------------------
+ # Constructor
+ #
---------------------------------------------------------------------------
+
+ def __init__ (self, *args, **params):
+ commonToolkit.GFUserInterface.__init__ (self, *args, **params)
+ self.name = "HTML"
+ # self._display = ...
+
+ # self.app = getApp ()
self._htmlapp = gethtmlApp(self)
+
self.textWidth = 12 # The pixel width of text inside a widget
self.textHeight = 24 # The pixel height of text inside a widget
self.widgetWidth = self.textWidth # The pixel width of a 1 char
widget (for things like buttons)
self.widgetHeight = self.textHeight + 5 # The pixel height of a 1
char widget (for things like buttons)
+ assert gDebug (6, "Metrics %s x %s" % (self.textWidth,
self.textHeight))
+
+
def mainLoop(self):
self._htmlapp.MainLoop() # simply call the wxApp's MainLoop method
@@ -73,7 +87,7 @@
"Input routines currently not supported!"
self._UIform._ui_show_message_(message, "", title, cancel)
# FIXME: connect to current open form
- return False
+ return None
#
---------------------------------------------------------------------------
Added: trunk/gnue-forms/src/uidrivers/html/gnue.js
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/gnue.js 2007-03-27 18:13:56 UTC (rev
9450)
+++ trunk/gnue-forms/src/uidrivers/html/gnue.js 2007-03-28 12:17:10 UTC (rev
9451)
@@ -0,0 +1,176 @@
+/* This file is part of GNU Enterprise.
+*
+* GNU Enterprise 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, or (at your option) any later version.
+*
+* GNU Enterprise is distributed in the hope that it will be
+* useful, but WITHOUT ANY WARRANTY; without even the implied
+* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+* PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public
+* License along with program; see the file COPYING. If not,
+* write to the Free Software Foundation, Inc., 59 Temple Place
+* - Suite 330, Boston, MA 02111-1307, USA.
+*
+* Copyright 2000-2007 Free Software Foundation
+*
+* FILE: gnue.js
+*
+* DESCRIPTION: Webfrontend specific javascript code
+*/
+
+function setCursorPosition(oInput,oStart,oEnd) {
+ if( oInput.setSelectionRange ) {
+ oInput.setSelectionRange(oStart,oEnd);
+ }
+ else if( oInput.createTextRange ) {
+ var range = oInput.createTextRange();
+ range.collapse(true);
+ range.moveEnd('character',oEnd);
+ range.moveStart('character',oStart);
+ range.select();
+ }
+ }
+
+ // FIXME: Use prototype instead of event handler per element
+ // dojo.widget.Button.prototype.onClick=function(){}
+ var updates = {}
+ var bindArgs = {
+ url: "/jsonrpc",
+ type: "text/javascript",
+ load: function(type, data, evt){
+ updates = eval(data)
+ execUpdates()
+ }
+ }
+
+function updateWidgets() {
+ list=dojo.widget.manager.getWidgetsByType("TextBox");
+ for (i in list) {
+ list[i].textbox.style.width=list[i].domNode.parentNode.style.width;
+ list[i].textbox.style.height=list[i].domNode.parentNode.style.height;
+ dojo.event.connect(list[i].textbox, "onchange", function(e){
+ sendCmd("onChange","id="+e.target.id+"&text="+e.target.value)
+ }
+ );
+ }
+}
+
+dojo.addOnLoad(updateWidgets);
+
+ function getUid() {
+ myURL = window.location.href
+ x=myURL.indexOf("/session_")
+ return myURL.substring(x+9,x+41)
+ }
+ function sendCmd(cmd, args) {
+ bindArgs.url="/jsonrpc_"+getUid()+"?cmd="+cmd+"&"+args
+ dojo.io.bind(bindArgs);
+ }
+
+ function execUpdates() {
+ for (i in updates) {
+ item=updates[i];
+ try {
+ if (item[0]=="alert") {
+ //alert(item[2])
+ document.getElementById("basic_title").innerHTML=item[1];
+ var msg=item[2];
+ if (msg[0]!="<") { msg="<PRE>"+msg+"</PRE>" };
+ document.getElementById("basic_content").innerHTML=msg;
+ var btn=document.getElementById("basic_button");
+ dlg=dojo.widget.getWidgetById("basicDialog")
+ dlg.setCloseControl(btn);
+ dlg.show()
+ }
+ if (item[0]=="status") {
+ window.status=item[2]
+ }
+
+ if (item[0]=="set") {
+ elem = dojo.widget.getWidgetById(item[1])
+ if (elem==undefined) {
+ elem = document.getElementById(item[1])
+ }
+ if (elem.textbox!=undefined) {
+ elem.textbox.value=item[2];
+ } else {
+ elem.value=item[2];
+ }
+ }
+ if (item[0]=="replace") {
+ elem = document.getElementById(item[1])
+ elem.innerHTML=item[2]
+ }
+ if (item[0]=="disable") { // disable id true/false
+ elem = dojo.widget.getWidgetById(item[1])
+ if (elem==undefined) {
+ elem = document.getElementById(item[1])
+ elem.disabled=item[2];
+ } else {
+ if (item[2]==true) {
+ elem.disable()
+ } else {
+ elem.enable()
+ }
+ }
+ }
+ if (item[0]=="activate") { // toggle id
+ elem = dojo.widget.getWidgetById(item[1])
+ if (!(elem==undefined)) {
+ if (item[2]==true) {
+ elem.select()
+ } else {
+ elem.deselect()
+ }
+ }
+ }
+ if (item[0]=="grab_focus") {
+ elem = document.getElementById(item[1])
+ if (elem==undefined) {
+ elem = dojo.widget.getWidgetById(item[1])
+ elem.focus()
+ } else {
+ elem.focus()
+ }
+ }
+ if (item[0]=="set_page") {
+ elem = dojo.widget.getWidgetById(item[2])
+
+ }
+ if (item[0]=="set_cursor") {
+ elem = document.getElementById(item[1])
+ if (elem==undefined) {
+ elem = dojo.widget.getWidgetById(item[1])
+ }
+ setCursorPosition(elem,item[2],item[2])
+ }
+ if (item[0]=="select_region") {
+ elem = document.getElementById(item[1])
+ if (elem==undefined) {
+ elem = dojo.widget.getWidgetById(item[1])
+ }
+ selection_start = item[2][0]
+ selection_end = item[2][1]
+ setCursorPosition(elem,selection_start,selection_end )
+ }
+ if (item[0]=="close") {
+ // return to main page
+ window.location="/"
+ }
+ }
+ catch(err) {
+ txt="There was an error on this page.\\n\\n"
+ txt+="Id: " + item[1] + "\\n"
+ txt+="Value: " + item[2] + "\\n"
+ txt+="Error Name: " + err.name + "\\n"
+ txt+="Error Message: " + err.message + "\\n\\n"
+ txt+="Click OK to continue.\\n\\n"
+ // err.fileName + err.lineNumber
+ dojo.debug(txt)
+ }
+ }
+ }
Property changes on: trunk/gnue-forms/src/uidrivers/html/gnue.js
___________________________________________________________________
Name: svn:executable
+ *
Modified: trunk/gnue-forms/src/uidrivers/html/widgets/entry.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/widgets/entry.py 2007-03-27
18:13:56 UTC (rev 9450)
+++ trunk/gnue-forms/src/uidrivers/html/widgets/entry.py 2007-03-28
12:17:10 UTC (rev 9451)
@@ -39,7 +39,6 @@
if object.style == 'dropdown' or \
object.style == 'listbox':
choices = []
- # FIXME: choices get initialized in _ui_set_choices_()
if object.style == "listbox":
dhtml=build_entry_listbox(id, "%s", choices,
object.Char__height,
@@ -68,10 +67,16 @@
self.itemY, self.itemWidth, \
self.itemHeight)
- else: # normal text box
+ else: # normal text box - just digits
+ textbox_style = "Textbox"
+ # Textbox", IntegerTextbox, DateTextbox, TimeTextbox
dhtml = build_entry_default(id, "%s",
object.Char__x*event.widgetWidth,\
- self.itemY, self.itemWidth,
self.itemHeight)
+ self.itemY, self.itemWidth,
self.itemHeight,
+ textbox_style)
+ # ["set_cursor", "141", 0], ["select_region", "141", [0, 0]]]
+
+
newWidget = HtmlEntryWidget(event.container, self._uiDriver, 'ENTRY',
dhtml, id)
newWidget.style=object.style
@@ -92,7 +97,16 @@
def _ui_disable_(self, index):
self.widgets[index].set_sensitive(False)
+ #
---------------------------------------------------------------------------
+ # Set "editable" status for this widget
+ #
---------------------------------------------------------------------------
+ def _ui_set_editable_(self, index, editable):
+
+ # FIXME: grey out entry, disallow changes if possible
+ pass
+
+
#
---------------------------------------------------------------------------
# Set the cursor position in a widget to position
#
---------------------------------------------------------------------------
@@ -106,7 +120,44 @@
widget.set_cursor_pos(position)
+ # -------------------------------------------------------------------------
+ def _ui_copy_(self, index):
+
+ widget = self.widgets[index]
+
+ if hasattr(widget, 'copy_clipboard'):
+ widget.copy_clipboard()
+
+ # -------------------------------------------------------------------------
+
+ def _ui_paste_(self, index):
+
+ widget = self.widgets[index]
+
+ if hasattr(widget, 'paste_clipboard'):
+ widget.paste_clipboard()
+
+ # -------------------------------------------------------------------------
+
+ def _ui_select_all_(self, index):
+
+ widget = self.widgets[index]
+
+ if hasattr(widget, 'select_region'):
+ widget.set_position(-1)
+ pos = widget.get_position()
+ widget.select_region(0, -1)
+ bounds = widget.get_selection_bounds()
+ # There seems to be no event that is fired when the selection of an
+ # entry changes, so we must notify the GF layer ourselves.
+ # FIXME: This also means that selecting "Select All" from the
+ # context menu of the entry doesn't work.
+ self._request('SELECTWITHMOUSE', position1=bounds[0],
+ position2=bounds[1], cursor=pos)
+
+
+
#
---------------------------------------------------------------------------
# set the selected area
#
---------------------------------------------------------------------------
Modified: trunk/gnue-forms/src/uidrivers/html/widgets/form.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/html/widgets/form.py 2007-03-27 18:13:56 UTC
(rev 9450)
+++ trunk/gnue-forms/src/uidrivers/html/widgets/form.py 2007-03-28 12:17:10 UTC
(rev 9451)
@@ -61,7 +61,7 @@
# FIXME: add dialogs
else:
newWidget = HtmlWidget(event.container, self._uiDriver, 'FORM',
dhtml, getNextId())
-
+
self.mainWindow = newWidget
self.mainWindow.updates = []
@@ -149,7 +149,7 @@
def _ui_update_status_ (self, tip, record_status, insert_status,
record_number, record_count, page_number, page_count):
- # create and update status bar
+ # TODO: create and update status bar
pass
@@ -170,11 +170,18 @@
@return: True if the Ok-, Close-, or Yes-button was pressed, False if
the
No-button was pressed or None if the Cancel-button was pressed.
"""
- # FIXME: Display dialog box
- self.mainWindow.updates.append(["alert","",message])
- return False
+ result=True
+ if cancel or kind=="Question":
+ id=23242
+ self.mainWindow.updates.append(["message",id,[message,kind, title,
cancel]])
+ result=self.mainWindow.controller.waitResult(id)
+ else:
+ self.mainWindow.updates.append(["alert",title,message])
+ return result
+
+
#
---------------------------------------------------------------------------
# Display an about box
#
---------------------------------------------------------------------------
@@ -186,7 +193,7 @@
Author: %s
Description: %s
""") % (name, version, author, description)
- self.mainWindow.updates.append(["alert","",message])
+ self.mainWindow.updates.append(["alert","About",message])
#
---------------------------------------------------------------------------
# Print form screenshot
@@ -194,7 +201,7 @@
def _ui_printout_(self, title, subtitle, user):
message = u_("Printout currently not supported")
- self.mainWindow.updates.append(["alert","",message])
+ self.mainWindow.updates.append(["alert","Info",message])
#
---------------------------------------------------------------------------
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r9451 - in trunk/gnue-forms/src/uidrivers/html: . widgets,
jan <=