Open Media Library Platform

This commit is contained in:
j 2013-10-11 19:28:32 +02:00
commit 411ad5b16f
5849 changed files with 1778641 additions and 0 deletions

View file

@ -0,0 +1,12 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Twisted Spread UI: UI utilities for various toolkits connecting to PB.
"""
# Undeprecating this until someone figures out a real plan for alternatives to spread.ui.
##import warnings
##warnings.warn("twisted.spread.ui is deprecated. Please do not use.", DeprecationWarning)

View file

@ -0,0 +1,218 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
import gtk
from twisted import copyright
from twisted.internet import defer
from twisted.python import failure, log, util
from twisted.spread import pb
from twisted.cred.credentials import UsernamePassword
from twisted.internet import error as netError
def login(client=None, **defaults):
"""
@param host:
@param port:
@param identityName:
@param password:
@param serviceName:
@param perspectiveName:
@returntype: Deferred RemoteReference of Perspective
"""
d = defer.Deferred()
LoginDialog(client, d, defaults)
return d
class GladeKeeper:
"""
@cvar gladefile: The file in which the glade GUI definition is kept.
@type gladefile: str
@cvar _widgets: Widgets that should be attached to me as attributes.
@type _widgets: list of strings
"""
gladefile = None
_widgets = ()
def __init__(self):
from gtk import glade
self.glade = glade.XML(self.gladefile)
# mold can go away when we get a newer pygtk (post 1.99.14)
mold = {}
for k in dir(self):
mold[k] = getattr(self, k)
self.glade.signal_autoconnect(mold)
self._setWidgets()
def _setWidgets(self):
get_widget = self.glade.get_widget
for widgetName in self._widgets:
setattr(self, "_" + widgetName, get_widget(widgetName))
class LoginDialog(GladeKeeper):
# IdentityConnector host port identityName password
# requestLogin -> identityWrapper or login failure
# requestService serviceName perspectiveName client
# window killed
# cancel button pressed
# login button activated
fields = ['host','port','identityName','password',
'perspectiveName']
_widgets = ("hostEntry", "portEntry", "identityNameEntry", "passwordEntry",
"perspectiveNameEntry", "statusBar",
"loginDialog")
_advancedControls = ['perspectiveLabel', 'perspectiveNameEntry',
'protocolLabel', 'versionLabel']
gladefile = util.sibpath(__file__, "login2.glade")
_timeoutID = None
def __init__(self, client, deferred, defaults):
self.client = client
self.deferredResult = deferred
GladeKeeper.__init__(self)
self.setDefaults(defaults)
self._loginDialog.show()
def setDefaults(self, defaults):
if not defaults.has_key('port'):
defaults['port'] = str(pb.portno)
elif isinstance(defaults['port'], (int, long)):
defaults['port'] = str(defaults['port'])
for k, v in defaults.iteritems():
if k in self.fields:
widget = getattr(self, "_%sEntry" % (k,))
widget.set_text(v)
def _setWidgets(self):
GladeKeeper._setWidgets(self)
self._statusContext = self._statusBar.get_context_id("Login dialog.")
get_widget = self.glade.get_widget
get_widget("versionLabel").set_text(copyright.longversion)
get_widget("protocolLabel").set_text("Protocol PB-%s" %
(pb.Broker.version,))
def _on_loginDialog_response(self, widget, response):
handlers = {gtk.RESPONSE_NONE: self._windowClosed,
gtk.RESPONSE_DELETE_EVENT: self._windowClosed,
gtk.RESPONSE_OK: self._doLogin,
gtk.RESPONSE_CANCEL: self._cancelled}
handler = handlers.get(response)
if handler is not None:
handler()
else:
log.msg("Unexpected dialog response %r from %s" % (response,
widget))
def _on_loginDialog_close(self, widget, userdata=None):
self._windowClosed()
def _on_loginDialog_destroy_event(self, widget, userdata=None):
self._windowClosed()
def _cancelled(self):
if not self.deferredResult.called:
self.deferredResult.errback(netError.UserError("User hit Cancel."))
self._loginDialog.destroy()
def _windowClosed(self, reason=None):
if not self.deferredResult.called:
self.deferredResult.errback(netError.UserError("Window closed."))
def _doLogin(self):
idParams = {}
idParams['host'] = self._hostEntry.get_text()
idParams['port'] = self._portEntry.get_text()
idParams['identityName'] = self._identityNameEntry.get_text()
idParams['password'] = self._passwordEntry.get_text()
try:
idParams['port'] = int(idParams['port'])
except ValueError:
pass
f = pb.PBClientFactory()
from twisted.internet import reactor
reactor.connectTCP(idParams['host'], idParams['port'], f)
creds = UsernamePassword(idParams['identityName'], idParams['password'])
d = f.login(creds, self.client)
def _timeoutLogin():
self._timeoutID = None
d.errback(failure.Failure(defer.TimeoutError("Login timed out.")))
self._timeoutID = reactor.callLater(30, _timeoutLogin)
d.addCallbacks(self._cbGotPerspective, self._ebFailedLogin)
self.statusMsg("Contacting server...")
# serviceName = self._serviceNameEntry.get_text()
# perspectiveName = self._perspectiveNameEntry.get_text()
# if not perspectiveName:
# perspectiveName = idParams['identityName']
# d = _identityConnector.requestService(serviceName, perspectiveName,
# self.client)
# d.addCallbacks(self._cbGotPerspective, self._ebFailedLogin)
# setCursor to waiting
def _cbGotPerspective(self, perspective):
self.statusMsg("Connected to server.")
if self._timeoutID is not None:
self._timeoutID.cancel()
self._timeoutID = None
self.deferredResult.callback(perspective)
# clear waiting cursor
self._loginDialog.destroy()
def _ebFailedLogin(self, reason):
if isinstance(reason, failure.Failure):
reason = reason.value
self.statusMsg(reason)
if isinstance(reason, (unicode, str)):
text = reason
else:
text = unicode(reason)
msg = gtk.MessageDialog(self._loginDialog,
gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR,
gtk.BUTTONS_CLOSE,
text)
msg.show_all()
msg.connect("response", lambda *a: msg.destroy())
# hostname not found
# host unreachable
# connection refused
# authentication failed
# no such service
# no such perspective
# internal server error
def _on_advancedButton_toggled(self, widget, userdata=None):
active = widget.get_active()
if active:
op = "show"
else:
op = "hide"
for widgetName in self._advancedControls:
widget = self.glade.get_widget(widgetName)
getattr(widget, op)()
def statusMsg(self, text):
if not isinstance(text, (unicode, str)):
text = unicode(text)
return self._statusBar.push(self._statusContext, text)

View file

@ -0,0 +1,461 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkDialog" id="loginDialog">
<property name="title" translatable="yes">Login</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">True</property>
<property name="has_separator">True</property>
<signal name="response" handler="_on_loginDialog_response" last_modification_time="Sat, 25 Jan 2003 13:52:57 GMT"/>
<signal name="close" handler="_on_loginDialog_close" last_modification_time="Sat, 25 Jan 2003 13:53:04 GMT"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancelbutton1">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="loginButton">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="response_id">-5</property>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="label" translatable="yes">_Login</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkStatusbar" id="statusBar">
<property name="visible">True</property>
<property name="has_resize_grip">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">6</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">2</property>
<property name="column_spacing">0</property>
<child>
<widget class="GtkLabel" id="hostLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">_Host:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.9</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">hostEntry</property>
<accessibility>
<atkrelation target="hostEntry" type="label-for"/>
<atkrelation target="portEntry" type="label-for"/>
</accessibility>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkEntry" id="hostEntry">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">The name of a host to connect to.</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes">localhost</property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
<accessibility>
<atkrelation target="hostLabel" type="labelled-by"/>
</accessibility>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="portEntry">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">The number of a port to connect on.</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes">8787</property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
<property name="width_chars">5</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="nameLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">_Name:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.9</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">identityNameEntry</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="identityNameEntry">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">An identity to log in as.</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="passwordEntry">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">The Identity's log-in password.</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">False</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="passwordLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">_Password:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.9</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">passwordEntry</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="perspectiveLabel">
<property name="label" translatable="yes">Perspective:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.9</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="perspectiveNameEntry">
<property name="tooltip" translatable="yes">The name of a Perspective to request.</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="protocolLabel">
<property name="label" translatable="yes">Insert Protocol Version Here</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="versionLabel">
<property name="label" translatable="yes">Insert Twisted Version Here</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">1</property>
<child>
<widget class="GtkToggleButton" id="advancedButton">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Advanced options.</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Advanced &gt;&gt;</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<signal name="toggled" handler="_on_advancedButton_toggled" object="Login" last_modification_time="Sat, 25 Jan 2003 13:47:17 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View file

@ -0,0 +1,204 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
What I want it to look like:
+- One
| \- Two
| |- Three
| |- Four
| +- Five
| | \- Six
| |- Seven
+- Eight
| \- Nine
"""
import os
from Tkinter import *
class Node:
def __init__(self):
"""
Do whatever you want here.
"""
self.item=None
def getName(self):
"""
Return the name of this node in the tree.
"""
pass
def isExpandable(self):
"""
Return true if this node is expandable.
"""
return len(self.getSubNodes())>0
def getSubNodes(self):
"""
Return the sub nodes of this node.
"""
return []
def gotDoubleClick(self):
"""
Called when we are double clicked.
"""
pass
def updateMe(self):
"""
Call me when something about me changes, so that my representation
changes.
"""
if self.item:
self.item.update()
class FileNode(Node):
def __init__(self,name):
Node.__init__(self)
self.name=name
def getName(self):
return os.path.basename(self.name)
def isExpandable(self):
return os.path.isdir(self.name)
def getSubNodes(self):
names=map(lambda x,n=self.name:os.path.join(n,x),os.listdir(self.name))
return map(FileNode,names)
class TreeItem:
def __init__(self,widget,parent,node):
self.widget=widget
self.node=node
node.item=self
if self.node.isExpandable():
self.expand=0
else:
self.expand=None
self.parent=parent
if parent:
self.level=self.parent.level+1
else:
self.level=0
self.first=0 # gets set in Tree.expand()
self.subitems=[]
def __del__(self):
del self.node
del self.widget
def __repr__(self):
return "<Item for Node %s at level %s>"%(self.node.getName(),self.level)
def render(self):
"""
Override in a subclass.
"""
raise NotImplementedError
def update(self):
self.widget.update(self)
class ListboxTreeItem(TreeItem):
def render(self):
start=self.level*"| "
if self.expand==None and not self.first:
start=start+"|"
elif self.expand==0:
start=start+"L"
elif self.expand==1:
start=start+"+"
else:
start=start+"\\"
r=[start+"- "+self.node.getName()]
if self.expand:
for i in self.subitems:
r.extend(i.render())
return r
class ListboxTree:
def __init__(self,parent=None,**options):
self.box=apply(Listbox,[parent],options)
self.box.bind("<Double-1>",self.flip)
self.roots=[]
self.items=[]
def pack(self,*args,**kw):
"""
for packing.
"""
apply(self.box.pack,args,kw)
def grid(self,*args,**kw):
"""
for gridding.
"""
apply(self.box.grid,args,kw)
def yview(self,*args,**kw):
"""
for scrolling.
"""
apply(self.box.yview,args,kw)
def addRoot(self,node):
r=ListboxTreeItem(self,None,node)
self.roots.append(r)
self.items.append(r)
self.box.insert(END,r.render()[0])
return r
def curselection(self):
c=self.box.curselection()
if not c: return
return self.items[int(c[0])]
def flip(self,*foo):
if not self.box.curselection(): return
item=self.items[int(self.box.curselection()[0])]
if item.expand==None: return
if not item.expand:
self.expand(item)
else:
self.close(item)
item.node.gotDoubleClick()
def expand(self,item):
if item.expand or item.expand==None: return
item.expand=1
item.subitems=map(lambda x,i=item,s=self:ListboxTreeItem(s,i,x),item.node.getSubNodes())
if item.subitems:
item.subitems[0].first=1
i=self.items.index(item)
self.items,after=self.items[:i+1],self.items[i+1:]
self.items=self.items+item.subitems+after
c=self.items.index(item)
self.box.delete(c)
r=item.render()
for i in r:
self.box.insert(c,i)
c=c+1
def close(self,item):
if not item.expand: return
item.expand=0
length=len(item.subitems)
for i in item.subitems:
self.close(i)
c=self.items.index(item)
del self.items[c+1:c+1+length]
for i in range(length+1):
self.box.delete(c)
self.box.insert(c,item.render()[0])
def remove(self,item):
if item.expand:
self.close(item)
c=self.items.index(item)
del self.items[c]
if item.parent:
item.parent.subitems.remove(item)
self.box.delete(c)
def update(self,item):
if item.expand==None:
c=self.items.index(item)
self.box.delete(c)
self.box.insert(c,item.render()[0])
elif item.expand:
self.close(item)
self.expand(item)
if __name__=="__main__":
tk=Tk()
s=Scrollbar()
t=ListboxTree(tk,yscrollcommand=s.set)
t.pack(side=LEFT,fill=BOTH)
s.config(command=t.yview)
s.pack(side=RIGHT,fill=Y)
t.addRoot(FileNode("C:/"))
#mainloop()

View file

@ -0,0 +1,397 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""Utilities for building L{PB<twisted.spread.pb>} clients with L{Tkinter}.
"""
from Tkinter import *
from tkSimpleDialog import _QueryString
from tkFileDialog import _Dialog
from twisted.spread import pb
from twisted.internet import reactor
from twisted import copyright
import string
#normalFont = Font("-adobe-courier-medium-r-normal-*-*-120-*-*-m-*-iso8859-1")
#boldFont = Font("-adobe-courier-bold-r-normal-*-*-120-*-*-m-*-iso8859-1")
#errorFont = Font("-adobe-courier-medium-o-normal-*-*-120-*-*-m-*-iso8859-1")
class _QueryPassword(_QueryString):
def body(self, master):
w = Label(master, text=self.prompt, justify=LEFT)
w.grid(row=0, padx=5, sticky=W)
self.entry = Entry(master, name="entry",show="*")
self.entry.grid(row=1, padx=5, sticky=W+E)
if self.initialvalue:
self.entry.insert(0, self.initialvalue)
self.entry.select_range(0, END)
return self.entry
def askpassword(title, prompt, **kw):
'''get a password from the user
@param title: the dialog title
@param prompt: the label text
@param **kw: see L{SimpleDialog} class
@returns: a string
'''
d = apply(_QueryPassword, (title, prompt), kw)
return d.result
def grid_setexpand(widget):
cols,rows=widget.grid_size()
for i in range(cols):
widget.columnconfigure(i,weight=1)
for i in range(rows):
widget.rowconfigure(i,weight=1)
class CList(Frame):
def __init__(self,parent,labels,disablesorting=0,**kw):
Frame.__init__(self,parent)
self.labels=labels
self.lists=[]
self.disablesorting=disablesorting
kw["exportselection"]=0
for i in range(len(labels)):
b=Button(self,text=labels[i],anchor=W,height=1,pady=0)
b.config(command=lambda s=self,i=i:s.setSort(i))
b.grid(column=i,row=0,sticky=N+E+W)
box=apply(Listbox,(self,),kw)
box.grid(column=i,row=1,sticky=N+E+S+W)
self.lists.append(box)
grid_setexpand(self)
self.rowconfigure(0,weight=0)
self._callall("bind",'<Button-1>',self.Button1)
self._callall("bind",'<B1-Motion>',self.Button1)
self.bind('<Up>',self.UpKey)
self.bind('<Down>',self.DownKey)
self.sort=None
def _callall(self,funcname,*args,**kw):
rets=[]
for l in self.lists:
func=getattr(l,funcname)
ret=apply(func,args,kw)
if ret!=None: rets.append(ret)
if rets: return rets
def Button1(self,e):
index=self.nearest(e.y)
self.select_clear(0,END)
self.select_set(index)
self.activate(index)
return "break"
def UpKey(self,e):
index=self.index(ACTIVE)
if index:
self.select_clear(0,END)
self.select_set(index-1)
return "break"
def DownKey(self,e):
index=self.index(ACTIVE)
if index!=self.size()-1:
self.select_clear(0,END)
self.select_set(index+1)
return "break"
def setSort(self,index):
if self.sort==None:
self.sort=[index,1]
elif self.sort[0]==index:
self.sort[1]=-self.sort[1]
else:
self.sort=[index,1]
self._sort()
def _sort(self):
if self.disablesorting:
return
if self.sort==None:
return
ind,direc=self.sort
li=list(self.get(0,END))
li.sort(lambda x,y,i=ind,d=direc:d*cmp(x[i],y[i]))
self.delete(0,END)
for l in li:
self._insert(END,l)
def activate(self,index):
self._callall("activate",index)
# def bbox(self,index):
# return self._callall("bbox",index)
def curselection(self):
return self.lists[0].curselection()
def delete(self,*args):
apply(self._callall,("delete",)+args)
def get(self,*args):
bad=apply(self._callall,("get",)+args)
if len(args)==1:
return bad
ret=[]
for i in range(len(bad[0])):
r=[]
for j in range(len(bad)):
r.append(bad[j][i])
ret.append(r)
return ret
def index(self,index):
return self.lists[0].index(index)
def insert(self,index,items):
self._insert(index,items)
self._sort()
def _insert(self,index,items):
for i in range(len(items)):
self.lists[i].insert(index,items[i])
def nearest(self,y):
return self.lists[0].nearest(y)
def see(self,index):
self._callall("see",index)
def size(self):
return self.lists[0].size()
def selection_anchor(self,index):
self._callall("selection_anchor",index)
select_anchor=selection_anchor
def selection_clear(self,*args):
apply(self._callall,("selection_clear",)+args)
select_clear=selection_clear
def selection_includes(self,index):
return self.lists[0].select_includes(index)
select_includes=selection_includes
def selection_set(self,*args):
apply(self._callall,("selection_set",)+args)
select_set=selection_set
def xview(self,*args):
if not args: return self.lists[0].xview()
apply(self._callall,("xview",)+args)
def yview(self,*args):
if not args: return self.lists[0].yview()
apply(self._callall,("yview",)+args)
class ProgressBar:
def __init__(self, master=None, orientation="horizontal",
min=0, max=100, width=100, height=18,
doLabel=1, appearance="sunken",
fillColor="blue", background="gray",
labelColor="yellow", labelFont="Verdana",
labelText="", labelFormat="%d%%",
value=0, bd=2):
# preserve various values
self.master=master
self.orientation=orientation
self.min=min
self.max=max
self.width=width
self.height=height
self.doLabel=doLabel
self.fillColor=fillColor
self.labelFont= labelFont
self.labelColor=labelColor
self.background=background
self.labelText=labelText
self.labelFormat=labelFormat
self.value=value
self.frame=Frame(master, relief=appearance, bd=bd)
self.canvas=Canvas(self.frame, height=height, width=width, bd=0,
highlightthickness=0, background=background)
self.scale=self.canvas.create_rectangle(0, 0, width, height,
fill=fillColor)
self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,
height / 2, text=labelText,
anchor="c", fill=labelColor,
font=self.labelFont)
self.update()
self.canvas.pack(side='top', fill='x', expand='no')
def updateProgress(self, newValue, newMax=None):
if newMax:
self.max = newMax
self.value = newValue
self.update()
def update(self):
# Trim the values to be between min and max
value=self.value
if value > self.max:
value = self.max
if value < self.min:
value = self.min
# Adjust the rectangle
if self.orientation == "horizontal":
self.canvas.coords(self.scale, 0, 0,
float(value) / self.max * self.width, self.height)
else:
self.canvas.coords(self.scale, 0,
self.height - (float(value) /
self.max*self.height),
self.width, self.height)
# Now update the colors
self.canvas.itemconfig(self.scale, fill=self.fillColor)
self.canvas.itemconfig(self.label, fill=self.labelColor)
# And update the label
if self.doLabel:
if value:
if value >= 0:
pvalue = int((float(value) / float(self.max)) *
100.0)
else:
pvalue = 0
self.canvas.itemconfig(self.label, text=self.labelFormat
% pvalue)
else:
self.canvas.itemconfig(self.label, text='')
else:
self.canvas.itemconfig(self.label, text=self.labelFormat %
self.labelText)
self.canvas.update_idletasks()
class DirectoryBrowser(_Dialog):
command = "tk_chooseDirectory"
def askdirectory(**options):
"Ask for a directory to save to."
return apply(DirectoryBrowser, (), options).show()
class GenericLogin(Toplevel):
def __init__(self,callback,buttons):
Toplevel.__init__(self)
self.callback=callback
Label(self,text="Twisted v%s"%copyright.version).grid(column=0,row=0,columnspan=2)
self.entries={}
row=1
for stuff in buttons:
label,value=stuff[:2]
if len(stuff)==3:
dict=stuff[2]
else: dict={}
Label(self,text=label+": ").grid(column=0,row=row)
e=apply(Entry,(self,),dict)
e.grid(column=1,row=row)
e.insert(0,value)
self.entries[label]=e
row=row+1
Button(self,text="Login",command=self.doLogin).grid(column=0,row=row)
Button(self,text="Cancel",command=self.close).grid(column=1,row=row)
self.protocol('WM_DELETE_WINDOW',self.close)
def close(self):
self.tk.quit()
self.destroy()
def doLogin(self):
values={}
for k in self.entries.keys():
values[string.lower(k)]=self.entries[k].get()
self.callback(values)
self.destroy()
class Login(Toplevel):
def __init__(self,
callback,
referenced = None,
initialUser = "guest",
initialPassword = "guest",
initialHostname = "localhost",
initialService = "",
initialPortno = pb.portno):
Toplevel.__init__(self)
version_label = Label(self,text="Twisted v%s" % copyright.version)
self.pbReferenceable = referenced
self.pbCallback = callback
# version_label.show()
self.username = Entry(self)
self.password = Entry(self,show='*')
self.hostname = Entry(self)
self.service = Entry(self)
self.port = Entry(self)
self.username.insert(0,initialUser)
self.password.insert(0,initialPassword)
self.service.insert(0,initialService)
self.hostname.insert(0,initialHostname)
self.port.insert(0,str(initialPortno))
userlbl=Label(self,text="Username:")
passlbl=Label(self,text="Password:")
servicelbl=Label(self,text="Service:")
hostlbl=Label(self,text="Hostname:")
portlbl=Label(self,text="Port #:")
self.logvar=StringVar()
self.logvar.set("Protocol PB-%s"%pb.Broker.version)
self.logstat = Label(self,textvariable=self.logvar)
self.okbutton = Button(self,text="Log In", command=self.login)
version_label.grid(column=0,row=0,columnspan=2)
z=0
for i in [[userlbl,self.username],
[passlbl,self.password],
[hostlbl,self.hostname],
[servicelbl,self.service],
[portlbl,self.port]]:
i[0].grid(column=0,row=z+1)
i[1].grid(column=1,row=z+1)
z = z+1
self.logstat.grid(column=0,row=6,columnspan=2)
self.okbutton.grid(column=0,row=7,columnspan=2)
self.protocol('WM_DELETE_WINDOW',self.tk.quit)
def loginReset(self):
self.logvar.set("Idle.")
def loginReport(self, txt):
self.logvar.set(txt)
self.after(30000, self.loginReset)
def login(self):
host = self.hostname.get()
port = self.port.get()
service = self.service.get()
try:
port = int(port)
except:
pass
user = self.username.get()
pswd = self.password.get()
pb.connect(host, port, user, pswd, service,
client=self.pbReferenceable).addCallback(self.pbCallback).addErrback(
self.couldNotConnect)
def couldNotConnect(self,f):
self.loginReport("could not connect:"+f.getErrorMessage())
if __name__=="__main__":
root=Tk()
o=CList(root,["Username","Online","Auto-Logon","Gateway"])
o.pack()
for i in range(0,16,4):
o.insert(END,[i,i+1,i+2,i+3])
mainloop()