start implementing treeview and nodemodel
[sface.git] / sface / screens / mainscreen.py
1
2 import os
3 from PyQt4.QtCore import *
4 from PyQt4.QtGui import *
5
6 from sfa.util.rspecHelper import RSpec
7 from sface.sfahelper import *
8 from sface.sficonfig import config
9 from sface.sfiprocess import SfiProcess
10 from sface.screens.sfascreen import SfaScreen
11
12 class NodeView(QTreeView):
13     def __init__(self, parent):
14         QTreeView.__init__(self, parent)
15
16         self.setItemsExpandable(True)
17         self.setRootIsDecorated(False)
18         self.setAlternatingRowColors(True)
19         self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
20
21 class TreeItem:
22     def __init__(self, data, parent=None):
23         self.parentItem = parent
24         self.itemData = data
25         self.childItems = []
26
27     def appendChild(self, child):
28         self.childItems.append(child)
29
30     def child(self, row):
31         return self.childItems[row]
32     
33     def childCount(self):
34         return len(self.childItems)
35
36     def columnCount(self):
37         print len(self.itemData)
38         return len(self.itemData)
39
40     def data(self, column):
41         return self.itemData[column]
42
43     def row(self):
44         if (self.parentItem):
45             for i in self.parentItem.childItems:
46                 if i is self:
47                     return i
48     
49     def parent(self):
50         return self.parentItem
51
52
53
54 class NodeModel(QAbstractItemModel):
55     def __init__(self, parent):
56         QAbstractItemModel.__init__(self, parent)
57         self.rootItem = TreeItem([QString("Testbed"), QString("Hostname")])
58
59     def addToRoot(self, item):
60         self.rootItem.appendChild(item)
61
62     def columnCount(self, parent):
63         if parent.isValid():
64             print "toto"
65             parent.internalPointer().columnCount()
66         else:
67             print "lala"
68             return self.rootItem.columnCount()
69
70     def data(self, index, role):
71         if not index.isValid():
72             return QVariant()
73
74         if role != Qt.DisplayRole:
75             return QVariant()
76
77         item = index.internalPointer()
78         return item.data(index.column())
79
80     def headerData(self, section, orientation, role):
81         if orientation == Qt.Horizontal and role == Qt.DisplayRole:
82             return self.rootItem.data(section)
83         return QVariant()
84
85     def index(self, row, column, parent):
86         if not self.hasIndex(row, column, parent):
87             return QModelIndex()
88
89         parentItem = None
90         if not parent.isValid():
91             parentItem = self.rootItem
92         else:
93             parentItem = parent.internalPointer()
94             
95         childItem = parentItem.child(row)
96         if childItem:
97             return self.createIndex(row, column, childItem)
98         else:
99             return QModelIndex()
100
101     def parent(self, index):
102         if not index.isValid():
103             return QModelIndex()
104
105         childItem = index.internalPointer()
106         parentItem = childItem.parent()
107
108         if not parentItem:
109             return QModelIndex()
110
111         if parentItem == self.rootItem:
112             return QModelIndex()
113
114         return self.createIndex(parentItem.row(), 0, parentItem);
115
116     def rowCount(self, parent):
117         if parent.column() > 0:
118             return 0
119
120         parentItem = None
121         if not parent.isValid():
122             parentItem = self.rootItem
123         else:
124             parentItem = parent.internalPointer()
125
126         return parentItem.childCount()
127
128
129 class SliceWidget(QWidget):
130     def __init__(self, parent):
131         QWidget.__init__(self, parent)
132
133         self.nodeView = NodeView(self)
134         self.nodeModel = NodeModel(self)
135         self.nodeView.setModel(self.nodeModel)
136
137         refresh = QLabel("<a href='refresh'>Refresh</a>", self)
138         refresh.setScaledContents(False)
139         slicename = QLabel ("Slice : %s"%(config.getSlice() or "None"),self)
140         slicename.setScaledContents(False)
141
142         hlayout = QHBoxLayout()
143         hlayout.addWidget(slicename)
144         hlayout.addStretch()
145         hlayout.addWidget(refresh)
146
147         layout = QVBoxLayout()
148         layout.addLayout(hlayout)
149         layout.addWidget(self.nodeView)
150         self.setLayout(layout)
151         self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
152
153         self.connect(refresh, SIGNAL('linkActivated(QString)'), self.refresh)
154
155         rspec_file = os.path.expanduser("~/.sfi/%s.rspec" % config.getSlice())
156         if os.path.exists(rspec_file):
157             self.updateView()
158         
159     def readSliceRSpec(self):
160         rspec_file = os.path.expanduser("~/.sfi/%s.rspec" % config.getSlice())
161         xml = open(rspec_file).read()
162         return xml
163
164     def refresh(self, link=None):
165         if not config.getSlice():
166             self.parent().setStatus("<font color='red'>Slice not set yet!</font>")
167             return
168
169         self.process = SfiProcess()
170         outfile = self.process.getRSpecFromSM()
171         self.parent().setStatus("Updating slice data. This may take some time...")
172         
173         self.connect(self.process, SIGNAL('finished()'), self.refreshFinished)
174
175     def refreshFinished(self):
176         del self.process
177         self.parent().setStatus("<font color='green'>Slice data updated.</font>")
178         self.updateView()
179
180     def updateView(self):
181         rspec_string = self.readSliceRSpec()
182         networks = rspec_get_networks(rspec_string)
183
184         for network in networks:
185             networkItem = TreeItem([QString(network), QString("")])
186
187             all_nodes = rspec_get_nodes_from_network(rspec_string, network)
188             for node in all_nodes:
189                 nodeItem = TreeItem([QString(""), QString(node)])
190                 networkItem.appendChild(nodeItem)
191
192             self.nodeModel.addToRoot(networkItem)
193
194
195 class MainScreen(SfaScreen):
196     def __init__(self, parent):
197         SfaScreen.__init__(self, parent)
198
199         slice = SliceWidget(self)
200         self.init(slice, "Main Window", "PlanetLab Federation GUI")