def __init__(self, widget, cols=None, *args, **ka):
        QtCore.QAbstractTableModel.__init__(self, None)

        self._widget = widget

        self._peer = IncrementalMultiViewer(*args, delegate=self, **ka)

        self._updateChangedDeferred = None
        self._maxRow = self._minRow = -1

        self._columns  = []
        self._types    = []
        self._typeArgs = []
        self._labels   = []
        self._cache    = []
        self._parent   = QtCore.QModelIndex()

        if cols == None: cols = []

        self._minRowHeight = 0
        self._minColumnWidth = 0

        self._loading = 0

        self._sizeHints = {}

        if 'minRowHeight' in ka: self._minRowHeight = ka['minRowHeight']
        if 'minColumnWidth' in ka: self._minColumnWidth = ka['minColumnWidth']
        if 'sizeHints' in ka: self._sizeHints = ka['sizeHints']

        if self._minRowHeight == None: self._minRowHeight = 0
        if self._minColumnWidth == None: self._minColumnWidth = 0
        if self._sizeHints == None: self._sizeHints = {}

        if isinstance(cols, list) and len(cols) > 0 and isinstance(cols[0], dict):
            cols.insert(0, {'path':'id'})
            self._columns = []
            self._labels = []
            self._types = []
            self._typeArgs = []
            for cfg in cols:
                if cfg is None: continue
                self._columns.append(cfg.get('path', None))
                self._labels.append(cfg.get('label', None))
                self._types.append(FX.convertType(cfg.get('type', None)))
                self._typeArgs.append(cfg.get('type-args', None))
        else: 
            cols.insert(0, 'id')
            self._columns, self._labels = FX.splitList(cols, ':')
            self._types, self._typeArgs, self._columns = FX.extractType(self._columns)
    def __init__(self, widget, room, path, cols=['_id'], parent=None, conflictCB=None, isList=True, identifier=None, reverseOrder=False, minRowHeight=None, minColumnWidth=None, wrapInList=False, sizeHints=None, editOnInsert=False, *args):
        QtCore.QAbstractTableModel.__init__(self, parent, *args)

        self._peer   = EmbeddedViewer(room, path, delegate=self, conflictCB=conflictCB, isList=isList, wrapInList=wrapInList, identifier=identifier, editOnInsert=editOnInsert)
        self._widget = widget

        self._reverseOrder = reverseOrder

        self._imageCache = {}

        self._minRowHeight = 0
        self._minColumnWidth = 0
        self._sizeHints = {}

        if minRowHeight != None: self._minRowHeight = int(float(minRowHeight))
        if minColumnWidth != None: self._minColumnWidth = int(float(minColumnWidth))
        if sizeHints != None: self._sizeHints = sizeHints

        self._isList   = isList
        self._wrapInList = wrapInList
        self._columns  = []
        self._labels   = []
        self._types    = []
        self._typeArgs = []
        self._data     = self._emptyData()
        self._parent   = QtCore.QModelIndex()
        self._keys = None
        self._rows = None

        self._length = 0
           
        if isinstance(cols, list) and len(cols) > 0 and isinstance(cols[0], dict):
            self._columns = []
            self._labels = []
            self._types = []
            self._typeArgs = []
            for cfg in cols:
                if cfg is None: continue
                self._columns.append(cfg.get('path', None))
                self._labels.append(cfg.get('label', None))
                self._types.append(FX.convertType(cfg.get('type', None)))
                self._typeArgs.append(cfg.get('type-args', None))
        else: 
            self._columns, self._labels = FX.splitList(cols, ':')
            self._types, self._typeArgs, self._columns = FX.extractType(self._columns)
        self._path = path
    def register(self):
        EnableLogic.register(self)
        TriggeredPillowsLogic.register(self)

        self._sortable = {}
        self._sortField = {"__default__": "__default__"}

        sortable = []

        self.setAlternatingRowColors(self.alternateRowColors)

        converted = False
        for c in self.sortable:
            if c is None: 
                sortable.append(None)
                continue
                
            if isinstance(c, (unicode, str)):
                if ':' in c:
                    c, field = c.split(':')
                else:
                    field = c

                sortable.append({'sortPath': field, 'path': c})
                converted = True
            else:
                sortable.append(c)

        if converted: self.sortable = sortable

        for c in self.sortable:
            if c is None: continue

            field = c.get('sortPath', None)
            c = c.get('path', None)
               
            self._sortable[c] = 0
            self._sortField[c] = field

        if len(self._sortable) > 0:
            self.horizontalHeader().setSortIndicatorShown(True)
        else:
            self.horizontalHeader().setSortIndicatorShown(False)

        if self.multiSelect:
            self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        else:
            self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)

        if isinstance(self.dbColumns, list) and len(self.dbColumns) > 0 and isinstance(self.dbColumns[0], (str, unicode)):
            columns, labels = FX.splitList(self.dbColumns, ':')
            types, args, columns = FX.extractType(columns, json=False)

            dbColumns = []

            # convert old format
            for i in range(len(columns)):
                dbColumns.append({
                    'path': columns[i],
                    'label': labels[i],
                    'type': types[i],
                    'type-args': args[i]
                })

            self.dbColumns = dbColumns

        self._columns = []
        self._labels = []
        self._types = []
        for cfg in self.dbColumns:
            if cfg is None: continue
            self._columns.append(cfg.get('path', None))
            self._labels.append(cfg.get('label', None))
            self._types.append(FX.convertType(cfg.get('type', None)))

        if self.orderPath != None:
            self.verticalHeader().setMovable(True) 

        if self.keyCodePillows != None:
            for kca in self.keyCodePillows:
                kca = unicode(kca)
                lst = kca.split(':')
                code = lst.pop(0)
                if len(lst) >= 2:
                    room = lst.pop(0)
                else:
                    room = self.room

                pillow = lst.pop(0)

                feathers = None
                if ',' in pillow:
                    feathers = pillow.split(',')
                    pillow = feathers.pop(0)

                code = eval("QtCore.Qt." + code)

                self._keyCodePillows[code] = (room, pillow, feathers)


        self._autoColumns = []
        col = 0
        for t in self._types:
            hasDelegate = False
            if isinstance(t, dict):
                for k, v in t.items():
                    if not hasDelegate and len(v) > 0 and v[0] == ':':
                        self.setItemDelegateForColumn(col+1, self._imageDelegate)
                        self._autoColumns.append(col+1)
                        hasDelegate = True
            elif t == "progress":
                self.setItemDelegateForColumn(col+1, self._progressDelegate)
            elif t == "image":
                self.setItemDelegateForColumn(col+1, self._imageDelegate)
                self._autoColumns.append(col+1)
                hasDelegate = True

            col = col + 1

        if self.doubleClickPillow != None:
            self._actionPeer = ActionButtonPeer(self.room, self.doubleClickPillow, self.doubleClickFeathers, tab=self.doubleClickTab)

        from wallaby.frontends.qt.models.multiViewTableModel import MultiViewTableModel
        self._model = MultiViewTableModel(self, self.dbColumns, room=self.room, view=self.view, viewIdentifier=self.viewIdentifier, viewArguments=self.viewArguments, dataView=self.dataView, orderPath=self.orderPath, minRowHeight=self.minRowHeight, minColumnWidth=self.minColumnWidth, queryDocID=self.queryDocID, sizeHints=self.sizeHints)
        self.setModel(self._model)

        if self.idVisible:
            self.setColumnHidden(0, False)
        else:
            self.setColumnHidden(0, True)
    def register(self):
        EnableLogic.register(self)
        EditLogic.register(self)
        TriggeredPillowsLogic.register(self)

        self.setAlternatingRowColors(self.alternateRowColors)

        if (
            isinstance(self.dbColumns, list)
            and len(self.dbColumns) > 0
            and isinstance(self.dbColumns[0], (str, unicode))
        ):
            columns, labels = FX.splitList(self.dbColumns, ":")
            types, args, columns = FX.extractType(columns, json=False)

            dbColumns = []

            # convert old format
            for i in range(len(columns)):
                dbColumns.append({"path": columns[i], "label": labels[i], "type": types[i], "type-args": args[i]})

            self.dbColumns = dbColumns

        self._columns = []
        self._labels = []
        self._types = []
        for cfg in self.dbColumns:
            if cfg is None:
                continue

            self._columns.append(cfg.get("path", None))
            self._labels.append(cfg.get("label", None))
            self._types.append(FX.convertType(cfg.get("type", None)))

        self._autoColumns = []
        self._comboDelegate = []
        col = 0
        for t in self._types:
            hasDelegate = False
            if t is None:
                col = col + 1
                continue
            if isinstance(t, dict):
                for k, v in t.items():
                    if not hasDelegate and len(v) > 0 and v[0] == ":":
                        self.setItemDelegateForColumn(col, self._imageDelegate)
                        self._autoColumns.append(col)
                        hasDelegate = True
            elif "image" in t:
                self.setItemDelegateForColumn(col, self._imageDelegate)
                self._autoColumns.append(col)
                hasDelegate = True
            elif t == "progress":
                self.setItemDelegateForColumn(col, self._progressDelegate)
            elif t == "comboedit":
                self._comboDelegate.append(ComboBoxDelegate(self, col))
                self.setItemDelegateForColumn(col, self._comboDelegate[-1])

            col = col + 1

        from wallaby.frontends.qt.models.embeddedViewTableModel import EmbeddedViewTableModel

        self._model = EmbeddedViewTableModel(
            self,
            self.room,
            self.path,
            self.dbColumns,
            conflictCB=self._conflict,
            isList=self.isList,
            identifier=self.identifier,
            reverseOrder=self.reverseOrder,
            minRowHeight=self.minRowHeight,
            minColumnWidth=self.minColumnWidth,
            wrapInList=self.wrapInList,
            sizeHints=self.sizeHints,
            editOnInsert=self.editOnInsert,
        )

        if FXUI.mainWindow.options() != None and FXUI.mainWindow.options().app != "inspector":
            self._proxyModel = QtGui.QSortFilterProxyModel(self)
            self._proxyModel.setSourceModel(self._model)
            self._proxyModel.setFilterRegExp(
                QtCore.QRegExp("^(?!inspector-|itest-)", QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp2)
            )
            # proxyModel.setFilterRegExp(QtCore.QRegExp("^inspector", QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp2))

            # proxyModel.setFilterKeyColumn(0)
            self.setModel(self._proxyModel)
        else:
            self.setModel(self._model)

        if self.doubleClickPillow != None:
            self._actionPeer = ActionButtonPeer(
                self.room, self.doubleClickPillow, self.doubleClickFeathers, tab=self.doubleClickTab, translate=True
            )

        QtCore.QTimer.singleShot(0, self.restoreSettings)