6 from wx.lib.mixins.listctrl import ColumnSorterMixin
7 from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
13 while len(sys.argv) >= 2:
14 if sys.argv[0] in ('-n', '--net'):
16 elif sys.argv[0] in ('--controlcookie'):
17 controlcookie = sys.argv[1]
19 print('Unknown option ' + sys.argv[0])
25 vpn = Tinc.VPN(net, controlcookie)
28 class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
29 def __init__(self, parent, style):
30 wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
31 ListCtrlAutoWidthMixin.__init__(self)
32 ColumnSorterMixin.__init__(self, 14)
34 def GetListCtrl(self):
38 class SettingsPage(wx.Panel):
39 def OnDebugLevel(self, event):
40 vpn.debug(self.debug.GetValue())
42 def __init__(self, parent, id):
43 wx.Panel.__init__(self, parent, id)
44 grid = wx.FlexGridSizer(cols = 2)
45 grid.AddGrowableCol(0, 1)
47 namelabel = wx.StaticText(self, -1, 'Name:')
48 self.name = wx.TextCtrl(self, -1, vpn.name)
52 portlabel = wx.StaticText(self, -1, 'Port:')
53 self.port = wx.TextCtrl(self, -1, vpn.port)
57 debuglabel = wx.StaticText(self, -1, 'Debug level:')
58 self.debug = wx.SpinCtrl(self, min = 0, max = 5, initial = vpn.debug())
59 self.debug.Bind(wx.EVT_SPINCTRL, self.OnDebugLevel)
63 modelabel = wx.StaticText(self, -1, 'Mode:')
64 self.mode = wx.ComboBox(self, -1, style = wx.CB_READONLY, value = 'Router', choices = ['Router', 'Switch', 'Hub'])
70 class ConnectionsPage(wx.Panel):
71 def __init__(self, parent, id):
72 wx.Panel.__init__(self, parent, id)
73 self.list = wx.ListCtrl(self, id, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
74 self.list.InsertColumn(0, 'Name')
75 self.list.InsertColumn(1, 'Address')
76 self.list.InsertColumn(2, 'Port')
77 self.list.InsertColumn(3, 'Options')
78 self.list.InsertColumn(4, 'Weight')
80 hbox = wx.BoxSizer(wx.HORIZONTAL)
81 hbox.Add(self.list, 1, wx.EXPAND)
85 class ContextMenu(wx.Menu):
86 def __init__(self, item):
87 wx.Menu.__init__(self)
91 disconnect = wx.MenuItem(self, -1, 'Disconnect')
92 self.AppendItem(disconnect)
93 self.Bind(wx.EVT_MENU, self.OnDisconnect, id=disconnect.GetId())
95 def OnDisconnect(self, event):
96 print('Disconnecting ' + self.item[0])
97 vpn.disconnect(self.item[0])
99 def OnContext(self, event):
100 print('Context menu!')
103 self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition())
106 self.list.itemDataMap = {}
109 for key, connection in vpn.connections.items():
110 if self.list.GetItemCount() <= i:
111 self.list.InsertStringItem(i, connection.name)
113 self.list.SetStringItem(i, 0, connection.name)
114 self.list.SetStringItem(i, 1, connection.address)
115 self.list.SetStringItem(i, 2, connection.port)
116 self.list.SetStringItem(i, 3, str(connection.options))
117 self.list.SetStringItem(i, 4, str(connection.weight))
118 self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options, connection.weight)
119 self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnContext)
122 while self.list.GetItemCount() > i:
123 self.list.DeleteItem(self.list.GetItemCount() - 1)
126 class NodesPage(wx.Panel):
127 def __init__(self, parent, id):
128 wx.Panel.__init__(self, parent, id)
129 self.list = SuperListCtrl(self, id)
130 self.list.InsertColumn( 0, 'Name')
131 self.list.InsertColumn( 1, 'Address')
132 self.list.InsertColumn( 2, 'Port')
133 self.list.InsertColumn( 3, 'Cipher')
134 self.list.InsertColumn( 4, 'Digest')
135 self.list.InsertColumn( 5, 'MACLength')
136 self.list.InsertColumn( 6, 'Compression')
137 self.list.InsertColumn( 7, 'Options')
138 self.list.InsertColumn( 8, 'Status')
139 self.list.InsertColumn( 9, 'Nexthop')
140 self.list.InsertColumn(10, 'Via')
141 self.list.InsertColumn(11, 'Distance')
142 self.list.InsertColumn(12, 'PMTU')
143 self.list.InsertColumn(13, 'Min MTU')
144 self.list.InsertColumn(14, 'Max MTU')
146 hbox = wx.BoxSizer(wx.HORIZONTAL)
147 hbox.Add(self.list, 1, wx.EXPAND)
152 self.list.itemDataMap = {}
155 for key, node in vpn.nodes.items():
156 if self.list.GetItemCount() <= i:
157 self.list.InsertStringItem(i, node.name)
159 self.list.SetStringItem(i, 0, node.name)
160 self.list.SetStringItem(i, 1, node.address)
161 self.list.SetStringItem(i, 2, node.port)
162 self.list.SetStringItem(i, 3, str(node.cipher))
163 self.list.SetStringItem(i, 4, str(node.digest))
164 self.list.SetStringItem(i, 5, str(node.maclength))
165 self.list.SetStringItem(i, 6, str(node.compression))
166 self.list.SetStringItem(i, 7, str(node.options))
167 self.list.SetStringItem(i, 8, str(node.status))
168 self.list.SetStringItem(i, 9, node.nexthop)
169 self.list.SetStringItem(i, 10, node.via)
170 self.list.SetStringItem(i, 11, str(node.distance))
171 self.list.SetStringItem(i, 12, str(node.pmtu))
172 self.list.SetStringItem(i, 13, str(node.minmtu))
173 self.list.SetStringItem(i, 14, str(node.maxmtu))
174 self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength, node.compression, node.options, node.status, node.nexthop, node.via, node.distance, node.pmtu, node.minmtu, node.maxmtu)
175 self.list.SetItemData(i, i)
178 while self.list.GetItemCount() > i:
179 self.list.DeleteItem(self.list.GetItemCount() - 1)
181 class EdgesPage(wx.Panel):
182 def __init__(self, parent, id):
183 wx.Panel.__init__(self, parent, id)
184 self.list = wx.ListCtrl(self, id, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
185 self.list.InsertColumn(0, 'From')
186 self.list.InsertColumn(1, 'To')
187 self.list.InsertColumn(2, 'Address')
188 self.list.InsertColumn(3, 'Port')
189 self.list.InsertColumn(4, 'Options')
190 self.list.InsertColumn(5, 'Weight')
192 hbox = wx.BoxSizer(wx.HORIZONTAL)
193 hbox.Add(self.list, 1, wx.EXPAND)
198 self.list.itemDataMap = {}
201 for key, edge in vpn.edges.items():
202 if self.list.GetItemCount() <= i:
203 self.list.InsertStringItem(i, edge.fr)
205 self.list.SetStringItem(i, 0, edge.fr)
206 self.list.SetStringItem(i, 1, edge.to)
207 self.list.SetStringItem(i, 2, edge.address)
208 self.list.SetStringItem(i, 3, edge.port)
209 self.list.SetStringItem(i, 4, str(edge.options))
210 self.list.SetStringItem(i, 5, str(edge.weight))
211 self.list.itemDataMap[i] = (edge.fr, edge.to, edge.address, edge.port, edge.options, edge.weight)
214 while self.list.GetItemCount() > i:
215 self.list.DeleteItem(self.list.GetItemCount() - 1)
217 class SubnetsPage(wx.Panel):
218 def __init__(self, parent, id):
219 wx.Panel.__init__(self, parent, id)
220 self.list = SuperListCtrl(self, id)
221 self.list.InsertColumn(0, 'Subnet', wx.LIST_FORMAT_RIGHT)
222 self.list.InsertColumn(1, 'Weight', wx.LIST_FORMAT_RIGHT)
223 self.list.InsertColumn(2, 'Owner')
224 hbox = wx.BoxSizer(wx.HORIZONTAL)
225 hbox.Add(self.list, 1, wx.EXPAND)
230 self.list.itemDataMap = {}
233 for key, subnet in vpn.subnets.items():
234 if self.list.GetItemCount() <= i:
235 self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen)
237 self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen)
238 self.list.SetStringItem(i, 1, subnet.weight)
239 self.list.SetStringItem(i, 2, subnet.owner)
240 self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner)
243 while self.list.GetItemCount() > i:
244 self.list.DeleteItem(self.list.GetItemCount() - 1)
246 class StatusPage(wx.Panel):
247 def __init__(self, parent, id):
248 wx.Panel.__init__(self, parent, id)
250 class GraphPage(wx.Window):
251 def __init__(self, parent, id):
252 wx.Window.__init__(self, parent, id)
254 class NetPage(wx.Notebook):
255 def __init__(self, parent, id):
256 wx.Notebook.__init__(self, parent)
257 self.settings = SettingsPage(self, id)
258 self.connections = ConnectionsPage(self, id)
259 self.nodes = NodesPage(self, id)
260 self.edges = EdgesPage(self, id)
261 self.subnets = SubnetsPage(self, id)
262 self.graph = GraphPage(self, id)
263 self.status = StatusPage(self, id)
265 self.AddPage(self.settings, 'Settings')
266 #self.AddPage(self.status, 'Status')
267 self.AddPage(self.connections, 'Connections')
268 self.AddPage(self.nodes, 'Nodes')
269 self.AddPage(self.edges, 'Edges')
270 self.AddPage(self.subnets, 'Subnets')
271 #self.AddPage(self.graph, 'Graph')
274 class MainWindow(wx.Frame):
275 def OnQuit(self, event):
278 def OnTimer(self, event):
280 self.np.nodes.refresh()
281 self.np.subnets.refresh()
282 self.np.edges.refresh()
283 self.np.connections.refresh()
285 def __init__(self, parent, id, title):
286 wx.Frame.__init__(self, parent, id, title)
288 menubar = wx.MenuBar()
290 file.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI')
291 menubar.Append(file, '&File')
293 #nb = wx.Notebook(self, -1)
294 #nb.SetPadding((0, 0))
295 self.np = NetPage(self, -1)
296 #nb.AddPage(np, 'VPN')
298 self.timer = wx.Timer(self, -1)
299 self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
300 self.timer.Start(1000)
301 self.Bind(wx.EVT_MENU, self.OnQuit, id=1)
302 self.SetMenuBar(menubar)
306 mw = MainWindow(None, -1, 'Tinc GUI')
308 #def OnTaskBarIcon(event):
311 #icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG)
312 #taskbaricon = wx.TaskBarIcon()
313 #taskbaricon.SetIcon(icon, 'Tinc GUI')
314 #wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon)