source: trunk/src/testing/ui/Mywx.py @ 4

Revision 4, 35.9 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1############################################################################
2#
3# SAGE UI - A Graphical User Interface for SAGE
4# Copyright (C) 2005 Electronic Visualization Laboratory,
5# University of Illinois at Chicago
6#
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions are met:
11#
12#  * Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14#  * Redistributions in binary form must reproduce the above
15#    copyright notice, this list of conditions and the following disclaimer
16#    in the documentation and/or other materials provided with the distribution.
17#  * Neither the name of the University of Illinois at Chicago nor
18#    the names of its contributors may be used to endorse or promote
19#    products derived from this software without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32#
33# Direct questions, comments etc about SAGE UI to www.evl.uic.edu/cavern/forum
34#
35# Author: Ratko Jagodic
36#       
37############################################################################
38
39
40import wx, os, os.path, socket, math
41from globals import *
42import wx.lib.foldpanelbar as fpb
43import preferences as prefs
44
45
46############################################################################
47#
48#  CLASS: MyImage
49
50#  DESCRIPTION: This is just a data storage class for decorative bitmaps used
51#               in the ui. You need to pass it a bitmap and optionally position,
52#               transparency and new size. If the new size is passed in, the
53#               bitmap will be automatically resized to that size.
54#
55#  DATE:        March, 2005
56#
57############################################################################
58
59class MyImage(wx.Object):
60
61    def __init__(self, bitmap, x=0, y=0, transparent=False, resizeWidth=0, resizeHeight=0):
62        self.image = wx.Image(ConvertPath(str(bitmap)))
63        self.x = x
64        self.y = y
65        self.transparent = transparent
66        if resizeHeight != 0:  # you can resize the image during creation
67            self.Rescale(resizeWidth, resizeHeight)
68        else:
69            self.bitmap = wx.BitmapFromImage(self.image)#.ConvertToBitmap()
70
71    def GetBitmap(self):
72        return self.bitmap
73
74    def GetWidth(self):
75        return self.bitmap.GetWidth()
76
77    def GetHeight(self):
78        return self.bitmap.GetHeight()
79
80    def SetX(self, x):
81        self.x = x
82
83    def SetY(self, y):
84        self.y = y
85
86    def GetY(self):
87        return self.y
88
89    def GetX(self):
90        return self.x
91
92    def IsTransparent(self):
93        return self.transparent
94
95    def Rescale(self, newWidth, newHeight):
96        if newWidth < 1:
97            newWidth = 1
98        if newHeight < 1:
99            newHeight = 1
100        self.bitmap = wx.BitmapFromImage(self.image.Rescale( round(newWidth), round(newHeight) ))#.ConvertToBitmap()
101        return self.bitmap
102
103
104    def Recalculate(self, newWidth, newHeight, x=-1, y=-1):
105        # set the position if it was passed in
106        if x != -1:
107            self.x = x
108        if y != -1:
109            self.y = y
110           
111        return self.Rescale(newWidth, newHeight)
112
113
114    def Hide(self):
115        if not self.IsTransparent():
116            self.transparent = True
117
118    def Show(self):
119        if self.IsTransparent():
120            self.transparent = False
121
122
123############################################################################
124#
125#  CLASS: MyBitmapButton
126
127#  DESCRIPTION: A template class for a bitmap button. It handles the images,
128#               resizes them and changes them based on the state of the button.
129#               It also handles basic painting (just draws the button on the
130#               screen). All bitmap buttons should extend this class and
131#               override some methods for specific behavior. In most cases
132#               OnLeftUp() will have to be overwritten to define what happens
133#               on a mouse click. In your overwride a method make sure you call
134#               the same named method of this class since that will visually
135#               update the button.
136#
137#  DATE:        March, 2005
138#
139############################################################################
140
141class MyBitmapButton(wx.Window):
142
143    def __init__(self, parent, (x,y), (resizeWidth, resizeHeight), up_bitmap, down_bitmap=None, over_bitmap=None, tTip="", id=-1 ):       
144        # call the superclass' constructor
145        wx.Window.__init__(self, parent, id, (x,y), (resizeWidth, resizeHeight), wx.NO_BORDER | wx.FULL_REPAINT_ON_RESIZE)
146        self.parent = parent
147
148        self.tTip = tTip
149       
150        if self.tTip != "":
151            self.toolTip = wx.ToolTip( self.tTip )
152            self.toolTip.SetDelay( 100 )
153            self.SetToolTip( self.toolTip )
154
155        self.resizeWidth = resizeWidth
156        self.resizeHeight = resizeHeight
157
158        # get the images and rescale them
159        if down_bitmap == None:
160            down_bitmap = up_bitmap
161        self.up_image = wx.Image(ConvertPath( str(up_bitmap) ))
162        self.down_image = wx.Image(ConvertPath( str(down_bitmap) ))
163        self.up_bitmap = self.RescaleBitmap(self.up_image, resizeWidth, resizeHeight)
164        self.down_bitmap = self.RescaleBitmap(self.down_image, resizeWidth, resizeHeight)
165        if over_bitmap:
166            self.over_image = wx.Image(ConvertPath( str(over_bitmap) ))
167            self.over_bitmap = self.RescaleBitmap(self.over_image, resizeWidth, resizeHeight)
168        self.currentImage = self.up_image
169        self.currentBitmap = self.up_bitmap
170
171        # register events and the event handlers
172        self.Bind( wx.EVT_LEFT_UP, self.OnLeftUp )
173        self.Bind( wx.EVT_LEFT_DOWN, self.OnLeftDown )
174        self.Bind( wx.EVT_RIGHT_UP, self.OnRightUp )
175        self.Bind( wx.EVT_RIGHT_DOWN, self.OnRightDown )
176        self.Bind( wx.EVT_ENTER_WINDOW, self.OnMouseEnter )
177        self.Bind( wx.EVT_LEAVE_WINDOW, self.OnMouseLeave )
178        self.Bind( wx.EVT_PAINT, self.OnPaint )
179        self.Bind( wx.EVT_ERASE_BACKGROUND, self.Chillout)
180
181
182    def Chillout(self, event):
183        pass   # this intercepts the ERASE_BACKGROUND event and therefore minimizes the flicker
184
185
186    def Rescale(self, newWidth, newHeight):
187        self.up_bitmap = self.RescaleBitmap(self.up_image, newWidth, newHeight)
188        self.down_bitmap = self.RescaleBitmap(self.down_image, newWidth, newHeight)
189        self.currentBitmap = self.RescaleBitmap(self.currentImage, newWidth, newHeight)
190        if hasattr(self, "over_bitmap"):
191            self.over_bitmap = self.RescaleBitmap(self.over_image, newWidth, newHeight)
192        self.SetSize( (newWidth, newHeight) )
193           
194    def RescaleBitmap(self, image, newWidth, newHeight):
195        if newWidth < 1:
196            newWidth = 1
197        if newHeight < 1:
198            newHeight = 1
199        bitmap = wx.BitmapFromImage(image.Rescale( round(newWidth), round(newHeight) )) #.ConvertToBitmap()
200        return bitmap
201
202
203    def SetUpBitmap(self, newBitmap):
204        self.up_image = wx.Image(ConvertPath( str(newBitmap) ))
205        self.up_bitmap = self.RescaleBitmap(self.up_image, self.resizeWidth, self.resizeHeight)
206
207    def SetDownBitmap(self, newBitmap):
208        self.down_image = wx.Image(ConvertPath( str(newBitmap) ))
209        self.down_bitmap = self.RescaleBitmap(self.down_image, self.resizeWidth, self.resizeHeight)
210
211    def SetOverBitmap(self, newBitmap):
212        self.over_image = wx.Image(ConvertPath( str(newBitmap) ))
213        self.over_bitmap = self.RescaleBitmap(self.over_image, self.resizeWidth, self.resizeHeight)
214
215       
216    #  event handlers
217    def OnPaint(self, event=None):
218        if not event == None:   
219            dc = wx.PaintDC(self)
220        else:
221            if "__WXMAC__" in wx.PlatformInfo:
222                self.Refresh()
223                return
224            dc = wx.ClientDC(self)
225        dc.DrawBitmap( self.currentBitmap, 0, 0, True )
226
227    def OnMouseEnter(self, event):       
228        if hasattr(self, "over_bitmap"):
229            self.currentBitmap = self.over_bitmap
230            self.currentImage = self.over_image
231            self.OnPaint()
232       
233    def OnMouseLeave(self, event):
234        self.currentBitmap = self.up_bitmap
235        self.currentImage = self.up_image
236        self.OnPaint()
237   
238    def OnLeftUp(self, event):
239        self.currentBitmap = self.up_bitmap
240        self.currentImage = self.up_image
241        self.OnPaint()
242
243    def OnLeftDown(self, event):
244        self.currentBitmap = self.down_bitmap
245        self.currentImage = self.down_image
246        self.OnPaint()
247
248    def OnRightUp(self, event):
249        self.currentBitmap = self.up_bitmap
250        self.currentImage = self.up_image
251        self.OnPaint()
252
253    def OnRightDown(self, event):
254        self.currentBitmap = self.down_bitmap
255        self.currentImage = self.down_image
256        self.OnPaint()
257       
258       
259           
260
261
262############################################################################
263#
264#  CLASS: AppButton
265
266#  DESCRIPTION: This class describes the buttons with which you start apps.
267#               It extends MyBitmapButton and adds a few methods for specific
268#               stuff. Also, all the app buttons are anchors for all the
269#               instances of that particular application. This class creates,
270#               positions and draws all of the InstanceButtons.
271#
272#  DATE:        March, 2005
273#
274############################################################################
275
276class AppButton(MyBitmapButton):   
277
278    def __init__(self, parent, up_bitmap, down_bitmap, over_bitmap, (x,y), (resizeWidth, resizeHeight), app):
279        tTip = "-- "+app.GetName().upper()+" --\nLEFT click to start application normally.\nRIGHT click to start the application through sageBridge for sharing."
280        if not os.path.isfile(over_bitmap):
281            over_bitmap = up_bitmap
282        MyBitmapButton.__init__(self, parent, (x,y), (resizeWidth, resizeHeight), up_bitmap, down_bitmap, over_bitmap, tTip)#app.GetName() )
283        self.SetName( app.GetName() )
284        self.app = app
285        self.leftClick = True   #a hack to detect which mouse button was clicked (used in config menu popup)
286        self.instanceButtons = {}  #keyed by windowId
287
288   
289    def AddConfigMenu(self, app):
290        # make the config popup menu (ids of the menuItems are the config numbers)
291        self.configMenu = wx.Menu()
292        num = 1
293        configs = self.app.GetConfigNames()
294        configs.sort(lambda x, y: cmp(x.lower(), y.lower()))
295        for configName in configs:
296            menuItem = self.configMenu.Append( num, configName )
297            self.configMenu.Bind(wx.EVT_MENU, self.OnConfigMenuItem, menuItem)
298            num+=1
299            #self.configMenu.Bind(wx.EVT_MENU_HIGHLIGHT_ALL, self.OnMenuItemHighlight, menuItem)
300        #self.configMenu.Bind(wx.EVT_MENU_CLOSE, self.OnCloseMenu)
301           
302
303    def AddInstanceButton(self, sageApp):
304        size = (16, 30)
305        x = self.GetPosition().x + (self.GetSize().GetWidth() - size[0]) / 2
306        y = self.GetPosition().y + self.GetSize().GetHeight() + len(self.instanceButtons)*size[1]
307        self.instanceButtons[ sageApp.getId() ] = InstanceButton(self, (x,y), size, "images/inst_up.jpg", "images/inst_up.jpg", "images/inst_down.jpg", sageApp)
308        self.OnPaint()
309
310    def RemoveInstanceButton(self, windowId):
311        self.instanceButtons[ windowId ].Destroy()  #remove the InstanceButton
312        del self.instanceButtons[ windowId ]  #remove it from the hash
313        self.OnPaint()
314
315
316    #  EVENT HANDLERS
317    def OnPaint(self, event=None):
318        if not event == None:   
319            dc = wx.PaintDC(self.parent)
320            MyBitmapButton.OnPaint(self, event)
321        else:
322            if "__WXMAC__" in wx.PlatformInfo:
323                self.Refresh()
324                return
325            dc = wx.ClientDC(self.parent)
326            MyBitmapButton.OnPaint(self)
327       
328        # then draw the instance buttons (update their position first)
329        yOffset = 0
330        for id, instance in self.instanceButtons.iteritems():
331            instance.MoveXY( self.GetPosition().x + (self.GetSize().GetWidth() - instance.GetSize().GetWidth()) / 2,
332                             self.GetPosition().y + self.GetSize().GetHeight() + yOffset*instance.GetSize().GetHeight())
333            yOffset = yOffset + 1
334            instance.Refresh()#OnPaint(event)
335
336       
337    def OnConfigMenuItem(self, event):
338        self.currentBitmap = self.up_bitmap
339        configName = self.configMenu.GetLabel(event.GetId())
340
341        # check if the user pressed on a vnc button... if so, add some vnc specific params
342        if self.GetName().lower().find("vnc") == -1:
343            if self.leftClick:
344                res = self.parent.parent.sageGate.executeApp(self.GetName(), configName)
345            else:
346                res = self.parent.parent.sageGate.executeApp(self.GetName(), configName, useBridge=True)
347        else:
348            myIP = socket.gethostbyname(socket.gethostname())
349            displayNum = "0"
350            displaySize = wx.DisplaySize()
351            res = self.__ShowSimpleVNCDialog(myIP, displayNum, displaySize)
352            if res: params=res[1]; displaySize=res[0]
353            else: return
354
355            if self.leftClick:
356                res = self.parent.parent.sageGate.executeApp(self.GetName(), configName, size=displaySize, optionalArgs=params)
357            else:
358                res = self.parent.parent.sageGate.executeApp(self.GetName(), configName, size=displaySize, optionalArgs=params, useBridge=True)
359
360        if res == -1:
361            Message("Application not started. Either application failed or the application launcher is not running", "Application Launch Failed")
362
363
364##     def __EncryptPassword(self, passwd):
365##         key = chr(23)+chr(82)+chr(107)+chr(6)+chr(35)+chr(78)+chr(88)+chr(7)
366##         obj = pyDes.des(key, pyDes.CBC, "\0\0\0\0\0\0\0\0")
367##         string = obj.encrypt(passwd, "\0")
368##         #print "string = ",string.decode("ascii")#, 'replace')
369##         return string.decode("utf-16")#, 'replace')
370
371
372    def __ShowSimpleVNCDialog(self, myIP, displayNum, displaySize):#, password):
373        def __CaptureReturn(event):
374            if event.GetKeyCode() == wx.WXK_RETURN or event.GetKeyCode() == wx.WXK_NUMPAD_ENTER:
375                dialog.EndModal(wx.ID_OK)
376            else:
377                event.Skip()
378               
379        # make the dialog
380        if "__WXMSW__" in wx.PlatformInfo:
381            dialog = wx.Dialog(self, wx.ID_ANY, "Desktop Sharing")
382        else:
383            dialog = wx.Dialog(self, wx.ID_ANY, "Desktop Sharing", style=wx.RESIZE_BORDER | wx.CLOSE_BOX)
384        dialog.SetBackgroundColour(dialogColor)
385        dialog.SetForegroundColour(wx.WHITE)
386
387        # make the control
388        ipText = wx.StaticText(dialog, wx.ID_ANY, "IP Address:")
389        ipField = wx.TextCtrl(dialog, wx.ID_ANY, myIP)
390        displayNumText = wx.StaticText(dialog, wx.ID_ANY, "Display Number:")
391        displayNumField = wx.TextCtrl(dialog, wx.ID_ANY, displayNum)
392        sizeText = wx.StaticText(dialog, wx.ID_ANY, "Screen Size:")
393        widthText = wx.StaticText(dialog, wx.ID_ANY, "W")
394        widthField = wx.TextCtrl(dialog, wx.ID_ANY,str(displaySize[0]))
395        heightText = wx.StaticText(dialog, wx.ID_ANY, "H")
396        heightField = wx.TextCtrl(dialog, wx.ID_ANY,str(displaySize[1]))
397        passwordText = wx.StaticText(dialog, wx.ID_ANY, "Password:")
398        passwordField = wx.TextCtrl(dialog, wx.ID_ANY, style=wx.TE_PASSWORD)
399        passwordField.SetFocus()
400        passwordField.Bind(wx.EVT_KEY_DOWN, __CaptureReturn)
401        okBtn = wx.Button(dialog, wx.ID_OK, "Share Desktop")
402
403        # layout (sizers)
404        horSizer = wx.BoxSizer(wx.HORIZONTAL)
405        horSizer.Add(widthText, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, border=3)
406        horSizer.Add(widthField, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT, border=3)
407        horSizer.Add(heightText, 0, wx.ALIGN_RIGHT | wx.LEFT | wx.RIGHT | wx.TOP, border=3)
408        horSizer.Add(heightField, 0, wx.ALIGN_RIGHT | wx.LEFT | wx.RIGHT, border=3)
409       
410        gridSizer = wx.FlexGridSizer(4, 2, 2, 4)
411        gridSizer.AddMany([ (ipText, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.TOP, 3), (ipField, 0, wx.EXPAND),
412                     (displayNumText, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.TOP, 3), (displayNumField, 0, wx.EXPAND),
413                     (sizeText, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.TOP, 3), (horSizer, 0),
414                     (passwordText, 1, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.TOP, 3), (passwordField, 0, wx.EXPAND)
415                   ])
416        gridSizer.AddGrowableCol(0)
417
418        mainSizer = wx.BoxSizer(wx.VERTICAL)
419        mainSizer.Add(gridSizer, 1, wx.ALIGN_LEFT | wx.EXPAND | wx.ALL, border=5)
420        mainSizer.Add(okBtn, 0, wx.ALIGN_CENTRE | wx.BOTTOM | wx.TOP, border=10)
421
422        # do the size stuff with some corrections because of the FoldPanelBar complications
423        dialog.SetSizer(mainSizer)
424        dialog.Fit()
425
426        # show it and get the result
427        if dialog.ShowModal() == wx.ID_OK:
428            ip = ipField.GetValue().strip()
429            dispNum = displayNumField.GetValue().strip()
430            w = widthField.GetValue().strip()
431            h = heightField.GetValue().strip()
432            passwd = passwordField.GetValue().strip()
433            return ((int(w),int(h)), (ip+" "+dispNum+" "+w+" "+h+" "+ passwd))
434        else:
435            return False
436
437
438
439
440    def __ShowVNCDialog(self, myIP, displayNum, displaySize, password):
441        def __OnStateChange(evt):
442            isExpanded = evt.GetFoldStatus()
443            s = dialog.GetSize()
444            if isExpanded:
445                dialog.SetSize((s[0], s[1]-150))
446            else:
447                dialog.SetSize((s[0], s[1]+150))
448            evt.Skip()
449
450        def __GetControlValues():
451            ip = ipField.GetValue()
452            dispNum = displayNumField.GetValue()
453            size = sizeField.GetValue().lower()
454            if "x" in size:
455                size = size.split("x")
456            elif "*" in size:
457                size = size.split("*")
458            else:
459                size = (1024, 768)
460            passwd = passwordField.GetValue()
461            profile = profileField.GetValue()
462            return (ip, dispNum, (int(size[0]), int(size[1])), passwd, profile)
463
464        def __FillControls(profile):#, ip, dispNum, size, passwd):
465            (myIP, displayNum, displaySize, password) = prefs.vnc.GetProfile(profile)
466            ipField.SetValue(myIP)
467            displayNumField.SetValue(displayNum)
468            sizeField.SetValue(str(displaySize[0])+" x "+str(displaySize[1]))
469            passwordField.SetValue(password)
470            profileField.SetValue(profile)
471           
472        def __OnComboBox(evt):
473            __FillControls( profileCombo.GetStringSelection() )
474           
475
476        def __OnDelete(evt):
477            sel = profileCombo.GetStringSelection()
478            if sel == "My Desktop":
479                return  # do not allow the deletion of the default profile
480            prefs.vnc.DeleteProfile( sel )
481            profileCombo.Delete( profileCombo.GetSelection() )
482            profileCombo.SetSelection(0)
483            __FillControls( profileCombo.GetStringSelection() )
484               
485        if "__WXMSW__" in wx.PlatformInfo:
486            dialog = wx.Dialog(self, wx.ID_ANY, "VNC Setup")#, style=wx.CLOSE_BOX)
487        else:
488            dialog = wx.Dialog(self, wx.ID_ANY, "VNC Setup", style=wx.RESIZE_BORDER | wx.CLOSE_BOX)#, style=wx.CLOSE_BOX | wx.THICK_FRAME)
489
490
491        foldBar = fpb.FoldPanelBar(dialog, wx.ID_ANY)#, wx.DefaultPosition, wx.DefaultSize, fpb.FPB_DEFAULT_STYLE | fpb.FPB_VERTICAL)
492        foldBar.Bind(fpb.EVT_CAPTIONBAR, __OnStateChange)
493        foldPanel = foldBar.AddFoldPanel("Advanced Options", collapsed=True)
494        p = wx.Panel(foldPanel, wx.ID_ANY)
495
496        # store the default vnc values... or if the default already exists, load it
497        if prefs.vnc.ProfileExists("My Desktop"):
498            # compare the IPs of the current machine and the stored profile
499            # if they are the same, use those values, otherwise use the detected values
500            defaultProfile = prefs.vnc.GetProfile("My Desktop")
501            if defaultProfile[0] == myIP:
502                (myIP, displayNum, displaySize, password) = defaultProfile
503        prefs.vnc.AddProfile("My Desktop", myIP, displayNum, displaySize, password)
504       
505        # controls
506        text = wx.StaticText(dialog, wx.ID_ANY, "VNC Profile:")
507        profileCombo = wx.ComboBox(dialog, wx.ID_ANY, "My Desktop", choices=prefs.vnc.GetProfileList(), style=wx.CB_DROPDOWN|wx.CB_READONLY)
508        profileCombo.SetMinSize((130, profileCombo.GetSize()[1]))
509        dialog.Bind(wx.EVT_COMBOBOX, __OnComboBox)
510       
511        ipText = wx.StaticText(p, wx.ID_ANY, "The IP ADDRESS of the machine you are trying to show:")
512        ipField = wx.TextCtrl(p, wx.ID_ANY)
513        ipField.SetMinSize((100, ipField.GetSize()[1]))
514        displayNumText = wx.StaticText(p, wx.ID_ANY, "The DISPLAY NUMBER where the VNC server is running (Linux or Mac):")
515        displayNumField = wx.TextCtrl(p, wx.ID_ANY)
516        sizeText = wx.StaticText(p, wx.ID_ANY, "The SIZE of the desktop you are trying to show (width x height):")
517        sizeField = wx.TextCtrl(p, wx.ID_ANY)
518        passwordText = wx.StaticText(p, wx.ID_ANY, "The PASSWORD for your vnc server:")
519        passwordField = wx.TextCtrl(p, wx.ID_ANY, style=wx.TE_PASSWORD)
520        profileText = wx.StaticText(p, wx.ID_ANY, "Save this profile as: ")
521        profileField = wx.TextCtrl(p, wx.ID_ANY)
522        profileField.SetMinSize((100, profileField.GetSize()[1]))
523        deleteBtn = wx.Button(p, wx.ID_ANY, "Delete")
524        p.Bind(wx.EVT_BUTTON, __OnDelete)
525        okBtn = wx.Button(dialog, wx.ID_OK, "Show")
526        __FillControls("My Desktop")
527
528        # layout (sizers)
529        horSizer2 = wx.BoxSizer(wx.HORIZONTAL)
530        horSizer2.Add(text, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, border=10)
531        horSizer2.Add(profileCombo, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
532       
533        gridSizer = wx.FlexGridSizer(4, 2, 2, 0)
534        gridSizer.AddMany([ (ipText, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL), (ipField, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL),
535                     (displayNumText, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL), (displayNumField, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL),
536                     (sizeText, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL), (sizeField, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL),
537                     (passwordText, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL), (passwordField, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
538                   ])
539        gridSizer.AddGrowableCol(0)
540
541        horSizer = wx.BoxSizer(wx.HORIZONTAL)
542        horSizer.Add((0,0), 1)
543        horSizer.Add(profileText, 0, wx.ALIGN_CENTER)
544        horSizer.Add(profileField, 0, wx.ALIGN_CENTER)
545        horSizer.Add((0,0), 1)
546        horSizer.Add(deleteBtn, 0, wx.ALIGN_RIGHT)
547
548        vertSizer = wx.BoxSizer(wx.VERTICAL)
549        vertSizer.Add(gridSizer, 1, wx.EXPAND | wx.ALIGN_TOP)
550        vertSizer.Add(horSizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_TOP | wx.TOP, border=5)
551        vertSizer.Add(wx.StaticLine(p), 0, wx.ALIGN_TOP | wx.EXPAND | wx.TOP, border=10)
552       
553        p.SetSizer(vertSizer)
554        p.Fit()
555        foldBar.AddFoldPanelWindow(foldPanel, p, fpb.FPB_ALIGN_LEFT)
556       
557        mainSizer = wx.BoxSizer(wx.VERTICAL)
558        mainSizer.Add(horSizer2, 0, wx.ALIGN_LEFT | wx.LEFT | wx.TOP | wx.BOTTOM, border=10)
559        mainSizer.Add(foldBar, 1, wx.ALIGN_LEFT | wx.EXPAND | wx.ALL, border=5)
560        mainSizer.Add(okBtn, 0, wx.ALIGN_CENTRE | wx.BOTTOM | wx.TOP, border=10)
561
562        # do the size stuff with some corrections because of the FoldPanelBar complications
563        dialog.SetSizer(mainSizer)
564        dialog.Fit()
565        minS = vertSizer.GetMinSize()
566        s=dialog.GetSize()
567        if s[0] < minS: dialog.SetSize((minS[0]+20, s[1]+10))
568       
569       
570        # show it and get the result
571        if dialog.ShowModal() == wx.ID_OK:
572            (ip, dispNum, size, passwd, profile) = __GetControlValues()
573            (w, h) = size
574            prefs.vnc.AddProfile(profile, ip, dispNum, size, passwd)
575            return (size, (ip+" "+str(dispNum)+" "+str(w)+" "+str(h)+" "+ str(passwd))) #self.__EncryptPassword(str(passwd))))
576        else:
577            return False
578
579       
580    def OnLeftDown(self, event):
581        MyBitmapButton.OnLeftDown(self, event)
582        if "imageviewer" in self.GetName() or "mplayer" in self.GetName():
583            Message("You cannot start these directly. Please use the file library to show multimedia files (F2)", "")
584        else:
585            self.leftClick = True #a hack to detect which mouse button was clicked
586            self.PopupMenu(self.configMenu)#, event.GetPosition())
587            self.OnPaint()
588       
589
590    def OnRightDown(self, event):
591        MyBitmapButton.OnRightDown(self, event)
592        if "imageviewer" in self.GetName() or "mplayer" in self.GetName():
593            Message("You cannot start these directly. Please use the file library to show multimedia files (F2)", "")
594        else:
595            self.leftClick = False  #a hack to detect which mouse button was clicked
596            self.PopupMenu(self.configMenu)#, event.GetPosition())
597            self.OnPaint()
598
599
600
601
602class RemoteAppButton(MyBitmapButton):
603    def __init__(self, parent, up_bitmap, down_bitmap, over_bitmap, (x,y), (resizeWidth, resizeHeight), sageGate):
604        tTip = "-- REMOTE APPLICATIONS --\nLEFT click to start application normally.\nRIGHT click to start the application through sageBridge for sharing."
605        if not os.path.isfile(over_bitmap):
606            over_bitmap = up_bitmap
607        MyBitmapButton.__init__(self, parent, (x,y), (resizeWidth, resizeHeight), up_bitmap, down_bitmap, over_bitmap, tTip)
608        self.SetName("REMOTE APPLICATIONS")
609        self.sageGate = sageGate
610        self.leftClick = True   #a hack to detect which mouse button was clicked (used in config menu popup)
611        #self.AddLauncherMenu()
612
613       
614    def AddLauncherMenu(self):
615        self.launcherMenu = wx.Menu()
616        launcherHash = self.sageGate.getLaunchers()
617
618        # appLaunchers
619        k=1
620       
621        # sort the appLaunchers by name
622        launchers = launcherHash.values()
623        launchers.sort(lambda x, y: cmp(x.getName().lower(), y.getName().lower()))
624       
625        for l in launchers:   
626
627            # applications
628            i = k*100
629            appMenu = wx.Menu()
630            appHash = l.getAppList()
631            appList = appHash.keys()
632            appList.sort(lambda x, y: cmp(x.lower(), y.lower()))
633            for appName in appList:   
634                configList = appHash[appName]
635                configList.sort(lambda x, y: cmp(x.lower(), y.lower()))
636               
637                # app configs
638                j=i*100
639                configMenu = wx.Menu()
640                for appConfig in configList:
641                    item = configMenu.Append(j, appConfig, help=l.getId())
642                    j+=1
643                    self.Bind(wx.EVT_MENU, self.OnConfigMenu, item)
644                   
645                mi = appMenu.AppendMenu(i, appName, configMenu, l.getId())
646                i+=1
647               
648            menuItem = self.launcherMenu.AppendMenu(k, l.getName(), appMenu, l.getId())
649            k+=1
650           
651   
652
653    #  EVENT HANDLERS
654    def OnPaint(self, event=None):
655        if not event == None:   
656            dc = wx.PaintDC(self.parent)
657            MyBitmapButton.OnPaint(self, event)
658        else:
659            if "__WXMAC__" in wx.PlatformInfo:
660                self.Refresh()
661                return
662            dc = wx.ClientDC(self.parent)
663            MyBitmapButton.OnPaint(self)
664
665
666    def OnConfigMenu(self, event):
667        configId = event.GetId()
668        windowId =  int(math.floor(configId/100))
669        lId = int(math.floor(windowId/100))
670
671        launcherMenu = self.launcherMenu.FindItemById(lId).GetSubMenu()
672        appMenuItem = launcherMenu.FindItemById(windowId)
673        appMenu = appMenuItem.GetSubMenu()
674        configMenuItem = appMenu.FindItemById(configId)
675        configMenu = configMenuItem.GetSubMenu()
676       
677        appName = appMenuItem.GetLabel()
678        configName = configMenuItem.GetLabel()
679        appLauncherId = appMenuItem.GetHelp()
680       
681        if self.leftClick:
682            res = self.sageGate.executeRemoteApp(appLauncherId, appName, configName)
683        else:
684            res = self.sageGate.executeRemoteApp(appLauncherId, appName, configName, useBridge=True)
685
686        if res == -1:
687            Message("Application not started. Either application failed or the application launcher "+str(appLauncherId)+" is not running", "Application Launch Failed")
688       
689
690    def OnLeftDown(self, event):
691        MyBitmapButton.OnLeftDown(self, event)
692        self.leftClick = True #a hack to detect which mouse button was clicked
693
694        # get a new list from the sage server and make the menu
695        self.AddLauncherMenu()
696
697        self.PopupMenu(self.launcherMenu)#, event.GetPosition())
698        self.OnPaint()
699                   
700
701    def OnRightDown(self, event):
702        MyBitmapButton.OnRightDown(self, event)
703        self.leftClick = False  #a hack to detect which mouse button was clicked
704
705        # get a new list from the sage server and make the menu
706        self.AddLauncherMenu()
707       
708        self.PopupMenu(self.launcherMenu)#, event.GetPosition())
709        self.OnPaint()
710
711
712       
713
714
715
716############################################################################
717#
718#  CLASS: InstanceButton
719
720#  DESCRIPTION: This class describes the buttons that represents instances of
721#               one application. It extends MyBitmapButton and adds a few
722#               methods for specific stuff. These buttons are created when a
723#               40001 message comes back and the app doesn't exists yet. They
724#               are anchored at the appButton for that application so that
725#               they are drawn underneith it. Also they are all positioned
726#               relative to one another so that when one instance is closed,
727#               the button for it goes away and all the other ones are
728#               repositioned.
729#
730#  DATE:        March, 2005
731#
732############################################################################
733
734class InstanceButton(MyBitmapButton):
735   
736    def __init__(self, parent, (x,y), (resizeWidth, resizeHeight), up_bitmap, down_bitmap, over_bitmap, app):       
737        MyBitmapButton.__init__(self, parent.parent, (x,y), (resizeWidth, resizeHeight), up_bitmap, down_bitmap, over_bitmap, app.getName()+" "+str(app.getId()), app.getId() )
738        self.SetName( self.GetToolTip().GetTip() )
739        self.app = app  #SAGEApp
740        self.anchor = parent  # parent is the AppButton that this instance corresponds to
741        self.displayCanvas = self.anchor.parent.parent.GetDisplayCanvas()
742        self.drawX = x
743        self.drawY = y
744        self.infoPanel = self.anchor.parent.parent.GetInfoPanel()
745        self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
746       
747
748    def SetDrawX(self, newX):
749        self.drawX = newX
750
751    def SetDrawY(self, newY):
752        self.drawY = newY
753
754   
755    #  EVENT HANDLERS
756    def OnRightUp(self, event):
757        menu = wx.Menu()
758        closeMenuItem = menu.Append( self.GetId()+1, "Close "+self.GetName() )  # +1 because Mac doesn't like 0 menuItem id
759        menu.Bind(wx.EVT_MENU, self.OnCloseMenuItem, closeMenuItem)
760        self.PopupMenu(menu, event.GetPosition())
761        menu.Destroy()
762
763    def OnCloseMenuItem(self, event):
764        # (AKS 2005-04-05) Stop performance monitoring that began "by default"
765        # when a new application had started.
766        self.displayCanvas.sageGate.shutdownApp(self.GetId()) 
767       
768    def OnPaint(self, event=None):
769        MyBitmapButton.OnPaint(self, event)
770           
771    def OnMouseEnter(self, event):
772        shape = self.displayCanvas.GetShape(self.GetId())
773       
774        # update the tooltip first because the name might have changed
775        if self.tTip != "":
776            self.tTip = shape.GetName()+" "+str(shape.GetId())+" - "+shape.GetTitle()
777            self.toolTip = wx.ToolTip( self.tTip )
778            self.toolTip.SetDelay( 200 )
779            self.SetToolTip( self.toolTip )
780           
781        shape.Highlight(True)
782        MyBitmapButton.OnMouseEnter(self, event)
783       
784    def OnMouseLeave(self, event):
785        self.displayCanvas.GetShape(self.GetId()).Highlight(False)
786        MyBitmapButton.OnMouseLeave(self, event)       
787       
788    def OnLeftUp(self, event):
789        MyBitmapButton.OnLeftUp(self, event)
790        self.displayCanvas.GetShape(self.GetId()).BringToFront()
791        self.infoPanel.ShowData(self.app.getName(), self.app.getId())
792        #self.infoPanel.ShowPerformanceData(self.app.getName(), self.app.getId())
793        #self.PopupMenu(self.configMenu, event.GetPosition())
794   
795
796
797class PerfToggleButton(MyBitmapButton):   
798
799    def __init__(self, parent, btnId, onClick, onDeClick, up_bitmap, down_bitmap, over_bitmap, (x,y), (resizeWidth, resizeHeight)):
800        if not os.path.isfile(over_bitmap):
801            over_bitmap = up_bitmap
802        MyBitmapButton.__init__(self, parent, (x,y), (resizeWidth, resizeHeight), up_bitmap, down_bitmap, over_bitmap )
803        self.__pressed = False  #the current state of the button
804        self.__id = btnId
805        self.__clickAction = onClick
806        self.__deClickAction = onDeClick
807
808    def OnLeftUp(self, event):
809        if self.__pressed:  #the button was pressed
810            self.__pressed = False
811            self.currentBitmap = self.up_bitmap
812            self.currentImage = self.up_image
813            self.__deClickAction( self.__id )
814        else:
815            self.__pressed = True
816            self.currentBitmap = self.down_bitmap
817            self.currentImage = self.down_image
818            self.__clickAction( self.__id )
819        self.OnPaint()
820
821
822    def OnLeftDown(self, event):
823        pass  # override the superclass handler
824
825    def OnMouseLeave(self, event):
826        if self.__pressed:
827            self.currentBitmap = self.down_bitmap
828            self.currentImage = self.down_image
829        else:
830            self.currentBitmap = self.up_bitmap
831            self.currentImage = self.up_image
832        self.OnPaint()
833
834    def GetValue(self):
835        return self.__pressed
836
837    def SetValue(self, press):
838        if self.__pressed == press:  #dont do anything if the button is already at that state
839            return
840        self.__pressed = press
841        if self.__pressed:
842            self.currentBitmap = self.down_bitmap
843            self.currentImage = self.down_image
844        else:
845            self.currentBitmap = self.up_bitmap
846            self.currentImage = self.up_image
847        self.OnPaint()
848       
849
850
851class MyButton(MyBitmapButton):
852   
853    def __init__(self, parent, (x,y), (resizeWidth, resizeHeight), function, up_bitmap, down_bitmap=None, over_bitmap=None, tTip="", id=-1 ):       
854        # call the superclass' constructor
855        MyBitmapButton.__init__(self, parent, (x,y), (resizeWidth, resizeHeight), up_bitmap, down_bitmap=None, over_bitmap=None, tTip="", id=-1 )       
856        self.function = function  # this is the function to be called when user presses the button
857               
858##     def OnPaint(self, event=None):
859##         if not event == None:   
860##             dc = wx.PaintDC(self)
861##         else:
862##             dc = wx.ClientDC(self)
863       
864##         #mask = wx.Mask(self.currentBitmap, wx.Colour(0,0,0))
865##      #self.currentBitmap.SetMask(mask)
866##         print "painting the help button"
867##         dc.DrawBitmap( self.currentBitmap, 0, 0, True )
868
869    def OnLeftDown(self, event):
870        MyBitmapButton.OnLeftDown(self, event)
871        self.function()
Note: See TracBrowser for help on using the repository browser.