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