Package Camelot :: Package camelot :: Package view :: Package wizard :: Module import_data

Source Code for Module Camelot.camelot.view.wizard.import_data

  1  from PyQt4 import QtGui, QtCore 
  2  from PyQt4.QtGui import QWizard, QWizardPage, QToolBar, QFileDialog, QPushButton, QTableView, QFont, QVBoxLayout, QGridLayout, QLabel, QComboBox, QItemDelegate, QStandardItemModel, QColor, QCheckBox 
  3  from PyQt4.QtCore import QString, QAbstractTableModel, QVariant, Qt, QAbstractListModel, QModelIndex, QStringList, QPoint 
  4  from camelot.view import art 
  5  from camelot.view.art import Icon 
  6  from camelot.action import createAction, addActions 
  7  from camelot.view.elixir_admin import EntityAdmin 
  8  from camelot.view.model_thread import get_model_thread 
  9  from camelot.view.controls.exception import model_thread_exception_message_box 
 10  from camelot.view.controls.delegates.comboboxdelegate import ComboBoxEditorDelegate, TestComboBoxDelegate 
 11  from camelot.view.controls.editors.choiceseditor import ChoicesEditor 
 12  import csv, itertools 
 13   
 14  _ = lambda x: x 
 15   
16 -class ImportWizard(QtGui.QWizard):
17 """Import wizard GUI"""
18 - def __init__(self, parent, attributes):
19 QWizard.__init__(self) 20 self.parent = parent 21 # the attributes of the object that will be imported 22 self.attributes = attributes
23 24 """ Make a wizard and the pages """
25 - def start(self):
26 self.qWizard = QWizard() 27 self.qWizard.setEnabled(True) 28 # qPage is the introduction page 29 self.qPage = ImportWizardPage(self.qWizard) 30 self.qPage.setTitle(QString('import wizard')) 31 32 self.makeToolBarToSearchFile() 33 34 #make grid 35 self.makeGridLayout() 36 37 #add layout to page 38 self.qPage.setLayout(self.grid) 39 self.qWizard.addPage(self.qPage) 40 41 #make the page that shows the table 42 self.qTablePage = QWizardPage(self.qWizard) 43 self.qTablePage.setTitle(QString('Data from file')) 44 45 self.qWizard.addPage(self.qTablePage) 46 47 cancelButton = QPushButton(QString('cancel'), self.qWizard) 48 self.qWizard.setButton(QWizard.CancelButton, cancelButton) 49 50 finishButton = QWizard.FinishButton 51 self.qWizard.setButtonText(finishButton, QString('import')) 52 53 self.qWizard.show() 54 self.qWizard.exec_()
55 56 """ 57 makes toolbar with button to open a csv-file. this is added at the qpage of a qwizard 58 """
59 - def makeToolBarToSearchFile(self):
60 self.openToolBar = QToolBar(self.qPage) 61 icon_file_open = Icon('tango/32x32/actions/fileopen.png').fullpath() 62 openAct = QtGui.QAction(QtGui.QIcon(icon_file_open), 'Open File', self.openToolBar) 63 self.openToolBar.connect(openAct, QtCore.SIGNAL('triggered()'), self.showOpenFileDialog) 64 self.openToolBar.addAction(openAct)
65
66 - def makeCheckBoxForFirstRow(self):
67 self.checkBox = QCheckBox('first row of data is column name') 68 action = QtGui.QAction('CheckBox', self.checkBox) 69 self.checkBox.connect(self.checkBox, QtCore.SIGNAL("clicked()"), self.repaintTable) 70 self.checkBox.addAction(action) 71 72 checkBox = QCheckBox('first row of data is column name') 73 action = QtGui.QAction('CheckBox', checkBox) 74 checkBox.connect(action, QtCore.SIGNAL('clicked()'), self.repaintTable) 75 checkBox.addAction(action) 76 return checkBox
77 78 """ 79 depending on the checkbox the table must be drawn again 80 """
81 - def repaintTable(self):
82 print 'repaint table' 83 if self.checkBox.checkState() == Qt.Unchecked: 84 newTable = self.makeTable(self.data, self.attributes) 85 self.updateTable(newTable) 86 else: 87 dataWithoutFirstRow = self.data[1:] 88 newTable = self.makeTable(dataWithoutFirstRow, self.attributes) 89 self.updateTable(newTable) 90 91 dataWithoutFirstRow = self.data[1:] 92 self.makeTable(dataWithoutFirstRow, self.attributes)
93 94 95 """ 96 makes the openfiledialog: when the file is committed, the table is shown. 97 the method prepares also the table to show 98 """
99 - def showOpenFileDialog(self):
100 filename = QtGui.QFileDialog.getOpenFileName(None, 'Open file', '/') 101 #make label 102 self.label.clear() 103 self.label = QtGui.QLabel(filename, self.qPage) 104 self.qPage.initializePath(filename) 105 self.grid.addWidget(self.label, 2, 0) 106 107 #open file 108 file=open(filename) 109 csvreader = csv.reader(file) 110 array = list(csvreader) 111 self.data = array 112 #checkbox 113 self.makeCheckBoxForFirstRow() 114 #tableview 115 self.tableView = self.makeTable(array, self.attributes, False) 116 self.setTableViewLayout()
117 118 """ layout of the page with the table 119 above a checkbox, below the table 120 """
121 - def setTableViewLayout(self):
122 self.vLayout = QVBoxLayout() 123 self.vLayout.addWidget(self.checkBox) 124 self.vLayout.addWidget(self.tableView) 125 self.qTablePage.setLayout(self.vLayout)
126 127 """ 128 if the checkbox is checked the first row isn't drawn anymore but used for the delegate 129 """
130 - def updateTable(self, newTable):
131 self.vLayout.removeWidget(self.tableView) 132 self.vLayout.addWidget(newTable) 133 self.tableView = newTable 134 self.vLayout.update()
135 136 """ the layout for the wizard """
137 - def makeGridLayout(self):
138 self.grid = QtGui.QGridLayout() 139 self.grid.setSpacing(10) 140 self.grid.addWidget(self.openToolBar, 1, 0) 141 self.label = QtGui.QLabel('select file', self.qPage) 142 self.grid.addWidget(self.label, 2, 0)
143 144 """ make the table for the page"""
145 - def makeTable(self, data, headerData, firstRow=False):
146 # create the view 147 tv = QTableView() 148 149 # set the table model 150 tm = InputTableModel(data, self.attributes, self.qTablePage) 151 152 tv.setModel(tm) 153 CHOICES = self.makeChoices(headerData) 154 155 delegate = ComboBoxEditorDelegate(choices=lambda o:CHOICES, parent=tv ) 156 tv.setItemDelegateForRow(0,delegate) 157 158 # set the minimum size 159 self.setMinimumSize(800, 600) 160 161 # hide grid 162 tv.setShowGrid(True) 163 164 # set the font 165 font = QFont("Courier New", 20) 166 tv.setFont(font) 167 168 # hide vertical header 169 vh = tv.verticalHeader() 170 vh.setVisible(False) 171 172 # hide horizontal header, the first row will be used as header 173 hh = tv.horizontalHeader() 174 hh.setVisible(False) 175 176 # set column width to fit contents 177 # will fale if to much data 178 #tv.resizeColumnsToContents() 179 180 # set row height 181 nrows = len(list(data)) 182 for row in xrange(nrows): 183 tv.setRowHeight(row, 18) 184 return tv
185 186 """" method for initializing the choices of the delegate. a tuple is returned"""
187 - def makeChoices(self, choices):
188 CHOICES = [] 189 for i in range(len(choices)): 190 CHOICES = CHOICES + [(str(i) , choices[i])] 191 return tuple(CHOICES)
192
193 - def makeHeader(self, model, header):
194 for column in range(len(header)): 195 index = model.index(0, column, QModelIndex()) 196 model.setData(index, QVariant(header[column]))
197 # can be done with the delegate, change this!!!! 198 #model.setData(index, QVariant(QColor(Qt.gray)), Qt.BackgroundColorRole) 199
200 - def makeBody(self, model, data):
201 for row in range(len(data)): 202 for column in range(len(self.attributes)): 203 index = model.index((row+1), column, QModelIndex()) 204 model.setData(index, QVariant(self.data[row][column]))
205 206 """method returning the imported data"""
207 - def getImportedData(self):
208 return list(self.data)
209 210 #class InputTableModel(QAbstractTableModel):
211 -class InputTableModel(QStandardItemModel):
212 """ class representing the table """
213 - def __init__(self, datain, headerData, parent=None, *args):
214 # QAbstractTableModel.__init__(self, parent, *args) 215 table = [headerData] + datain 216 QStandardItemModel.__init__(self, len(table), len(headerData), parent, *args) 217 self.fill_up_model(table)
218
219 - def __init__(self, datain, headerData, parent=None, *args):
220 QAbstractTableModel.__init__(self, parent, *args) 221 # the headerdata will be the first row in the table 222 # it is impossible to add a delegate to a qheaderview (it is possible but ignored) 223 # so add the data to the first row and add there the delegate 224 # you can add a (different) delegate for each row 225 #self.headerRow = headerData 226 self.fill_up_table(datain, headerData)
227 228 229
230 - def fill_up_table(self, datain, headerData, hints = None):
231 self.arraydata = list(datain) 232 self.arraydata.insert(0, headerData) 233 self.fill_up_header(hints)
234
235 - def fill_up_header(self, hints):
236 #first row of data can be a hint 237 print "hints" , hints 238 if not hints == None : 239 self.arraydata.insert(1, hints) 240 #for column in range(len(self.arraydata[0])): 241 # self.setData(self.index(0, column), hints[column], Qt.DisplayRole) 242 #if no hints are given, fill up the header with first attribute 243 #else: 244 #for column in range(len(self.arraydata[0])): 245 # self.setData(self.index(0, column), self.arraydata[0][0], Qt.DisplayRole) 246 247 self.emit(QtCore.SIGNAL("layoutChanged()"))
248 249
250 - def rowCount(self, parent):
251 #return len(self.arraydata) + len(self.headerRow[0]) 252 return len(self.arraydata)
253
254 - def columnCount(self, parent):
255 return len(self.arraydata[0])
256
257 - def data(self, index, role):
258 if not index.isValid(): 259 return QVariant() 260 elif role != Qt.DisplayRole: 261 return QVariant() 262 else: 263 return QVariant(QStandardItemModel.data(self, index, role)) 264 #if headerData != None: 265 # makeHeaderData() 266 #TODO, now the table is filled from (row = 0, column = 0) 267 # first row will have always a comboboxdelegate (index + 1) 268 # second row is maybe a "hint" for the choices of the comboboxdelegate (index + 2) 269 # so the actual data starts maybe at the index + 1 or index + 2 270 if not index.isValid(): 271 return QVariant() 272 elif role != Qt.DisplayRole: 273 return QVariant() 274 return QVariant(self.arraydata[index.row()][index.column()])
275
276 - def fill_up_model(self, table):
277 for row in range(len(table)): 278 data = table[row] 279 for column in range(len(data)): 280 index = self.index(row, column, QModelIndex()) 281 self.setData(index, QVariant(data[column]))
282 283
284 - def setData(self, index, value, role=Qt.ItemIsEditable):
285 self.arraydata[index.row()][index.column()] = value
286 287 """every item is editable, so no need to keep it for each object """
288 - def flags(self, index):
289 return Qt.ItemIsEditable
290 291
292 -class ImportWizardPage(QtGui.QWizardPage):
293 """ 294 class for the page shown in the wizard 295 """
296 - def __init__(self, parent=None, path=None, *args):
297 QWizardPage.__init__(self, parent, *args) 298 self.path = path
299
300 - def initializePath(self, path):
301 self.path = path 302 self.emit(QtCore.SIGNAL('completeChanged()'))
303
304 - def isComplete(self):
305 return self.path != None
306