Пример #1
0
class MainData(BaseObject):
    headers_1 = ['Data Id', 'Data Size']
    headers_2 = ['Data']

    def __init__(self):
        super(MainData, self).__init__()

        self.data = OrderedDict()
        self.data_keys = []

        self.interface1 = MainDataInterface1(self)
        self.interface2 = MainDataInterface2(self)

        self.data_changed = MrSignal()

    def _update_keys(self):
        self.data_keys.clear()
        self.data_keys.extend(list(self.data.keys()))

        self.data_changed.emit(list(self.data_keys))

    def rename(self, arg1, new_name_):
        if isinstance(arg1, int):
            old_name = self.data_keys[arg1]
        else:
            old_name = arg1

        old_data = OrderedDict(self.data)

        self.data.clear()

        _data = self.data

        for key, data in iteritems(old_data):
            if old_name == key:
                key = new_name_
            _data[key] = data

        self.data_changed.block()
        self._update_keys()
        self.data_changed.unblock()

        self.data_changed.emit(('rename', old_name, new_name_))

    def add(self, name=None):
        name = new_name(self.data, name)

        self.data[name] = self._new_data()

        self._update_keys()

        self.interface2.set_index(len(self.data) - 1)

    def insert(self, index, name=None, data=None):
        if name in self.data:
            name = new_name(self.data, name)

        old_data = OrderedDict(self.data)

        print('insert', name)

        self.data.clear()

        _data = self.data

        if data is None:
            _new_data = self._new_data()
        else:
            _new_data = data

        found_data = False

        i = 0
        for key, data in iteritems(old_data):
            if i == index:
                _data[name] = _new_data
                found_data = True
            _data[key] = data
            i += 1

        if not found_data:
            _data[name] = _new_data

        self.data_changed.block()
        self._update_keys()
        self.data_changed.unblock()

        self.data_changed.emit(('insert', index, name))

        self.interface2.set_index(index)

    def delete(self, index):
        old_data = OrderedDict(self.data)

        self.data.clear()

        _data = self.data

        index_ = index

        i = -1
        for key, data in iteritems(old_data):
            i += 1
            if i == index:
                continue
            _data[key] = data

        if index >= len(self.data):
            index -= 1

        self.data_changed.block()
        self._update_keys()
        self.data_changed.unblock()

        self.data_changed.emit(('delete', index_))

        self.interface2.set_index(index)

    def up(self, index):
        if index == 0:
            return False

        return self._move(index, index - 1)

    def down(self, index):
        if index == len(self.data) - 1:
            return False

        return self._move(index, index + 1)

    def _move(self, old_index, new_index):
        old_data = OrderedDict(self.data)
        old_keys = list(old_data.keys())

        self.data.clear()

        _data = self.data

        key_old = old_keys[old_index]
        data_old = old_data[key_old]

        key_new = old_keys[new_index]
        data_new = old_data[key_new]

        i = -1
        for key, data in iteritems(old_data):
            i += 1
            if i == new_index:
                _data[key_old] = data_old
                continue
            elif i == old_index:
                _data[key_new] = data_new
                continue
            _data[key] = data

        self._update_keys()

        self.interface2.set_index(new_index)

        return True

    @staticmethod
    def columns():
        return 1

    def _new_data(self):
        return np.zeros((1, self.columns()), dtype=np.float64)

    def __len__(self):
        return len(self.data)

    def serialize(self):
        result = []

        for key, data in iteritems(self.data):
            result.append((key, data.tostring()))

        return result

    def load(self, data):
        tmp = self._new_data()
        dtype = tmp.dtype
        cols = tmp.shape[1]

        for data_ in data:
            key, _data = data_
            tmp = np.fromstring(_data, dtype=dtype)
            self.data[key] = np.array(tmp.reshape((tmp.size // cols, cols)))

        self._update_keys()

    def clear(self):
        self.data.clear()
        self._update_keys()

    def ids(self):
        return list(self.data_keys)
Пример #2
0
class TableDataModel(QtCore.QAbstractTableModel):
    def __init__(self, *args):
        super(TableDataModel, self).__init__(*args)
        # self._headers = None
        self._data = None

        self._editable_columns = None
        """:type: set"""

        self.set_data = MrSignal()

    def setup_data(self, data):
        try:
            assert isinstance(data, TableDataList)
        except AssertionError:
            print(data.__class__)
            raise

        self._data = data
        # self._headers = list(data.headers)
        self._editable_columns = self._data.editable_columns()

        self.update_all()

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
        if self._data is not None and role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self._data.headers[section]
            else:
                return section + 1

        return None

    def rowCount(self, index=QtCore.QModelIndex()):
        try:
            return len(self._data)
        except TypeError:
            return 0

    def columnCount(self, index=QtCore.QModelIndex()):
        try:
            return len(self._data.headers)
        except (TypeError, AttributeError):
            return 0

    def flags(self, index):
        if int(index.column()) in self._editable_columns:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
        else:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if self._data is None or not index.isValid():
            return None

        if role == QtCore.Qt.EditRole:
            row = index.row()
            col = index.column()

            data_ = self._data[row]

            try:
                data = data_.edit_role(col)
            except AttributeError:
                data = data_[col]
            except TypeError:
                data = None

            if data is None:
                return ''

            return str(data)

        elif role == QtCore.Qt.DisplayRole:
            row = index.row()
            col = index.column()

            data_ = self._data[row]

            try:
                data = data_[col]
            except (TypeError, IndexError):
                data = None

            if data is None:
                return ''

            if isinstance(data, list) and len(data) > 0 and isinstance(
                    data[0], float):
                return str([round(i, 6) for i in data])

            return str(data)

        return None

    def setData(self, index, value, role=QtCore.Qt.DisplayRole):
        if self._data is None:
            return False

        row = index.row()
        col = index.column()

        self.set_data.emit((row, col), str(value), role)

        return True

    def update_all(self):
        try:
            self._editable_columns = self._data.editable_columns()
        except AttributeError:
            pass

        self.layoutChanged.emit()
        top_left = self.index(0, 0)
        bot_right = self.index(self.rowCount() - 1, self.columnCount() - 1)
        self.dataChanged.emit(top_left, bot_right)
Пример #3
0
class TableDataWidget(QtWidgets.QWidget):
    def __init__(self, *args):
        super(TableDataWidget, self).__init__(*args)

        self.ui = Ui_Form()
        self.ui.setupUi(self)

        self.tableView_list = DataTable.wrap_obj(self.ui.tableView_list)
        self.tableView_data = DataTable.wrap_obj(self.ui.tableView_data)

        self.tableView_list.set_editable_columns([0, 1])
        self.tableView_data.set_editable_columns([i for i in range(100)])

        self.ui.pushButton_add.clicked.connect(self._add)
        self.ui.pushButton_insert.clicked.connect(self._insert)
        self.ui.pushButton_delete.clicked.connect(self._delete)

        self.ui.pushButton_up.clicked.connect(self._up)
        self.ui.pushButton_down.clicked.connect(self._down)

        self.ui.pushButton_open.clicked.connect(self._open)

        self.main_data = MainData()
        """:type: fem.utilities.table_data_widget.model.MainData"""

        self.config = Configuration()

        self.tableView_list.setup_data(self.main_data.headers_1, self.main_data.interface1)
        self.tableView_data.setup_data(self.main_data.headers_2, self.main_data.interface2)

        self.tableView_list.selection_changed.connect(self._selection_changed)

        self.tableView_list.set_data_signal.connect(self._set_data_1)
        self.tableView_data.set_data_signal.connect(self._set_data_2)

        self.tableView_list.paste.connect(self._paste_1)
        self.tableView_data.paste.connect(self._paste_2)

        self.tableView_list.undo.connect(self._undo)
        self.tableView_list.redo.connect(self._redo)

        self.tableView_data.undo.connect(self._undo)
        self.tableView_data.redo.connect(self._redo)

        self.data_changed = MrSignal()

        self.main_data.data_changed.connect(self._data_changed)

    def _data_changed(self, *args):
        self.data_changed.emit(*args)

    def get_data(self):
        return self.main_data.data

    def clear_data(self):
        self.main_data.data.clear()

    def set_main_data(self, main_data):

        self.main_data.data_changed.disconnect_all()

        self.main_data = main_data
        """:type: fem.utilities.table_data_widget.model.MainData"""

        self.tableView_list.setup_data(self.main_data.headers_1, self.main_data.interface1)
        self.tableView_data.setup_data(self.main_data.headers_2, self.main_data.interface2)

        self.main_data.data_changed.connect(self._data_changed)

    def _open(self, *args):
        filename = getopenfilename(
            caption='Choose Data File',
            directory='',
            filter_=r'.txt (*.txt); .csv (*.csv)'
        )

        if filename in ('', None):
            return

        Action = Actions.ImportAction

        action_data = Action.ActionDataCls(filename)
        action = Action(self.main_data, action_data, self.config)

        command = Commands.ImportCommand(self, action)

        self.config.dispatch((action, action_data, command))

    def _undo(self, *args):
        self.config.dispatch('Undo')

    def _redo(self, *args):
        self.config.dispatch('Redo')

    def _add(self, *args):
        Action = Actions.AddAction

        action_data = Action.ActionDataCls(self.tableView_list.current_row())
        action = Action(self.main_data, action_data)

        command = Commands.AddCommand(self, action)

        self.config.dispatch((action, action_data, command))

    def _insert(self, *args):
        Action = Actions.InsertAction

        action_data = Action.ActionDataCls(self.tableView_list.current_row())
        action = Action(self.main_data, action_data)

        command = Commands.InsertCommand(self, action)

        self.config.dispatch((action, action_data, command))

    def _delete(self, *args):
        Action = Actions.RemoveAction

        action_data = Action.ActionDataCls(self.tableView_list.current_row())
        action = Action(self.main_data, action_data)

        command = Commands.RemoveCommand(self, action)

        self.config.dispatch((action, action_data, command))

    def _set_data_1(self, index, value, role):
        Action = Actions.SetDataAction

        table = self.tableView_list

        index = (table.current_row(), table.current_column())

        action_data = Action.ActionDataCls(index, value)
        action = Action(self.main_data.interface1, action_data)

        command = Commands.SetDataCommand(self, action)

        self.config.dispatch((action, action_data, command))

        return command.command_result

    def _set_data_2(self, index, value, role):
        Action = Actions.SetDataAction

        table = self.tableView_data

        index = (table.current_row(), table.current_column())

        action_data = Action.ActionDataCls(index, value)
        action = Action(self.main_data.interface2, action_data)

        command = Commands.SetDataCommand(self, action)

        self.config.dispatch((action, action_data, command))

        return command.command_result

    def _up(self, *args):
        Action = Actions.UpAction

        table = self.tableView_list

        action_data = Action.ActionDataCls(table.current_row())
        action = Action(self.main_data, action_data)

        command = Commands.UpCommand(self, action)

        self.config.dispatch((action, action_data, command))

    def _down(self, *args):
        Action = Actions.DownAction

        table = self.tableView_list

        action_data = Action.ActionDataCls(table.current_row())
        action = Action(self.main_data, action_data)

        command = Commands.DownCommand(self, action)

        self.config.dispatch((action, action_data, command))

    def _paste_1(self, selection, data):
        Action = Actions.PasteAction

        table = self.tableView_list

        action_data = Action.ActionDataCls(selection, data)
        action = Action(self.main_data.interface1, action_data)

        command = Commands.PasteCommand(self, action, table)

        self.config.dispatch((action, action_data, command))

    def _paste_2(self, selection, data):
        Action = Actions.PasteAction

        table = self.tableView_data

        action_data = Action.ActionDataCls(selection, data)
        action = Action(self.main_data.interface2, action_data)

        command = Commands.PasteCommand(self, action, table)

        self.config.dispatch((action, action_data, command))

    def update_all(self):
        self.tableView_list.update_all()
        self.tableView_data.update_all()

    def _selection_changed(self, row, col):
        self.main_data.interface2.set_index(row)
        self.tableView_data.update_all()
Пример #4
0
class OptionsLineEditDelegate(AbstractLineEditDelegate):
    def __init__(self, parent, data, options_data, dialog_title):
        """
        :param parent: QtWidgets.QLineEdit to whom the delegate belongs to
        :type parent: QtWidgets.QLineEdit
        :param data: AbstractData to whom the delegate sends _main_data to
        :type data: AbstractData
        """
        AbstractLineEditDelegate.__init__(self, parent, data)

        self.setObjectName(str(parent.objectName()) + "_delegate")

        self._dialog_title = dialog_title
        self._dialog = None
        self._options_data = options_data

        self.update_value = MrSignal()

        self._return_list = False

        if hasattr(self._options_data, 'return_data_list'):
            if self._options_data.return_data_list is True:
                self._return_list = True

    def execute(self, geometry=None):
        if self._enabled is False:
            return

        self._active = True

        self._dialog = OptionsDialog(self._dialog_title, parent=self._parent)
        self._dialog.skip_click = True
        self._dialog.finished.connect(self._update_value)

        options_data = self._options_data()

        data = options_data['_main_data']()
        headers = options_data['headers']
        widths = options_data['widths']
        initial_values = options_data['initial_values']()

        self._dialog.set_data(data)
        self._dialog.set_up_data_lists(headers, widths)
        self._dialog.initial_values(initial_values)
        self._dialog.align_to(self._parent)
        self._dialog.setFocus()
        self._dialog.exec_()

    def delegate(self):
        return self._dialog

    def done_editing(self, obj=None):
        return 0

    def _update_value(self, *args):
        try:
            if not self._return_list:
                value = self._dialog.return_data
                if value is None:
                    return
                self.update_value.emit(str(value))
            else:
                self.update_value.emit(map(str, self._dialog.return_data_list))
        except AttributeError:
            pass

    def hide(self):
        self._active = False
        try:
            self._dialog.hide()
        except AttributeError:
            pass

    def text(self):
        try:
            if not self._return_list:
                value = self._dialog.return_data
                if value is None:
                    return ""
                return str(value)
            else:
                list_ = self._dialog.return_data_list
                return "/".join(map(str, list_))
        except AttributeError:
            return ""

    def parent_text(self):
        return self._parent.text()
Пример #5
0
class TableNumpyDataList(AbstractTableDataList):

    CheckDataType = None
    DefaultDataType = None

    def __init__(self, data_id=None):
        self._data_id = data_id

        self.dtype = self.DefaultDataType.dtype

        self.blank_data = np.zeros(1, dtype=self.dtype)

        self.data = np.zeros(0, dtype=self.dtype)

        self._headers = list(
            self.data.dtype.names)[:self.DefaultDataType.columns()]

        self._ids = []

        self.list_changed = MrSignal()

    def clear(self):
        self.data.resize(0)

    def get_data(self):
        return self.data.tolist()

    def load_data(self, data):
        np.copyto(self.data, data)

    def add(self, data=None):

        self.data.resize(self.data.size + 1, refcheck=False)

        if data is not None:
            self.data[-1] = data

        self.list_changed.emit()

        return self.data[-1]

    def remove(self, index):
        if isinstance(index, (list, tuple)):
            i1 = index[0]
            i2 = index[1]
        else:
            i1 = index
            i2 = index

        indices = list(range(i1, i2 + 1))

        tmp = []

        for i in indices:
            tmp.append(tuple(self.data[i]))

        self.data = np.delete(self.data, indices)

        self.list_changed.emit()

        return tmp

    def insert(self, index, data=None):

        if data is not None:
            assert isinstance(data, tuple)
            try:
                if isinstance(data[0], tuple):
                    return self._insert_multiple(index, data)
            except IndexError:
                data = None

        if index < 0:
            index = 0

        if index >= self.data.size:
            return None

        if data is None:
            data = tuple(self.blank_data[0])

        self.data = np.insert(self.data, index, data)

        self.list_changed.emit()

        return self.data[index]

    def editable_columns(self):
        return set(range(len(self.headers)))

    def _insert_multiple(self, index, data):
        if index < 0:
            index = 0

        if index >= len(self.data) + 1:
            raise IndexError('%d' % index)

        self.list_changed.block()

        for data_ in data:
            self.data = np.insert(self.data, index, data_)

        self.list_changed.unblock()

        self.list_changed.emit()

        return data

    def serialize(self):
        data_i = self.DefaultDataType(self, 0)

        for i in range(self.data.shape[0]):
            data_i.index = i
            data_i.serialize()

        return base64.b64encode(compress(self.data.tobytes())).decode()

    def load(self, data):
        try:
            self.data = np.fromstring(decompress(
                base64.b64decode(data.encode())),
                                      dtype=self.dtype)
        except ValueError:
            print('get rid of this')
            return

        data_i = self.DefaultDataType(self, 0)

        for i in range(self.data.shape[0]):
            data_i.index = i
            data_i.load(self.data[i])

        # np.copyto(self._data, np.fromstring(base64.b64decode(data.encode()), dtype=self.dtype))

    def __getitem__(self, index):
        if isinstance(index, str):
            index = self.ids().index(index)

        return self.DefaultDataType(self, index)

    def set_data(self, index, value):
        row, column = index

        _data = self.DefaultDataType(self, row)

        try:
            old_value = _data[column]
            _data[column] = value
            new_value = _data[column]

            if old_value != new_value:
                return True, old_value, new_value
            else:
                return False, None, None
        except (MyExceptions.IndexError, MyExceptions.ValueError):
            return False, None, None

    @show_caller
    def __setitem__(self, index, data):
        assert isinstance(data, tuple)

        self.data[index] = data

    def id_exists(self, id_):

        data_i = self.DefaultDataType(self, 0)

        for i in range(self.data.shape[0]):
            data_i.index = i
            if data_i.id == id_:
                return True

        return False

    def subdata(self, index):
        return None

    def has_subdata(self):
        return None

    def find_index(self, data_id):
        assert isinstance(data_id, str)

        data_i = self.DefaultDataType(self, 0)

        for i in range(self.data.shape[0]):
            data_i.index = i
            if data_i.id == data_id:
                return i

        return -1

    def ids(self):

        data_i = self.DefaultDataType(self, 0)

        ids_ = []

        for i in range(self.data.shape[0]):
            data_i.index = i
            ids_.append(data_i.id)

        return ids_

    def _move(self, i1, i2):
        _data_i1 = tuple(self.data[i1])
        _data_i2 = tuple(self.data[i2])

        self.data[i1], self.data[i2] = _data_i2, _data_i1

        del self._ids[:]

        self.list_changed.emit()

    def shape(self):
        return self.data.shape[0], self.DefaultDataType.columns()

    @property
    def size(self):
        return self.__len__()

    def __len__(self):
        return self.data.shape[0]

    def get_index(self, data):
        pass

    def get_id(self):
        pass

    def up(self, index):
        pass

    def down(self, index):
        pass

    def insert_multiple(self, index, data):
        pass

    def validate(self, *args):
        pass

    @property
    def headers(self):
        return self._headers

    def remove_multiple(self, count):
        pass

    def add_multiple(self, count, data=None):
        pass
Пример #6
0
class TableDictList(AbstractTableDataList):
    CheckDataType = DummyTableData
    DefaultDataType = DummyTableData

    def __init__(self, data_id=None):
        self.data = {}
        """:type: dict[DummyTableData]"""

        self._headers = list(self.DefaultDataType.headers)

        self._data_id = data_id

        self.list_changed = MrSignal()

        self._ids = []

    def clear(self):
        self.data.clear()
        del self._ids[:]

    def get_id(self):
        return self._data_id

    @property
    def headers(self):
        return self._headers

    def get_data(self):
        return list(self.data.values())

    def load_data(self, data):
        self.data.clear()

        for _data in data:
            self.data[_data.id] = data

        self._update_ids()

    def add(self, *data):

        tmp = self.DefaultDataType()
        tmp.register_model(self.model)

        if len(data) > 0:
            tmp.load(data)

        self.data[tmp.id] = tmp

        self.list_changed.emit()

        del self._ids[:]

        return tmp

    def remove(self, index):
        try:
            tmp = self.data[index]
            del self.data[index]
        except MyExceptions.IndexError:
            return None

        self.list_changed.emit()

        return tmp

    def add_multiple(self, count, data=None):

        raise NotImplementedError

        result = []

        self.list_changed.block()

        if isinstance(data, (list, tuple)):
            assert count == len(data)
            for data_i in data:
                result.append(self.add(data_i))
        else:
            for i in range(count):
                result.append(self.add())

        self.list_changed.unblock()

        if len(result) > 0:
            del self._ids[:]
            self.list_changed.emit()

        return result

    def remove_multiple(self, count):

        raise NotImplementedError

        result = []

        self.list_changed.block()

        data_len = self.shape()[0]

        last_i = data_len

        for i in range(count):
            last_i -= 1
            try:
                result.append(self.remove(last_i)[0])
            except IndexError:
                pass

        self.list_changed.unblock()

        if len(result) > 0:
            del self._ids[:]
            self.list_changed.emit()

        return result

    def insert(self, index, *data):

        if len(data) > 1:
            tmp = self.DefaultDataType(*data)
        else:
            tmp = self.DefaultDataType()

        if index < 0:
            index = 0

        try:
            self.data.insert(index, tmp)
            del self._ids[:]
            self.list_changed.emit()
            return tmp
        except MyExceptions.IndexError:
            return None

    def insert_multiple(self, index, data):
        if index < 0:
            index = 0

        if index >= len(self.data) + 1:
            raise IndexError('%d' % index)

        self.list_changed.block()

        result = []

        for data_ in data:
            result_ = self.data.insert(index, data_)
            if result_ is not None:
                result.append(result_)

        self.list_changed.unblock()

        if len(result) > 0:
            del self._ids[:]
            self.list_changed.emit()

        return result

    def shape(self):
        return len(self.data), len(self.headers)

    def editable_columns(self):
        return set(range(len(self.headers)))

    def set_data(self, index, value):
        row, column = index

        try:
            old_value = self.data[row][column]
            self.data[row][column] = value
            new_value = self.data[row][column]

            if old_value != new_value:
                del self._ids[:]
                print('data is valid 2')
                return True, old_value, new_value
            else:
                print('old and new values equal')
                return False, None, None
        except (MyExceptions.IndexError, MyExceptions.ValueError):
            print('index or value error')
            print(self.data[row])
            return False, None, None

    def validate(self, *args):
        raise NotImplementedError

    def serialize(self):
        data = []

        for data_i in self.data:
            data.append(data_i.serialize())

        return data

    def load(self, data):
        self.list_changed.block()

        for data_i in data:
            self.add(data_i)

        self.list_changed.unblock()

        del self._ids[:]

        # self._update_ids()

        # make sure to update other data if needed

    def _move(self, i1, i2):
        self.data[i1], self.data[i2] = self.data[i2], self.data[i1]
        del self._ids[:]
        self.list_changed.emit()

    def up(self, index):
        if index <= 0 or index >= len(self.data):
            return False

        i1 = index
        i2 = index - 1

        self._move(i1, i2)

        return True

    def down(self, index):
        if index < 0 or index >= len(self.data) - 1:
            return False

        i1 = index
        i2 = index + 1

        self._move(i1, i2)

        return True

    def __len__(self):
        return len(self.data)

    def __getitem__(self, index):
        if isinstance(index, str):
            if index == '':
                return None
            index = self.ids().index(index)
        return self.data[index]

    @show_caller
    def __setitem__(self, index, data):
        assert isinstance(data, self.CheckDataType)
        # TODO: what to do here?
        self.data[index] = data

    def id_exists(self, id_):
        for data_i in self.data:
            if data_i.id == id_:
                return True

        return False

    def subdata(self, index):
        row, column = index
        try:
            return self.data[row].subdata(column)
        except (AttributeError, IndexError):
            return None

    def has_subdata(self):
        try:
            data = self.data[0]
        except IndexError:
            return None
        except KeyError:
            raise KeyError(self._data_id)

        for i in range(len(data)):
            try:
                subdata = data.subdata(i)
                if subdata is not None:
                    return subdata
            except NotImplementedError:
                pass

        return None

    def find_index(self, data_id):
        if isinstance(data_id, str):
            data = self.data
            for i in range(len(data)):
                if data[i].id == data_id:
                    return i
        elif isinstance(data_id, self.CheckDataType):
            data = self.data
            for i in range(len(data)):
                if data_id is data[i]:
                    return i
        return -1

    def get_index(self, data):
        return data

    def ids(self):
        if len(self._ids) == 0:
            self._update_ids()

        return list(self._ids)

    def _update_ids(self):
        del self._ids[:]

        _ids = self._ids

        for data in self.data:
            _ids.append(data.id)

    @property
    def size(self):
        return len(self.data)
Пример #7
0
class RecursiveTable(QtWidgets.QWidget):

    def __init__(self, parent=None, main_data=None, *args):
        super(RecursiveTable, self).__init__(parent, *args)

        # FIXME: main_data should be renamed to table_data since it is confusing with app main_data
        self.main_data = main_data

        self.config = Configuration(self.main_data.get_id())

        self.table = EmptyTable(self)

        self.dispatcher = self.config.dispatcher
        self.dispatcher.main_window = self
        self.dispatcher.table = self.table
        self.dispatcher.get_model = self.main_data

        self.Actions = self.config.Actions
        self.Commands = self.config.Commands

        self.Actions.set_main_data(self.main_data)
        self.Commands.set_main_window(self)

        self.table.pushButton_add.clicked.connect(self._add)
        self.table.pushButton_insert.clicked.connect(self._insert)
        self.table.pushButton_delete.clicked.connect(self._delete)

        self.table.pushButton_up.clicked.connect(self._up)
        self.table.pushButton_down.clicked.connect(self._down)

        self.table_model = TableDataModel()
        self.table.set_model(self.table_model)

        self.table.set_data.connect(self._set_data)
        self.table.paste.connect(self._paste)
        self.table.set_rows.connect(self._set_rows)
        self.table.undo.connect(self._undo)
        self.table.redo.connect(self._redo)

        self.table_model.setup_data(self.main_data)

        self._splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        self._splitter.addWidget(self.table)

        self.setLayout(QtWidgets.QHBoxLayout())

        self.layout().addWidget(self._splitter)

        self.table.selection_changed.connect(self._selection_changed)
        self.table.data_changed.connect(self._data_changed)

        self.subtable = None
        """:type: RecursiveTable"""

        self.data_changed = MrSignal()

    ####################################################################################################################

    def finalize(self):
        self.main_data = None
        self.config = None

        try:
            self.table.setParent(None)
        except RuntimeError:
            pass

        self.table = None

        self.dispatcher = None
        self.Actions = None
        self.Commands = None

        try:
            self.table_model.setParent(None)
        except RuntimeError:
            pass

        self.table_model = None

        try:
            self._splitter.setParent(None)
        except RuntimeError:
            pass

        self._splitter = None

        if self.subtable is not None:
            self.clear_data()

        self.subtable = None

        self.data_changed.disconnect_all()

    def _data_changed(self, *args):
        self.data_changed.emit()

    def _hide_subtable(self):
        if self.subtable is not None:
            # self.subtable.setParent(self)
            self.subtable.hide()

    def _show_subtable(self):
        if self.subtable is not None:
            self._splitter.addWidget(self.subtable)
            self.subtable.show()

    def _subtable(self, subdata):
        if subdata is not None:
            if self.subtable is None:
                self.subtable = RecursiveTable(parent=self, main_data=subdata)
                self.subtable.layout().setContentsMargins(QtCore.QMargins(0, 0, 0, 0))
                self.dispatcher.add_child(self.subtable.dispatcher)
                self._splitter.addWidget(self.subtable)
                self.subtable.hide()
                # noinspection PyProtectedMember
                self.subtable.data_changed.connect(self._data_changed)

            self.subtable.set_main_data(subdata)

        return self.subtable

    def force_update(self, index=None):
        if index is None:
            index = self._index()
        self._selection_changed(index)

    ####################################################################################################################

    def serialize(self):
        data = []

        for i in range(len(self.main_data)):
            data.append(self.main_data[i].serialize())

    def load(self, data):
        for i in range(len(data)):
            self.main_data.add().load(data[i])

    def clear(self):
        self.main_data.clear()
        self.update_all()

    def set_main_data(self, main_data):
        self.main_data = main_data

        try:
            self.dispatcher.get_model = main_data
        except AttributeError:
            print(self)
            raise


        self.Actions.set_main_data(self.main_data)
        self.table_model.setup_data(self.main_data)

        self.table.lineEdit_rows.setText(str(self.main_data.shape()[0]))

        self._selection_changed()

        self._update_all()

    def _update_all(self):
        self.table_model.update_all()
        self.table.lineEdit_rows.setText(str(self.table.row_count()))

    def update_all(self):
        self._update_all()

        try:
            self.subtable.update_all()
        except AttributeError:
            pass

    ####################################################################################################################

    def _selection_changed(self, index=None):

        if self.subtable is None:
            self._subtable(self.main_data.has_subdata())

        subdata = self._subdata(index)
        subtable = self._subtable(subdata)

        if None in (subtable, subdata):
            self._hide_subtable()
        else:
            self._show_subtable()

    ####################################################################################################################

    def _subdata(self, index=None):
        if index is None:
            index = self._index()

        return self.main_data.subdata(index)

    def _index(self):
        return self.table.current_index()

    ####################################################################################################################

    def _add(self):
        self.dispatcher.dispatch(('Add', ()))

    def _insert(self):
        self.dispatcher.dispatch(('Insert', (self._index(),)))

    def _delete(self):
        self.dispatcher.dispatch(('Remove', (self.table.selection(),)))

    def _up(self):
        self.dispatcher.dispatch(('Up', (self._index(),)))

    def _down(self):
        self.dispatcher.dispatch(('Down', (self._index(),)))

    def _set_data(self, enter_down, index, value, role):
        self.dispatcher.dispatch(('SetData', (index, value, enter_down)))

    def _paste(self, selection, data):
        self.dispatcher.dispatch(('Paste', (selection, data)))

    def _set_rows(self, rows):
        if rows < 0:
            self.table.lineEdit_rows.setText(str(self.table.table.model().rowCount()))
            return

        self.dispatcher.dispatch(('SetRows', (rows,)))

    def _undo(self, *args):
        self.dispatcher.dispatch('Undo')

    def _redo(self, *args):
        self.dispatcher.dispatch('Redo')

    ####################################################################################################################

    # @show_stack_trace
    def keyPressEvent(self, event):
        super(RecursiveTable, self).keyPressEvent(event)

        if event.isAccepted():
            return

        if event.matches(QtGui.QKeySequence.Undo):
            event.accept()
            self._undo()

        elif event.matches(QtGui.QKeySequence.Redo):
            event.accept()
            self._redo()

    def clear_data(self):

        self.dispatcher.clear_children()

        if self.subtable is not None:
            self.subtable.main_data = None
            self.subtable.hide()
Пример #8
0
class GroupsDock(QtWidgets.QDockWidget):
    def __init__(self, main_window):
        super(GroupsDock, self).__init__(main_window)

        self.main_window = main_window

        self.ui = Ui_DockWidget()
        self.ui.setupUi(self)

        self._groups_table_model = GroupsTableModel()
        self.ui.tableView_groups.setModel(self._groups_table_model)

        self._groups_selection_model = self.ui.tableView_groups.selectionModel(
        )
        """:type: QtGui.QItemSelectionModel"""

        self._groups_selection_model.selectionChanged.connect(
            self._groups_selection_changed)

        self.row_changed = MrSignal()
        self.column_changed = MrSignal()
        self.selection_changed = MrSignal()

        self._old_row = -1
        self._old_column = -1

        self.ui.pushButton_add_group.clicked.connect(self.add_group)
        self.ui.pushButton_remove_group.clicked.connect(self.remove_group)

        self.ui.pushButton_add_member.clicked.connect(self.add_members)
        self.ui.pushButton_remove_member.clicked.connect(self.remove_members)

        self._selection = PickedSelection()

        self._selection.data_changed.connect(self._picked_data_changed)

        self.setWindowTitle('Plot/Erase Groups')

    def add_group(self, group_name=None, group_members=None):
        if group_name in (False, None):
            group_name = fem_groups.new_name()

        group = fem_groups.add_group(group_name)

        if group_members is not None:
            group.set_data(group_members)

        self._groups_table_model.update_all()

    def remove_group(self, group):
        if isinstance(group, int):
            group = fem_groups.get_group_by_index(group)
        elif isinstance(group, str):
            group = fem_groups.get_group(group)
        else:
            raise TypeError(
                'GroupsDock.remove_group: group is not an int or string! %s' %
                str(group))

        fem_groups.remove_group(group.group_name)

        self._groups_table_model.update_all()

    def add_members(self):
        group = self._current_group()

        if group.group_name == 'Default':
            return

        group.add_data(str(self.ui.lineEdit_selection.text()))
        self._update_members_list()

    def remove_members(self):
        group = self._current_group()

        if group.group_name == 'Default':
            return

        group.remove_data(str(self.ui.lineEdit_selection.text()))
        self._update_members_list()

    def show_and_register(self):
        self.show()

        if self._old_row == -1:
            self._groups_row_changed(0)

        from fem.gui.vtk_widget.vtk_graphics.picking import PickingManager

        picking_manager = PickingManager.instance()
        picking_manager.register_selection(self._selection)

        self.main_window.show_dock(self)

    def _groups_selection_changed(self, current, previous):
        """
        :type current: QtGui.QItemSelection
        :type previous:QtGui.QItemSelection
        """

        try:
            first_index = current.indexes()[0]
        except IndexError:
            return

        new_row = first_index.row()
        new_column = first_index.column()

        old_row = self._old_row
        old_column = self._old_column

        selection_changed = False

        if new_row != old_row:
            self._old_row = new_row
            self.row_changed.emit(self._old_row)
            selection_changed = True
            self._groups_row_changed(new_row)

        if new_column != old_column:
            self._old_column = new_column
            self.column_changed.emit(self._old_column)
            selection_changed = True

        if selection_changed:
            self.selection_changed.emit(new_row, new_column)

    def _groups_row_changed(self, row):
        new_group = fem_groups.get_group_by_index(row)

        self.ui.plainTextEdit_members.setPlainText(new_group.to_str())

    def _picked_data_changed(self, *args):
        self.ui.lineEdit_selection.setText(self._selection.to_str())

    def _current_group(self):
        row = self._groups_selection_model.currentIndex().row()
        return fem_groups.get_group_by_index(row)

    def _update_members_list(self):
        group = self._current_group()
        self.ui.plainTextEdit_members.setPlainText(group.to_str())

    def update_all(self):
        self._groups_table_model.update_all()
Пример #9
0
class TableDataList(AbstractTableDataList):
    CheckDataType = DummyTableData
    DefaultDataType = DummyTableData

    def __init__(self, data_id=None):
        self.data = []
        """:type: list[DummyTableData]"""

        self._headers = list(self.DefaultDataType.headers)
        self._formats = list(self.DefaultDataType.formats)
        self._setters = list(self.DefaultDataType.setters)

        self._data_id = data_id

        self.list_changed = MrSignal()

        self._ids = []

    def clear(self):
        try:
            self.data.clear()
        except AttributeError:
            del self.data[:]

        del self._ids[:]

    def get_id(self):
        return self._data_id

    @property
    def headers(self):
        return self._headers

    @property
    def formats(self):
        return self._formats

    @property
    def setters(self):
        return self._setters

    def get_data(self):
        return list(self.data)

    def load_data(self, data):
        del self.data[:]
        self.data.extend(list(data))
        self._update_ids()

    def add(self, *data):
        tmp = self.DefaultDataType()

        # object needs to be added to data first for logging purposes
        self.data.append(tmp)

        if len(data) > 0:
            tmp.load(data)

        self.list_changed.emit()

        del self._ids[:]

    def remove(self, index):
        try:
            tmp = self.data[index]
            del self.data[index]
        except MyExceptions.IndexError:
            return None

        self.list_changed.emit()

    def remove_multiple(self, indices):
        offset = 1
        for i in range(1, len(indices)):
            indices[i] -= offset
            offset += 1

        for i in indices:
            self.remove(i)

    def insert(self, index, *data):
        tmp = self.DefaultDataType()

        if index < 0:
            index = 0

        try:
            self.data.insert(index, tmp)
            if len(data) > 0:
                tmp.load(data)
            del self._ids[:]
            self.list_changed.emit()
        except MyExceptions.IndexError:
            pass

    def insert_multiple(self, indices):
        """
        
        :param indices: 
        :type indices: list[int]
        :return: 
        """

        if len(indices) == 0:
            return

        offset = 1
        for i in range(1, len(indices)):
            indices[i] += offset
            offset += 1

        for i in indices:
            self.insert(i)

    def shape(self):
        return len(self.data), len(self.headers)

    def editable_columns(self):
        return set(range(len(self.headers)))

    def set_data(self, index, value):
        row, column = index

        try:
            data = self.data[row]
        except MyExceptions.IndexError:
            print('index error')
            return

        getattr(data, self._setters[column])(value)

    def validate(self, *args):
        raise NotImplementedError

    def serialize(self):
        data = []

        for data_i in self.data:
            data.append(data_i.serialize())

        return data

    def load(self, data):
        self.list_changed.block()

        for data_i in data:
            self.add(data_i)

        self.list_changed.unblock()

        del self._ids[:]

        # self._update_ids()

        # make sure to update other data if needed

    def _move(self, i1, i2):
        self.data[i1], self.data[i2] = self.data[i2], self.data[i1]
        del self._ids[:]
        self.list_changed.emit()

    def up(self, index):
        if index <= 0 or index >= len(self.data):
            return False

        i1 = index
        i2 = index - 1

        self._move(i1, i2)

        return True

    def down(self, index):
        if index < 0 or index >= len(self.data) - 1:
            return False

        i1 = index
        i2 = index + 1

        self._move(i1, i2)

        return True

    def __len__(self):
        return len(self.data)

    def __getitem__(self, index):
        if isinstance(index, str):
            if index == '':
                return None
            index = self.ids().index(index)
        return self.data[index]

    @show_caller
    def __setitem__(self, index, data):
        assert isinstance(data, self.CheckDataType)
        # TODO: what to do here?
        self.data[index] = data

    def id_exists(self, id_):
        for data_i in self.data:
            if data_i.id == id_:
                return True

        return False

    def subdata(self, index):
        row, column = index
        try:
            return self.data[row].subdata(column)
        except (AttributeError, IndexError):
            return None

    def has_subdata(self):
        try:
            data = self.data[0]
        except IndexError:
            return None
        except KeyError:
            raise KeyError(self._data_id)

        for i in range(len(data)):
            try:
                subdata = data.subdata(i)
                if subdata is not None:
                    return subdata
            except NotImplementedError:
                pass

        return None

    def find_index(self, data_id):
        if isinstance(data_id, str):
            data = self.data
            for i in range(len(data)):
                if data[i].id == data_id:
                    return i
        elif isinstance(data_id, self.CheckDataType):
            data = self.data
            for i in range(len(data)):
                if data_id is data[i]:
                    return i
        return -1

    def get_index(self, data):
        return data

    def ids(self):
        if len(self._ids) == 0:
            self._update_ids()

        return list(self._ids)

    def _update_ids(self):
        del self._ids[:]

        _ids = self._ids

        for data in self.data:
            _ids.append(data.id)

    @property
    def size(self):
        return len(self.data)

    def get_formatted_data_by_index(self, index):
        row, col = index

        return self._formats[col] % self.data[row][col]

    def get_edit_data_by_index(self, index):
        row, col = index
        return str(self.data[row][col])

    def resize(self, new_size):
        data_len = len(self.data)

        if data_len == new_size:
            return

        if new_size > data_len:
            diff = new_size - data_len

            for i in range(diff):
                self.add()

        else:
            diff = data_len - new_size

            last_i = data_len - 1

            for i in range(diff):
                self.remove(last_i)
                last_i -= 1
Пример #10
0
class PolyPicker(vtkCameraManipulator):
    def __init__(self):
        vtkCameraManipulator.__init__(self)

        self._start_position = [0, 0]
        self._end_position = [0, 0]
        self._pixel_array = vtk.vtkUnsignedCharArray()

        self._left_button_down = False
        self._ctrl_left_button_down = False
        self._right_button_down = False
        self._middle_button_down = False

        self._down_pos = None
        self._up_pos = None

        self._point_list = []

        self.renderer = None
        self.iren = None

        #self.reset_polygon()
        self._points = 0

        self.polygon = vtk.vtkPolygon()

        self.poly_data = vtk.vtkPolyData()
        self.poly_points = vtk.vtkPoints()
        self.poly_data.SetPoints(self.poly_points)

        self.cell_array = vtk.vtkCellArray()
        self.cell_array.InsertNextCell(self.polygon)
        self.cell_array.Squeeze()

        self.poly_data.SetPolys(self.cell_array)

        self.done_picking = MrSignal()
        self._picking_active = False

        self.poly_pick_filter = PolyPickFilter()
        self.poly_pick_filter.set_poly_pick_data(self.poly_data)

        self.vtk_graphics = VTKGraphics.instance()

        from .picking_manager import PickingManager
        self.picking_manager = PickingManager.instance()

    def set_input_connection(self, port):
        self.poly_pick_filter.SetInputConnection(port)

    def reset_polygon(self):
        self._point_list = []
        self._points = 0
        self.poly_points.Reset()
        self.polygon.GetPointIds().Reset()

    def begin_picking(self, renderer, interactor):
        self.reset_polygon()

        self.renderer = renderer
        self.iren = interactor

        self.poly_pick_filter.set_renderer(renderer)

        self.ren_win = interactor.GetRenderWindow()
        self.ren_win_size = self.ren_win.GetSize()

        self._pixel_array.Reset()
        self._pixel_array.SetNumberOfComponents(4)
        self._pixel_array.SetNumberOfTuples(self.ren_win_size[0] * self.ren_win_size[1])

        self.ren_win.GetRGBACharPixelData(0, 0, self.ren_win_size[0] - 1, self.ren_win_size[1] - 1, 1,
                                          self._pixel_array)

        pos = interactor.GetEventPosition()

        self._first_point = pos
        self._last_point = pos

        self._points = 0

        self._picking_active = True

    def self_intersecting(self):

        def on_segment(p, r, q):

            max0 = max(p[0], r[0])
            min0 = min(p[0], r[0])

            max1 = max(p[1], r[1])
            min1 = min(p[1], r[1])

            if min0 <= q[0] <= max0 and min1 <= q[1] <= max1:
                return True
            else:
                return False

        def orientation(p, r, q):
            val = int((q[1] - p[1])*(r[0] - q[0]) - (q[0] - p[0])*(r[1] - q[1]))

            if val == 0:
                return 0

            if val > 0:
                return 1
            else:
                return 2

        def does_intersect(p1, q1, p2, q2):

            if p1 == p2 or p1 == q2 or q1 == p2 or q1 == q2:
                return False

            o1 = orientation(p1, q1, p2)
            o2 = orientation(p1, q1, q2)
            o3 = orientation(p2, q2, p1)
            o4 = orientation(p2, q2, q1)

            if o1 != o2 and o3 != o4:
                return True

            if o1 == 0 and on_segment(p1, q1, p2):
                return True

            if o2 == 0 and on_segment(p1, q1, q2):
                return True

            if o3 == 0 and on_segment(p2, q2, p1):
                return True

            if o4 == 0 and on_segment(p2, q2, q1):
                return True

            return False

        pl = self._point_list

        points = len(pl)

        if points <= 2:
            return False

        e1 = [pl[0], pl[points-1]]
        e2 = [pl[points-2], pl[points-1]]

        for i in range(1, points-1):
            p1 = pl[i]
            p2 = pl[i-1]

            if does_intersect(p1, p2, e1[0], e1[1]) or does_intersect(p1, p2, e2[0], e2[1]):
                return True

        return False

    def add_point(self, interactor, renderer):

        def distance(p1, p2):
            sum = (p1[0] - p2[0])**2
            sum += (p1[1] - p2[1])**2

            return sum ** 0.5

        pos = interactor.GetEventPosition()

        if self._points > 2 and (distance(pos, self._last_point) <= 5 or distance(pos, self._first_point) <= 5):
            self.end_picking(self.renderer, interactor)
            return True

        self._point_list.append(pos)

        if self.self_intersecting():
            self._point_list.pop()
            return False

        world_point = display_to_world(pos, renderer, .001)
        self.poly_points.InsertNextPoint(world_point[:3])

        self._last_point = pos

        self.polygon.GetPointIds().InsertNextId(self._points)
        self.polygon.Modified()

        self._points += 1

        return False

    def end_picking(self, renderer, interactor):
        self.something_picked()
        self._picking_active = False
        self.done_picking.emit()

    def get_picking_frustums(self):
        return []

    def something_picked(self):
        self.poly_points.Modified()
        self.polygon.Modified()
        self.poly_data.SetPoints(self.poly_points)
        self.cell_array.Reset()
        self.cell_array.InsertNextCell(self.polygon)
        self.cell_array.Squeeze()
        self.poly_data.SetPolys(self.cell_array)
        self.poly_data.Modified()

        self.poly_pick_filter.set_poly_pick_data(self.poly_data)
        self.poly_pick_filter.Modified()
        self.poly_pick_filter.Update()

        global_ids = self.poly_pick_filter.GetOutputDataObject(0).GetCellData().GetArray("global_ids")

        if global_ids is None:
            self.picking_manager.set_picked_data([])
            return

        get_value = global_ids.GetValue

        data = []

        for i in range(global_ids.GetNumberOfTuples()):
            data.append(get_value(i))

        self.picking_manager.set_picked_data(data)

    def _redraw_picking_box(self, interactor):
        tmp_array = vtk.vtkUnsignedCharArray()
        tmp_array.DeepCopy(self._pixel_array)

        min = [0, 0]
        max = [0, 0]

        size = self.ren_win_size

        if self._start_position[0] <= self._end_position[0]:
            min[0] = self._start_position[0]
        else:
            min[0] = self._end_position[0]

        if min[0] < 0:
            min[0] = 0
        if min[0] >= size[0]:
            min[0] = size[0] - 1

        if self._start_position[1] <= self._end_position[1]:
            min[1] = self._start_position[1]
        else:
            min[1] = self._end_position[1]

        if min[1] < 0:
            min[1] = 0
        if min[1] >= size[1]:
            min[1] = size[1] - 1

        if self._end_position[0] > self._start_position[0]:
            max[0] = self._end_position[0]
        else:
            max[0] = self._start_position[0]

        if max[0] < 0:
            max[0] = 0
        if max[0] >= size[0]:
            max[0] = size[0] - 1

        if self._end_position[1] > self._start_position[1]:
            max[1] = self._end_position[1]
        else:
            max[1] = self._start_position[1]

        if max[1] < 0:
            max[1] = 0
        if max[1] >= size[1]:
            max[1] = size[1] - 1

        point_list = self._point_list[:]
        point_list.append(self._end_position)

        my_int = int

        for i in range(1, len(point_list)):
            p1 = point_list[i-1]
            p2 = point_list[i]

            points = get_line_pixels(p1, p2)

            for p in points:
                index1 = p[1] * size[0] + p[0]
                tmp_array.SetTuple4(index1, 255, 120, 0, 1)

        p1 = list(point_list[0])
        p2 = list(point_list[-1])

        points = get_line_pixels(p1, p2)
        for p in points:
            index1 = p[1] * size[0] + p[0]
            tmp_array.SetTuple4(index1, 255, 120, 0, 1)

        p1[1] += 1
        p2[1] += 1

        points = get_line_pixels(p1, p2)
        for p in points:
            index1 = p[1] * size[0] + p[0]
            tmp_array.SetTuple4(index1, 255, 120, 0, 1)

        p1[1] -= 2
        p2[1] -= 2

        points = get_line_pixels(p1, p2)
        for p in points:
            index1 = p[1] * size[0] + p[0]
            tmp_array.SetTuple4(index1, 255, 120, 0, 1)

        p1[1] += 1

        point_list = [[p1[0] - 5, p1[1] + 5], [p1[0] + 5, p1[1] + 5], [p1[0] + 5, p1[1] - 5], [p1[0] - 5, p1[1] - 5]]
        point_list.append(point_list[0])

        for i in range(1, len(point_list)):
            p1 = point_list[i-1]
            p2 = point_list[i]

            points = get_line_pixels(p1, p2)

            for p in points:
                index1 = p[1] * size[0] + p[0]
                tmp_array.SetTuple4(index1, 255, 120, 0, 1)

        interactor.GetRenderWindow().SetRGBACharPixelData(0, 0, size[0] - 1, size[1] - 1, tmp_array, 0)
        interactor.GetRenderWindow().Frame()

    def OnButtonDown(self, x, y, ren, iren):
        if self._picking_active:
            self.add_point(iren, ren)
        else:
            self.begin_picking(ren, iren)
            self.add_point(iren, ren)

    def OnButtonUp(self, x, y, ren, iren):
        #self.end_picking(ren, iren)
        pass

    def OnMouseMove(self, x, y, ren, iren):
        if not self._picking_active:
            return

        if not ren:
            return

        self.renderer = ren
        self.iren = iren

        pos = iren.GetEventPosition()

        self._end_position[0] = pos[0]
        self._end_position[1] = pos[1]
        self.ren_win_size = self.ren_win.GetSize()

        size = self.ren_win_size

        if self._end_position[0] > size[0] - 1:
            self._end_position[0] = size[0] - 1

        if self._end_position[0] < 0:
            self._end_position[0] = 0

        if self._end_position[1] > size[1] - 1:
            self._end_position[1] = size[1] - 1

        if self._end_position[1] < 0:
            self._end_position[1] = 0

        self._redraw_picking_box(iren)

    def PrintSelf(self):
        super(self, PolyPicker).PrintSelf()
        print("Center: %f, %f, %f" % (self.Center[0], self.Center[1], self.Center[2]))

    def finalize(self):
        self.vtk_graphics = None
        self.picking_manager = None
Пример #11
0
class EmptyTable(QtWidgets.QTableView):
    def __init__(self, *args, **kwargs):
        super().__init__(*args)

        self._scroll_factor = 1.
        self._enter_down = True

        self.undo = MrSignal()
        self.redo = MrSignal()

    def setModel(self, model):
        from ..table_data import TableDataModel
        assert isinstance(model, TableDataModel)
        super().setModel(model)

    def keyPressEvent(self, event):
        super().keyPressEvent(event)

        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = True

        elif event.key() == QtCore.Qt.Key_Tab:
            event.accept()

        if event.matches(QtGui.QKeySequence.Copy):
            self._copy()
            event.accept()

        elif event.matches(QtGui.QKeySequence.Paste):
            paste_data = str(QtWidgets.QApplication.clipboard().text())
            self.model().set_data_range(self.selection_range(), paste_data)
            event.accept()

        elif event.matches(QtGui.QKeySequence.Undo):
            event.accept()
            self.undo.emit()

        elif event.matches(QtGui.QKeySequence.Redo):
            event.accept()
            self.redo.emit()

    def keyReleaseEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = False
        super().keyReleaseEvent(event)

    def wheelEvent(self, event):
        if not QtWidgets.QApplication.keyboardModifiers(
        ) & QtCore.Qt.ControlModifier:
            return super().wheelEvent(event)

        font = self.font()

        new_size = old_size = font.pointSize()

        if event.angleDelta().y() > 0:
            new_size += 1
        else:
            new_size -= 1

        if new_size == 0:
            new_size = old_size

        self._scroll_factor = new_size / old_size

        font.setPointSize(new_size)

        self.setFont(font)
        self.horizontalHeader().setFont(font)
        self.verticalHeader().setFont(font)

        self.resizeRowsToContents()
        self.resizeColumnsToContents()

        self._scroll_factor = 1.

    def resizeRowsToContents(self):
        header = self.verticalHeader()

        for i in range(self.model().rowCount()):
            header.resizeSection(i, self.rowHeight(i) * self._scroll_factor)

    def resizeColumnsToContents(self):
        header = self.horizontalHeader()

        for i in range(self.model().columnCount()):
            header.resizeSection(i, self.columnWidth(i) * self._scroll_factor)

    def set_selection(self, selections):
        try:
            QtWidgets.QApplication.instance().focusWidget().clearFocus()
        except AttributeError:
            pass

        selection_model = self.selectionModel()

        selection_model.clearSelection()

        first_index = None

        model = self.model()

        for i in range(len(selections)):
            selection = selections[i]
            index = model.index(selection[0], selection[1])
            selection_model.select(index, QtCore.QItemSelectionModel.Select)

            if first_index is None:
                first_index = index

        self.setFocus()

        return first_index

    def set_selection_and_index(self, selections):
        self.setCurrentIndex(self.set_selection(selections))

    def select_last_row(self):
        data_len = self.model().rowCount()
        self.set_selection_and_index([[data_len - 1, 0]])

    def select_and_edit(self, row, column):
        index = self.model().index(row, column)

        selection_model = self.selectionModel()

        selection_model.clear()
        selection_model.select(index, QtCore.QItemSelectionModel.Select)

        self.edit(index)

    def selection_range(self):
        selection = self.selectionModel().selectedIndexes()

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

        return [(min_row, min_col), (max_row, max_col)]

    def selection(self):
        selection = self.selectionModel().selectedIndexes()

        tmp = []

        for index in selection:
            row = index.row()
            col = index.column()

            tmp.append((row, col))

        return sorted(tmp, key=itemgetter(0))

    def update_all(self):
        try:
            self.model().update_all()
        except AttributeError:
            pass

    def current_index(self):
        index = self.currentIndex()
        return index.row(), index.column()

    def _copy(self):
        model = self.model()
        selection = self.selectionModel().selectedIndexes()

        edit_role = QtCore.Qt.EditRole

        try:
            row1 = selection[0].row()
            col1 = selection[0].column()
        except IndexError:
            return

        copy_data = []

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

            data = str(model.data(index, edit_role))

            copy_data.append([row, col, data])

        rows = max_row - min_row + 1
        columns = max_col - min_col + 1

        if rows == 0 or columns == 0:
            return

        np_data = np.zeros((rows, columns), dtype=object)

        for tmp in copy_data:
            row, col, data = tmp

            row -= min_row
            col -= min_col

            np_data[row, col] = data

        text = []

        for i in range(np_data.shape[0]):
            _text = []
            for j in range(np_data.shape[1]):
                _text.append(np_data[i, j])
            text.append('\t'.join(_text))

        text = '\n'.join(text)

        # noinspection PyArgumentList
        clipboard = QtWidgets.QApplication.clipboard()
        """:type: QtGui.QClipboard"""

        clipboard.setText(text)
Пример #12
0
class DataTable(QtWidgets.QTableView):

    row_changed = QtCore.Signal(int)
    column_changed = QtCore.Signal(int)
    selection_changed = QtCore.Signal(int, int)

    @classmethod
    def wrap_obj(cls, obj=None, *args, **kwargs):
        """

        :rtype: DataTable
        """

        if obj is None:
            obj = DataTable(*args, **kwargs)
            return obj

        elif isinstance(obj, DataTable):
            return obj

        assert isinstance(obj, QtWidgets.QTableView)

        #parent = obj.parent()

        obj.__class__ = DataTable
        DataTable.init(obj)

        return obj

    def __init__(self, *args):
        super(DataTable, self).__init__(*args)

        self.table_model = None
        """:type: TableModel"""

        self.selection_model = None
        """:type: QtGui.QItemSelectionModel"""
        #self.selection_model.selectionChanged.connect(self._selection_changed)

        self._old_row = -1
        self._old_column = -1

        self._enter_down = False

        self.data_changed = None
        """:type: MrSignal"""

        self.copy = None
        """:type: MrSignal"""

        self.paste = None
        """:type: MrSignal"""

        self.set_data_signal = None
        """:type: MrSignal"""

        self.row_changed = None
        """:type: MrSignal"""

        self.column_changed = None
        """:type: MrSignal"""

        self.selection_changed = None
        """:type: MrSignal"""

        self.undo = None
        """:type: MrSignal"""

        self.redo = None
        """:type: MrSignal"""

        self.init()

    def init(self):
        self.table_model = TableModel(self)
        self.setModel(self.table_model)

        self.selection_model = self.selectionModel()
        """:type: QtGui.QItemSelectionModel"""
        self.selection_model.selectionChanged.connect(self._selection_changed)

        self._old_row = -1
        self._old_column = -1

        self._enter_down = False

        self.data_changed = self.table_model.data_changed

        self.data_changed.connect(self._data_changed)

        self.copy = MrSignal()
        self.paste = MrSignal()

        self.row_changed = MrSignal()
        self.column_changed = MrSignal()
        self.selection_changed = MrSignal()

        self.undo = MrSignal()
        self.redo = MrSignal()

        self.set_data_signal = self.table_model.set_data_signal

        #self.table_model.dataChanged.connect(self._data_updated)

    def _data_changed(self, row, column):
        if self._enter_down:
            row += 1
            column = column

            if row >= self.table_model.rowCount():
                row -= 1

            self.set_selection([[row, column]])

    # def set_selection(self, selections):
    #     try:
    #         QtWidgets.QApplication.instance().focusWidget().clearFocus()
    #     except AttributeError:
    #         pass
    #
    #     self.selection_model.clearSelection()
    #
    #     first_index = None
    #
    #     for i in range(len(selections)):
    #         selection = selections[i]
    #         index = self.table_model.index(selection[0], selection[1])
    #         self.selection_model.select(index, QtCore.QItemSelectionModel.Select)
    #
    #         if first_index is None:
    #             first_index = index
    #
    #     self.setCurrentIndex(first_index)
    #     #self.setFocus(True)
    #     self.setFocus()

    def set_selection(self, selections):
        try:
            QtWidgets.QApplication.instance().focusWidget().clearFocus()
        except AttributeError:
            pass

        self.selection_model.clearSelection()

        first_index = None

        for i in range(len(selections)):
            selection = selections[i]
            index = self.table_model.index(selection[0], selection[1])
            self.selection_model.select(index,
                                        QtCore.QItemSelectionModel.Select)

            if first_index is None:
                first_index = index

        #self.setCurrentIndex(first_index)
        self.setFocus(True)
        # self.setFocus()

    def set_selection_and_index(self, selections):
        try:
            QtWidgets.QApplication.instance().focusWidget().clearFocus()
        except AttributeError:
            pass

        self.selection_model.clearSelection()

        first_index = None

        for i in range(len(selections)):
            selection = selections[i]
            index = self.table_model.index(selection[0], selection[1])
            self.selection_model.select(index,
                                        QtCore.QItemSelectionModel.Select)

            if first_index is None:
                first_index = index

        self.setCurrentIndex(first_index)
        self.setFocus(True)
        # self.setFocus()

    def selection(self):
        selection = self.selectionModel().selectedIndexes()

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

        return [(min_row, min_col), (max_row, max_col)]

    def keyPressEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = True

        elif event.matches(QtGui.QKeySequence.Copy):
            self._copy()

        elif event.matches(QtGui.QKeySequence.Paste):
            paste_data = str(QtWidgets.QApplication.clipboard().text())
            self.paste.emit(self.selection(), paste_data)

        elif event.matches(QtGui.QKeySequence.Undo):
            self.undo.emit()

        elif event.matches(QtGui.QKeySequence.Redo):
            self.redo.emit()

        else:
            super(DataTable, self).keyPressEvent(event)

    def keyReleaseEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = False

        super(DataTable, self).keyReleaseEvent(event)

    def setup_data(self, headers, data):
        self.table_model.setup_data(headers, data)

    def set_headers(self, headers):
        self.table_model.set_headers(headers)

    def sizeHint(self):
        return QtCore.QSize(800, 500)

    def update_all(self):
        self.table_model.update_all()

    def current_row(self):
        return self._old_row

    def current_column(self):
        return self._old_column

    def set_editable_columns(self, int_set):
        self.table_model.set_editable_columns(int_set)

    def _selection_changed(self, current, previous):
        """
        :type current: QtGui.QItemSelection
        :type previous:QtGui.QItemSelection
        """

        try:
            first_index = current.indexes()[0]
        except IndexError:
            return

        new_row = first_index.row()
        new_column = first_index.column()

        old_row = self._old_row
        old_column = self._old_column

        selection_changed = False

        if new_row != old_row:
            self._old_row = new_row
            self.row_changed.emit(self._old_row)
            selection_changed = True

        if new_column != old_column:
            self._old_column = new_column
            self.column_changed.emit(self._old_column)
            selection_changed = True

        if selection_changed:
            self.selection_changed.emit(new_row, new_column)

    def select_last_row(self):
        data_len = len(self.table_model._data)

        self.set_selection([[data_len - 1, 0]])

    def select_and_edit(self, row, column):
        index = self.table_model.index(row, column)
        self.selectionModel().clear()
        self.selectionModel().select(index, QtCore.QItemSelectionModel.Select)
        self.edit(index)

    def _copy(self):
        model = self.model()
        selection = self.selectionModel().selectedIndexes()

        edit_role = QtCore.Qt.EditRole

        try:
            row1 = selection[0].row()
            col1 = selection[0].column()
        except IndexError:
            return

        copy_data = []

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

            data = str(model.data(index, edit_role))

            copy_data.append([row, col, data])

        rows = max_row - min_row + 1
        columns = max_col - min_col + 1

        if rows == 0 or columns == 0:
            return

        np_data = np.zeros((rows, columns), dtype=object)

        for tmp in copy_data:
            row, col, data = tmp

            row -= min_row
            col -= min_col

            np_data[row, col] = data

        text = []

        for i in range(np_data.shape[0]):
            _text = []
            for j in range(np_data.shape[1]):
                _text.append(np_data[i, j])
            text.append('\t'.join(_text))

        text = '\n'.join(text)

        # noinspection PyArgumentList
        clipboard = QtWidgets.QApplication.clipboard()
        """:type: QtGui.QClipboard"""

        clipboard.setText(text)
Пример #13
0
class TableModel(QtCore.QAbstractTableModel):
    def __init__(self, *args):
        super(TableModel, self).__init__(*args)
        self.headers = None
        self._data = None
        self._get_data = None
        self._set_data = None

        self.editable_columns = set()

        self.data_changed = MrSignal()

        self.set_data_signal = MrSignal()

    def set_headers(self, headers):
        self.headers = headers
        self.update_all()

    def setup_data(self, headers, data):

        if not isinstance(headers, (list, tuple)):
            headers = [headers]

        self.headers = headers
        self._data = data
        self._get_data = self._data.get_data
        self._set_data = self._data.set_data

        if headers is None or data is None:
            return

        self.update_all()

    def set_data(self, data):
        self._data = data
        self._get_data = self._data.get_data
        self._set_data = self._data.set_data

        if data is None:
            return

        self.update_all()

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
        if self.headers is not None and role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self.headers[section]
            else:
                return section + 1

        return None

    def rowCount(self, index=QtCore.QModelIndex()):
        if self._data is None:
            return 0

        return len(self._data)

    def columnCount(self, index=QtCore.QModelIndex()):
        if self.headers is None:
            return 0

        return len(self.headers)

    def set_editable_columns(self, int_set):
        self.editable_columns = int_set

    def flags(self, index):
        if int(index.column()) in self.editable_columns:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
        else:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if self._data is None or self.headers is None:
            return None

        if role == QtCore.Qt.EditRole:
            row = index.row()
            col = index.column()

            data = self._get_data((row, col))

            if data is None:
                return ''

            return str(data)

        elif role == QtCore.Qt.DisplayRole:
            row = index.row()
            col = index.column()

            data = self._get_data((row, col))

            if data is None:
                return ''

            if isinstance(data, list) and len(data) > 0 and isinstance(
                    data[0], float):
                return str([round(i, 6) for i in data])

            return str(data)

    def setData(self, index, value, role=QtCore.Qt.DisplayRole):
        if self._data is None or self.headers is None:
            return

        row = index.row()
        col = index.column()

        self.set_data_signal.emit((row, col), str(value), role)

        return self.set_data_signal.results[0]

    def update_all(self):
        self.layoutChanged.emit()
        top_left = self.index(0, 0)
        bot_right = self.index(self.rowCount() - 1, self.columnCount() - 1)
        self.dataChanged.emit(top_left, bot_right)
Пример #14
0
class AbstractTableView(QtWidgets.QTableView):
    
    TableModel = AbstractTableModel
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args)

        self._scroll_factor = 1.
        self._enter_down = False
        self._shift_down = False
        self._ctrl_down = False

        self.undo = MrSignal()
        self.redo = MrSignal()
        
        self._model = self.TableModel()
        self.setModel(self._model)

        self.selection_model = self.selectionModel()
        """:type: QtGui.QItemSelectionModel"""
        self.selection_model.selectionChanged.connect(self._selection_changed)

        self.selection_changed = MrSignal()
        self.row_changed = MrSignal()
        self.column_changed = MrSignal()

        self._old_row = -1
        self._old_column = -1

    def _select_next_row_down(self):
        row, col = self.current_index()

        if row < self.model().rowCount() - 1:
            row += 1

        self.set_selection_and_index([[row, col]])

    def _select_next_row_up(self):
        row, col = self.current_index()

        if row > 0:
            row -= 1

        self.set_selection_and_index([[row, col]])

    def keyPressEvent(self, event):
        super().keyPressEvent(event)

        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = True

            if self._ctrl_down is False:
                if self._shift_down is True:
                    self._select_next_row_up()
                else:
                    self._select_next_row_down()

        elif event.key() == QtCore.Qt.Key_Shift:
            self._shift_down = True

        elif event.key() == QtCore.Qt.Key_Control:
            self._ctrl_down = True

        elif event.key() == QtCore.Qt.Key_Tab:
            event.accept()

        if event.matches(QtGui.QKeySequence.Copy):
            self._copy()
            event.accept()

        elif event.matches(QtGui.QKeySequence.Paste):
            
            selection_range = self.selection_range()
            
            paste_data = str(QtWidgets.QApplication.clipboard().text())
            paste_data = _get_paste_data(selection_range, paste_data, 
                                         (self.model().rowCount(), self.model().columnCount())
                                         )
            
            if paste_data is not None:
                self.model().set_data_range(selection_range[0], paste_data)
                top_left = selection_range[0]
                bot_right = selection_range[0][0] + len(paste_data) - 1, selection_range[0][1] + len(paste_data[0]) - 1
                self.set_selection_range(top_left, bot_right)
                event.accept()

        elif event.matches(QtGui.QKeySequence.Undo):
            event.accept()
            self.undo.emit()

        elif event.matches(QtGui.QKeySequence.Redo):
            event.accept()
            self.redo.emit()

    def keyReleaseEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = False

        elif event.key() == QtCore.Qt.Key_Shift:
            self._shift_down = False

        elif event.key() == QtCore.Qt.Key_Control:
            self._ctrl_down = False

        super().keyReleaseEvent(event)

    def wheelEvent(self, event):
        if not QtWidgets.QApplication.keyboardModifiers() & QtCore.Qt.ControlModifier:
            return super().wheelEvent(event)

        font = self.font()

        new_size = old_size = font.pointSize()

        if event.angleDelta().y() > 0:
            new_size += 1
        else:
            new_size -= 1

        if new_size == 0:
            new_size = old_size

        self._scroll_factor = new_size / old_size

        font.setPointSize(new_size)

        self.setFont(font)
        self.horizontalHeader().setFont(font)
        self.verticalHeader().setFont(font)

        self.resizeRowsToContents()
        self.resizeColumnsToContents()

        self._scroll_factor = 1.

    def resizeRowsToContents(self):
        header = self.verticalHeader()

        for i in range(self.model().rowCount()):
            header.resizeSection(i, self.rowHeight(i) * self._scroll_factor)

    def resizeColumnsToContents(self):
        header = self.horizontalHeader()

        for i in range(self.model().columnCount()):
            header.resizeSection(i, self.columnWidth(i) * self._scroll_factor)

    def set_selection(self, selections):
        try:
            QtWidgets.QApplication.instance().focusWidget().clearFocus()
        except AttributeError:
            pass

        selection_model = self.selectionModel()

        selection_model.clearSelection()

        first_index = None

        model = self.model()

        for i in range(len(selections)):
            selection = selections[i]
            index = model.index(selection[0], selection[1])
            selection_model.select(index, QtCore.QItemSelectionModel.Select)

            if first_index is None:
                first_index = index

        self.setFocus()

        return first_index

    def set_selection_range(self, top_left, bot_right):

        selections = []

        rows = bot_right[0] - top_left[0] + 1
        cols = bot_right[1] - top_left[1] + 1

        i_, j_ = top_left

        for i in range(rows):
            for j in range(cols):
                selections.append((i_ + i, j_ + j))

        self.set_selection(selections)

    def set_selection_and_index(self, selections):
        self.setCurrentIndex(self.set_selection(selections))

    def select_last_row(self):
        data_len = self.model().rowCount()
        self.set_selection_and_index([[data_len - 1, 0]])

    def select_and_edit(self, row, column):
        index = self.model().index(row, column)

        selection_model = self.selectionModel()

        selection_model.clear()
        selection_model.select(index, QtCore.QItemSelectionModel.Select)

        self.edit(index)

    def selection_range(self):
        selection = self.selectionModel().selectedIndexes()

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

        return [(min_row, min_col), (max_row, max_col)]

    def selection(self):
        selection = self.selectionModel().selectedIndexes()

        tmp = []

        for index in selection:
            row = index.row()
            col = index.column()

            tmp.append((row, col))

        return list(sorted(tmp, key=itemgetter(0)))

    def update_all(self):
        self.model().update_all()

    def current_index(self):
        index = self.currentIndex()
        return index.row(), index.column()

    def _copy(self):
        model = self.model()
        selection = self.selectionModel().selectedIndexes()

        edit_role = QtCore.Qt.EditRole

        try:
            row1 = selection[0].row()
            col1 = selection[0].column()
        except IndexError:
            return

        copy_data = []

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

            data = str(model.data(index, edit_role))

            copy_data.append([row, col, data])

        rows = max_row - min_row + 1
        columns = max_col - min_col + 1

        if rows == 0 or columns == 0:
            return

        np_data = np.zeros((rows, columns), dtype=object)

        for tmp in copy_data:
            row, col, data = tmp

            row -= min_row
            col -= min_col

            np_data[row, col] = data

        text = []

        for i in range(np_data.shape[0]):
            _text = []
            for j in range(np_data.shape[1]):
                _text.append(np_data[i, j])
            text.append('\t'.join(_text))

        text = '\n'.join(text)

        # noinspection PyArgumentList
        clipboard = QtWidgets.QApplication.clipboard()
        """:type: QtGui.QClipboard"""

        clipboard.setText(text)
    
    def set_model_data(self, data, update_all=True):
        self._model.set_model_data(data, update_all)

    def _selection_changed(self, current, previous):
        """
        :type current: QtGui.QItemSelection
        :type previous: QtGui.QItemSelection
        """

        try:
            first_index = current.indexes()[0]
        except IndexError:
            return

        new_row = first_index.row()
        new_column = first_index.column()

        old_row = self._old_row
        old_column = self._old_column

        selection_changed = False

        if new_row != old_row:
            self._old_row = new_row
            self.row_changed.emit(self._old_row)
            selection_changed = True

        if new_column != old_column:
            self._old_column = new_column
            self.column_changed.emit(self._old_column)
            selection_changed = True

        if selection_changed:
            self.selection_changed.emit((new_row, new_column))
Пример #15
0
class HoveredInteractorStyle(vtkCameraManipulator):
    def __init__(self):
        vtkCameraManipulator.__init__(self)

        self.cell_picker = CellPicker()

        self.hovered_data = None
        self.visible_filter = None
        self.pickable_types = None

        self.picked_id = -1

        self.vtk_graphics = VTKGraphics.instance()

        self.key_down = MrSignal()

    def visible_only(self):
        self.cell_picker.toggle_visible()

    def set_hovered_data(self, hovered_data):
        self.hovered_data = hovered_data

    def set_visible_filter(self, visible_filter):
        self.visible_filter = visible_filter
        self.cell_picker.SetInputConnection(
            self.visible_filter.GetOutputPort())

    def set_pickable_types(self, pickable_types):
        self.pickable_types = pickable_types
        self.cell_picker.SetActiveData(self.pickable_types.raw_pointer(),
                                       'card_types')

    def OnMouseMove(self, x, y, ren, iren):
        self.cell_picker.Pick(x, y, 0, ren)

        picked_id = self.cell_picker.GetClosestCellGlobalId()

        if self.picked_id != picked_id:
            self.picked_id = picked_id
            if picked_id > 0:
                self.hovered_data.set_data(picked_id)
            else:
                self.hovered_data.set_data([])

            self.vtk_graphics.hovered_filter.Modified()
            self.vtk_graphics.render()

    def OnKeyDown(self, iren):
        super(HoveredInteractorStyle, self).OnKeyDown(iren)
        self.key_down.emit(self.KeyCode)

    def unload(self):
        self.hovered_data.set_data([])

    def finalize(self):
        self.cell_picker.finalize()
        self.cell_picker = None
        self.hovered_data = None
        self.visible_filter = None
        self.pickable_types = None

        self.vtk_graphics = None
Пример #16
0
class MultiTable(QtWidgets.QWidget):

    MainData_1 = TableDataList
    MainData_2 = TableDataList

    main_data_1 = None
    main_data_2 = None

    def __init__(self, parent=None, dispatcher_id=None, id_1='Table1', id_2='Table2'):
        super(MultiTable, self).__init__(parent)

        class _Table1(BasicTable):
            MainData = self.MainData_1
            main_data = self.main_data_1

        class _Table2(BasicTable):
            MainData = self.MainData_2
            main_data = self.main_data_2

        self.table_1 = _Table1(self)
        self.table_1.dispatcher.dispatcher_id = id_1

        self.table_2 = _Table2(self)
        self.table_2.dispatcher.dispatcher_id = id_2

        self._splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        self._splitter.addWidget(self.table_1)
        self._splitter.addWidget(self.table_2)

        self._layout = QtWidgets.QHBoxLayout(self)
        self.setLayout(self._layout)

        self._layout.addWidget(self._splitter)

        self.table_1.table_1.row_changed.connect(self._row_changed)

        self.dispatcher = _CommandDispatcher(self)
        self.dispatcher.dispatcher_id = dispatcher_id

        self.dispatcher.add_child(self.table_1.dispatcher)
        self.dispatcher.add_child(self.table_2.dispatcher)

        self.request_focus = MrSignal()

        self.data = {}
        """:type: dict[str, TableDataList]"""

    def _row_changed(self, row):
        try:
            data_id = self.table_1.main_data[row].id
        except IndexError:
            return

        if data_id == '':
            return

        try:
            data = self.data[data_id]
        except KeyError:
            data = self.data[data_id] = self.MainData_2()

        self.table_2.set_main_data(data)

    def current_data_id(self):
        try:
            return self.table_1.main_data[self.table_1.table_1.current_index()[0]].id
        except IndexError:
            return None

    def get_data(self, data_id):
        # debuginfo(self.data)
        return self.data.get(data_id, None)

    # @show_stack_trace
    def activate(self, data_id):

        # debuginfo('activate', 1)

        ids = self.table_1.main_data.ids()

        # debuginfo('activate', 2)

        try:
            index = ids.index(data_id)
        except ValueError:
            return

        # debuginfo('activate', 3)

        # debuginfo('MultiTable set selection and index')

        self.table_1.table_1.set_selection_and_index([[index, 0]])

        # debuginfo('activate', 4)

        self.request_focus.emit()

    def update_all(self):
        self.table_1.update_all()
        self.table_2.update_all()
Пример #17
0
class FemGroupList(object):
    def __init__(self):
        self.groups = OrderedDict()
        """:type: OrderedDict[FemGroup]"""

        self.data_changed = MrSignal()

        self._all_groups = FemGroup()

        self._default_group = FemGroup()
        self._default_group.group_name = 'Default'
        self._default_group.data_changed.connect(self._data_changed)

        self.groups['Default'] = self._default_group

    def _data_changed(self):
        self.all_groups()
        self.data_changed.emit()

    def add_group(self, name):
        if name == 'Default':
            self.groups['Default'] = self._default_group
            return self._default_group

        if name in self.groups:
            new_name = self.new_name()
            name = new_name.replace('group', name)

        new_group = FemGroup()
        new_group.data_changed.connect(self._data_changed)

        self.groups[name] = new_group
        new_group.group_name = name

        return new_group

    def remove_group(self, name):
        if name == 'Default':
            return

        try:
            old_group = self.groups[name]
            old_group.data_changed.disconnect(self._data_changed)
            del self.groups[name]
        except KeyError:
            pass

    def get_group(self, name):
        return self.groups[name]

    def get_group_by_index(self, index):
        group_name = list(self.groups.keys())[index]
        return self.groups[group_name]

    def rename_group(self, old_name, new_name):
        if old_name == 'Default':
            return

        if old_name not in self.groups:
            return

        group_names = list(self.groups.keys())

        tmp = dict(self.groups)

        self.groups.clear()

        for group_name in group_names:
            group = tmp[group_name]

            if group_name == old_name:
                group_name = new_name
                group.group_name = group_name

            self.groups[group_name] = group

        self.data_changed.emit()

    def set_active(self, group_name, bool):
        if group_name not in self.groups:
            return

        self.groups[group_name].set_active(bool)

    def show_group(self, name):
        try:
            self.groups[name].set_active(True)
        except KeyError:
            pass

    def hide_group(self, name):
        try:
            self.groups[name].set_active(False)
        except KeyError:
            pass

    def all_groups(self):

        data = self._all_groups

        data.data_changed.block()

        data.set_data([])

        add_data = data.data.add_data4

        for id, group in iteritems(self.groups):
            if group.is_active:
                add_data(group.data)

        data.data_changed.unblock()

        return data

    def size(self):
        return len(self.groups)

    def new_name(self):
        size = self.size()

        new_name_ = 'group_%d' % size

        while new_name_ in self.groups:
            size += 1
            new_name_ = 'group_%d' % size

        return new_name_

    def serialize(self):
        data = []

        for key, item in iteritems(self.groups):
            data.append((key, item.to_str()))

        return data

    def clear(self):
        self.groups.clear()

    def load(self, data):
        if not isinstance(data, list):
            return

        self.clear()

        for data_ in data:
            group_name, group_data = data_
            group = self.add_group(group_name)
            group.set_data(group_data)
Пример #18
0
class EmptyTable(QtWidgets.QWidget):
    def __init__(self, parent=None, *args):
        super(EmptyTable, self).__init__(parent, *args)

        self.setLayout(QtWidgets.QVBoxLayout())

        #### buttons ####

        self.pushButton_add = QtWidgets.QPushButton('Add', self)
        self.pushButton_insert = QtWidgets.QPushButton('Insert', self)
        self.pushButton_delete = QtWidgets.QPushButton('Delete', self)

        self.button_spacer = QtWidgets.QSpacerItem(
            100, 10, QtWidgets.QSizePolicy.Expanding,
            QtWidgets.QSizePolicy.Minimum)

        self.button_layout = QtWidgets.QHBoxLayout()

        self.button_layout.addWidget(self.pushButton_add)
        self.button_layout.addWidget(self.pushButton_insert)
        self.button_layout.addWidget(self.pushButton_delete)

        self.button_layout.addItem(self.button_spacer)

        #### table_2 ####

        self.table = QtWidgets.QTableView(self)
        self.table.wheelEvent = self._wheel_event
        self.table.resizeRowsToContents = self._resize_rows
        self.table.resizeColumnsToContents = self._resize_columns
        # self.table_2.setModel(QtCore.QAbstractTableModel())

        #### bottom buttons ####

        self.pushButton_up = QtWidgets.QPushButton('^', self)
        self.pushButton_down = QtWidgets.QPushButton('v', self)

        self.lineEdit_rows = QtWidgets.QLineEdit(self)
        self.lineEdit_rows.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit_rows.setCursor(QtCore.Qt.ArrowCursor)
        self.lineEdit_rows.setMaximumWidth(50)

        self.lineEdit_rows.editingFinished.connect(self._set_rows)
        self.lineEdit_rows.mousePressEvent = self._rows_mouse_press

        self.lineEdit_rows.setStyleSheet("""
            QLineEdit::hover{
            background-color: Lightcyan
            }
            """)

        self.bottom_spacer = QtWidgets.QSpacerItem(
            100, 10, QtWidgets.QSizePolicy.Expanding,
            QtWidgets.QSizePolicy.Minimum)

        self.bottom_layout = QtWidgets.QHBoxLayout()

        self.bottom_layout.addWidget(self.pushButton_up)
        self.bottom_layout.addWidget(self.pushButton_down)
        self.bottom_layout.addItem(self.bottom_spacer)
        self.bottom_layout.addWidget(self.lineEdit_rows)

        #### add to layout ####

        self.layout().addItem(self.button_layout)
        self.layout().addWidget(self.table)
        self.layout().addItem(self.bottom_layout)

        # self.table_2.selectionModel().selectionChanged.connect(self._selection_changed)

        self._old_row = -1
        self._old_column = -1

        self._enter_down = False

        self.selection_changed = MrSignal()
        self.row_changed = MrSignal()
        self.column_changed = MrSignal()

        self.undo = MrSignal()
        self.redo = MrSignal()
        self.paste = MrSignal()
        self.set_data = MrSignal()
        self.set_rows = MrSignal()
        self.data_changed = MrSignal()

        self.table.keyPressEvent = self._keyPressEvent
        self.table.keyReleaseEvent = self._keyReleaseEvent
        # self.table.mousePressEvent = self._mousePressEvent

        self._scroll_factor = 1.

    def _wheel_event(self, event):

        if not QtWidgets.QApplication.keyboardModifiers(
        ) & QtCore.Qt.ControlModifier:
            return QtWidgets.QTableView.wheelEvent(self.table, event)

        font = self.table.font()

        new_size = old_size = font.pointSize()

        if event.angleDelta().y() > 0:
            new_size += 1
        else:
            new_size -= 1

        if new_size == 0:
            new_size = old_size

        self._scroll_factor = new_size / old_size

        font.setPointSize(new_size)

        self.table.setFont(font)
        self.table.horizontalHeader().setFont(font)
        self.table.verticalHeader().setFont(font)

        self._resize_rows()
        self._resize_columns()

        self._scroll_factor = 1.

        # return QtWidgets.QTableView.wheelEvent(self.table, event)

    def _resize_rows(self):
        header = self.table.verticalHeader()

        for i in range(self.table.model().rowCount()):
            header.resizeSection(i,
                                 self.table.rowHeight(i) * self._scroll_factor)

    def _resize_columns(self):
        header = self.table.horizontalHeader()

        for i in range(self.table.model().columnCount()):
            header.resizeSection(
                i,
                self.table.columnWidth(i) * self._scroll_factor)

    def _rows_mouse_press(self, event):
        event.accept()
        self.lineEdit_rows.selectAll()

    def _set_rows(self, *args):
        try:
            rows = int(self.lineEdit_rows.text())
        except (ValueError, TypeError):
            rows = -1

        self.lineEdit_rows.clearFocus()
        self.set_rows.emit(rows)

    def hide_buttons(self):
        self.pushButton_add.hide()
        self.pushButton_insert.hide()
        self.pushButton_delete.hide()
        self.pushButton_up.hide()
        self.pushButton_down.hide()
        self.lineEdit_rows.hide()

    def show_buttons(self):
        self.pushButton_add.show()
        self.pushButton_insert.show()
        self.pushButton_delete.show()
        self.pushButton_up.show()
        self.pushButton_down.show()
        self.lineEdit_rows.show()

    def set_model(self, model):
        self.table.setModel(model)
        self.table.selectionModel().selectionChanged.connect(
            self._selection_changed)
        self.table.model().set_data.connect(self._set_data)

        self.table.model().dataChanged.connect(self._data_changed)

    def _data_changed(self, *args):
        self.data_changed.emit()

    def _set_data(self, *args):
        self.set_data.emit(self._enter_down, *args)

    def set_selection(self, selections):
        try:
            QtWidgets.QApplication.instance().focusWidget().clearFocus()
        except AttributeError:
            pass

        selection_model = self.table.selectionModel()

        selection_model.clearSelection()

        first_index = None

        model = self.table.model()

        for i in range(len(selections)):
            selection = selections[i]
            index = model.index(selection[0], selection[1])
            selection_model.select(index, QtCore.QItemSelectionModel.Select)

            if first_index is None:
                first_index = index

        self.table.setFocus()

        return first_index

    def set_selection_and_index(self, selections):
        self.table.setCurrentIndex(self.set_selection(selections))

    def select_last_row(self):
        data_len = self.table.model().rowCount()

        self.set_selection_and_index([[data_len - 1, 0]])

    def select_and_edit(self, row, column):
        index = self.table.model().index(row, column)

        selection_model = self.table.selectionModel()

        selection_model.clear()
        selection_model.select(index, QtCore.QItemSelectionModel.Select)
        self.edit(index)

    def selection_range(self):
        selection = self.table.selectionModel().selectedIndexes()

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

        return [(min_row, min_col), (max_row, max_col)]

    def selection(self):
        selection = self.table.selectionModel().selectedIndexes()

        tmp = []

        for index in selection:
            row = index.row()
            col = index.column()

            tmp.append((row, col))

        return sorted(tmp, key=itemgetter(0))

    def update_all(self):
        try:
            self.table.model().update_all()
        except AttributeError:
            pass

    def _selection_changed(self, current, previous):
        """
        :type current: QtGui.QItemSelection
        :type previous:QtGui.QItemSelection
        """

        try:
            first_index = current.indexes()[0]
        except IndexError:
            return

        new_row = first_index.row()
        new_column = first_index.column()

        old_row = self._old_row
        old_column = self._old_column

        selection_changed = False

        if new_row != old_row:
            self._old_row = new_row
            self.row_changed.emit(self._old_row)
            selection_changed = True

        if new_column != old_column:
            self._old_column = new_column
            self.column_changed.emit(self._old_column)
            selection_changed = True

        if selection_changed:
            self.selection_changed.emit((new_row, new_column))

    def _keyPressEvent(self, event):
        QtWidgets.QTableView.keyPressEvent(self.table, event)

        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = True
            # event.accept()

        elif event.key() == QtCore.Qt.Key_Tab:
            event.accept()

        if event.matches(QtGui.QKeySequence.Copy):
            self._copy()
            event.accept()

        elif event.matches(QtGui.QKeySequence.Paste):
            paste_data = str(QtWidgets.QApplication.clipboard().text())
            self.paste.emit(self.selection_range(), paste_data)
            event.accept()

        elif event.matches(QtGui.QKeySequence.Undo):
            event.accept()
            self.undo.emit()

        elif event.matches(QtGui.QKeySequence.Redo):
            event.accept()
            self.redo.emit()

    def _keyReleaseEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = False

        QtWidgets.QTableView.keyReleaseEvent(self.table, event)

    def mousePressEvent(self, event):
        self.lineEdit_rows.clearFocus()
        QtWidgets.QWidget.mousePressEvent(self, event)

    def current_index(self):
        index = self.table.currentIndex()
        return index.row(), index.column()

    def _copy(self):
        model = self.table.model()
        selection = self.table.selectionModel().selectedIndexes()

        edit_role = QtCore.Qt.EditRole

        try:
            row1 = selection[0].row()
            col1 = selection[0].column()
        except IndexError:
            return

        copy_data = []

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

            data = str(model.data(index, edit_role))

            copy_data.append([row, col, data])

        rows = max_row - min_row + 1
        columns = max_col - min_col + 1

        if rows == 0 or columns == 0:
            return

        np_data = np.zeros((rows, columns), dtype=object)

        for tmp in copy_data:
            row, col, data = tmp

            row -= min_row
            col -= min_col

            np_data[row, col] = data

        text = []

        for i in range(np_data.shape[0]):
            _text = []
            for j in range(np_data.shape[1]):
                _text.append(np_data[i, j])
            text.append('\t'.join(_text))

        text = '\n'.join(text)

        # noinspection PyArgumentList
        clipboard = QtWidgets.QApplication.clipboard()
        """:type: QtGui.QClipboard"""

        clipboard.setText(text)

    def row_count(self):
        return self.table.model().rowCount()
Пример #19
0
class BoxPicker(vtkCameraManipulator):
    def __init__(self):
        vtkCameraManipulator.__init__(self)

        self.picked_data = None
        self.box_picker = vtk.vtkExtractSelectedFrustum()
        self._start_position = [0, 0]
        self._end_position = [0, 0]
        self._pixel_array = vtk.vtkUnsignedCharArray()

        self.ex = vtk.vtkExtractSelection()
        self.selection_node = vtk.vtkSelectionNode()
        self.selection_node.SetContentType(vtk.vtkSelectionNode.THRESHOLDS)
        self.ex_selection = vtk.vtkSelection()
        self.ex_selection.AddNode(self.selection_node)

        self.ex.SetInputConnection(0, self.box_picker.GetOutputPort())
        self.ex.SetInputData(1, self.ex_selection)

        self._down_pos = None
        self._up_pos = None

        self.iren = None
        self.ren_win = None
        self.ren_win_size = None

        self.data_picked = MrSignal()
        self.done_picking = MrSignal()

        self._picking_active = False

        # self.vtk_graphics = VTKGraphics.instance()

        from .picking_manager import PickingManager
        self.picking_manager = PickingManager.instance()

    def set_input_connection(self, port):
        self.box_picker.SetInputConnection(port)

    def begin_picking(self, interactor):
        self.iren = interactor

        self.ren_win = interactor.GetRenderWindow()
        self.ren_win_size = self.ren_win.GetSize()

        self._start_position[0] = interactor.GetEventPosition()[0]
        self._start_position[1] = interactor.GetEventPosition()[1]
        self._end_position[0] = self._start_position[0]
        self._end_position[1] = self._start_position[1]

        self._pixel_array.Reset()
        self._pixel_array.SetNumberOfComponents(4)
        self._pixel_array.SetNumberOfTuples(self.ren_win_size[0] * self.ren_win_size[1])

        self.ren_win.GetRGBACharPixelData(0, 0, self.ren_win_size[0] - 1, self.ren_win_size[1] - 1, 1,
                                          self._pixel_array)

        pos = interactor.GetEventPosition()

        self._down_pos = pos

        self._picking_active = True

    def end_picking(self, renderer, interactor):

        pos = interactor.GetEventPosition()

        self._up_pos = pos

        self._frustum = create_box_frustum(self._down_pos[0], self._down_pos[1],
                                           self._up_pos[0], self._up_pos[1], renderer)

        self.box_picker.SetFrustum(self._frustum)

        self.something_picked()

        self._picking_active = False
        self.done_picking.emit()

    def get_picking_frustums(self):
        return [self._frustum]

    def something_picked(self):
        self.box_picker.Modified()
        self.box_picker.Update()

        global_ids = self.box_picker.GetOutput().GetCellData().GetArray("global_ids")

        if global_ids is None:
            self.picking_manager.set_picked_data([])
            return

        get_value = global_ids.GetValue

        data = []

        for i in range(global_ids.GetNumberOfTuples()):
            data.append(get_value(i))

        self.picking_manager.set_picked_data(data)

    def _redraw_picking_box(self, interactor):
        tmp_array = vtk.vtkUnsignedCharArray()
        tmp_array.DeepCopy(self._pixel_array)

        min = [0, 0]
        max = [0, 0]

        size = self.ren_win_size

        if self._start_position[0] <= self._end_position[0]:
            min[0] = self._start_position[0]
        else:
            min[0] = self._end_position[0]

        if min[0] < 0:
            min[0] = 0
        if min[0] >= size[0]:
            min[0] = size[0] - 1

        if self._start_position[1] <= self._end_position[1]:
            min[1] = self._start_position[1]
        else:
            min[1] = self._end_position[1]

        if min[1] < 0:
            min[1] = 0
        if min[1] >= size[1]:
            min[1] = size[1] - 1

        if self._end_position[0] > self._start_position[0]:
            max[0] = self._end_position[0]
        else:
            max[0] = self._start_position[0]

        if max[0] < 0:
            max[0] = 0
        if max[0] >= size[0]:
            max[0] = size[0] - 1

        if self._end_position[1] > self._start_position[1]:
            max[1] = self._end_position[1]
        else:
            max[1] = self._start_position[1]

        if max[1] < 0:
            max[1] = 0
        if max[1] >= size[1]:
            max[1] = size[1] - 1

        for i in range(min[0], max[0] + 1):
            index1 = min[1] * size[0] + i
            tmp_array.SetTuple4(index1, 255, 120, 0, 1)

            index1 = max[1] * size[0] + i
            tmp_array.SetTuple4(index1, 255, 120, 0, 1)

        for i in range(min[1] + 1, max[1]):
            index1 = i*size[0] + min[0]
            tmp_array.SetTuple4(index1, 255, 120, 0, 1)

            index1 = i*size[0] + max[0]
            tmp_array.SetTuple4(index1, 255, 120, 0, 1)

        interactor.GetRenderWindow().SetRGBACharPixelData(0, 0, size[0] - 1, size[1] - 1, tmp_array, 0)
        interactor.GetRenderWindow().Frame()

    def OnButtonDown(self, x, y, ren, iren):
        self.begin_picking(iren)

    def OnButtonUp(self, x, y, ren, iren):
        self.end_picking(ren, iren)

    def OnMouseMove(self, x, y, ren, iren):
        if not self._picking_active:
            return

        if not ren:
            return

        self._end_position[0] = iren.GetEventPosition()[0]
        self._end_position[1] = iren.GetEventPosition()[1]
        self.ren_win_size = self.ren_win.GetSize()

        size = self.ren_win_size

        if self._end_position[0] > size[0] - 1:
            self._end_position[0] = size[0] - 1

        if self._end_position[0] < 0:
            self._end_position[0] = 0

        if self._end_position[1] > size[1] - 1:
            self._end_position[1] = size[1] - 1

        if self._end_position[1] < 0:
            self._end_position[1] = 0

        self._redraw_picking_box(iren)

    def PrintSelf(self):
        super(self, BoxPicker).PrintSelf()
        print("Center: %f, %f, %f" % (self.Center[0], self.Center[1], self.Center[2]))

    def finalize(self):
        # self.vtk_graphics = None
        self.picking_manager = None
Пример #20
0
class BasicDockWidget(QtWidgets.QDockWidget):
    def __init__(self, dock_name='BasicDockWidget'):
        super(BasicDockWidget, self).__init__()

        self.dock_name = dock_name

        self.setWindowTitle(dock_name)

        self.dispatcher = _CommandDispatcher(dock_name, self)

        self.widget = None

        self.show_dock = MrSignal()

        self.data_changed = MrSignal()
        """:type: MrSignal"""

    def set_widget(self, tab_widget):
        try:
            self.widget.data_changed.disconnect_all()
        except AttributeError:
            pass

        self.widget = tab_widget
        self.setWidget(self.widget)

        self.dispatcher.add_child(self.widget.dispatcher)

        try:
            self.widget.data_changed.connect(self._data_changed)
        except AttributeError:
            pass

    def _data_changed(self, *args):
        self.data_changed.emit()

    def request_focus(self):
        self.show()
        self.raise_()

    def keyPressEvent(self, event):
        super(BasicDockWidget, self).keyPressEvent(event)

        if event.isAccepted():
            return

        if event.matches(QtGui.QKeySequence.Undo):
            event.accept()
            self.dispatcher.dispatch('Undo')

        elif event.matches(QtGui.QKeySequence.Redo):
            event.accept()
            self.dispatcher.dispatch('Redo')

    def serialize(self):
        return self.widget.serialize()

    def load(self, data):
        self.widget.load(data)

    def clear(self):
        self.widget.clear()

    def update_all(self):
        self.widget.update_all()

    def clear_data(self):
        try:
            self.widget.clear_data()
        except AttributeError:
            pass
Пример #21
0
class BasicTabWidget(QtWidgets.QTabWidget):
    def __init__(self, tab_name, parent=None):
        super(BasicTabWidget, self).__init__(parent)

        self.tab_name = tab_name

        self.dispatcher = _CommandDispatcher(tab_name, self)

        self.tables = {}

        self.data_changed = MrSignal()

    def add_table(self, table, name, prefix):
        """

        :param table:
        :type table: BasicTable
        :param name:
        :type name: str
        :param prefix:
        :type prefix: str
        :return:
        :rtype:
        """

        self.dispatcher.add_child(table.dispatcher)

        self.addTab(table, name)

        self.tables[name] = table

        table.table_1.data_changed.connect(self._data_changed)
        table.table_2.data_changed.connect(self._data_changed)

    def _data_changed(self, *args):
        self.data_changed.emit()

    def keyPressEvent(self, event):
        super(BasicTabWidget, self).keyPressEvent(event)

        if event.isAccepted():
            return

        if event.matches(QtGui.QKeySequence.Undo):
            event.accept()
            self.dispatcher.dispatch('Undo')

        elif event.matches(QtGui.QKeySequence.Redo):
            event.accept()
            self.dispatcher.dispatch('Redo')

    def serialize(self):
        data = []
        for key, table in iteritems(self.tables):
            data.append([key, table.serialize()])

        return data

    def load(self, data):
        for data_ in data:
            key, _data = data_
            self.tables[key].load(_data)

    def clear(self):
        for key, table in iteritems(self.tables):
            table.clear()

    def update_all(self):
        for key, table in iteritems(self.tables):
            table.update_all()
Пример #22
0
class FemSelection(object):
    def __init__(self):
        self.data = FemSelectionCpp()
        self.data_changed = MrSignal()

    def clear(self):
        self.data.clear()

    def copy(self, other):
        """

        :param other:
        :type other: FemSelection
        :return:
        :rtype:
        """
        self.set_data(other.data._data)

    def set_data(self, data):
        if isinstance(data, int):
            self.data.set_data1(data)
        elif isinstance(data, list):
            self.data.set_data2(data)
        elif isinstance(data, set):
            self.data.set_data3(data)
        elif isinstance(data, np.ndarray):
            self.data.set_data4(data, data.size)
        elif isinstance(data, str):
            self.data.set_data2(self.from_str(data))
        else:
            raise TypeError(type(data))

        self.data_changed.emit()

    def add_data(self, data):
        if isinstance(data, int):
            self.data.add_data1(data)
        elif isinstance(data, list):
            self.data.add_data2(data)
        elif isinstance(data, set):
            self.data.add_data3(data)
        elif isinstance(data, np.ndarray):
            self.data.add_data2(data)
        elif isinstance(data, str):
            self.data.add_data2(self.from_str(data))
        else:
            raise TypeError(type(data))

        self.data_changed.emit()

    def intersect(self, data):
        if isinstance(data, int):
            self.data.intersect1(data)
        elif isinstance(data, list):
            self.data.intersect2(data)
        elif isinstance(data, set):
            self.data.intersect3(data)
        elif isinstance(data, np.ndarray):
            self.data.intersect2(data)
        elif isinstance(data, str):
            self.data.intersect2(self.from_str(data))
        else:
            raise TypeError(type(data))

        self.data_changed.emit()

    def remove_data(self, data):
        if isinstance(data, int):
            self.data.remove_data1(data)
        elif isinstance(data, list):
            self.data.remove_data2(data)
        elif isinstance(data, set):
            self.data.remove_data3(data)
        elif isinstance(data, np.ndarray):
            self.data.remove_data2(data)
        elif isinstance(data, str):
            self.data.remove_data2(self.from_str(data))
        else:
            raise TypeError(type(data))

        self.data_changed.emit()

    def to_set(self):
        return self.data._data

    def to_numpy(self):
        return self.data.to_vector()

    def to_vector(self):
        return self.data.to_vector()

    def selection_by_category(self, category):
        results = self.data.selection_by_category(category)
        tmp = FemSelection()
        tmp.set_data(results)

        return tmp

    def to_str(self):
        sorted_list = sorted(list(self.data.to_vector()))

        categories = OrderedDict()

        get_category = bdf_card_info.card_category_by_eid
        global_id = bdf_card_info.global_id

        for eid in sorted_list:
            category = get_category(eid)
            eid_ = global_id(eid)
            try:
                categories[category].append(eid_)
            except KeyError:
                categories[category] = [eid_]

        result = ""

        for category, the_list in iteritems(categories):
            result += "%s %s\n\n" % (str(category), condense_list(the_list))

        return result[:-1]

    def to_str2(self):
        condensed = self.data.condense()

        get_category = bdf_card_info.card_category_by_eid
        global_id = bdf_card_info.global_id

        result = []

        # FIXME: fix for len(condensed) < 3
        # FIXME: this method doesn't work

        for tmp in condensed:

            try:
                category = get_category(tmp[0]).decode('utf-8')
            except IndexError:
                continue

            tmp_result = [category]

            for i in range(0, len(tmp), 3):
                eid1 = tmp[i]
                eid2 = tmp[i + 1]
                stride = tmp[i + 2]

                if stride != -1:
                    eid1 = global_id(eid1)
                    eid2 = global_id(eid2)
                    tmp_result.append('%d:%d:%d' % (eid1, eid2, stride))
                elif eid2 != -1:
                    eid1 = global_id(eid1)
                    eid2 = global_id(eid2)
                    tmp_result.append('%d:%d' % (eid1, eid2))
                else:
                    tmp_result.append('%d' % global_id(eid1))

            if len(tmp_result) > 1:
                result.append(' '.join(tmp_result))

        return '\n\n'.join(result)

    def from_str(self, data):
        if data == "":
            return []

        data_ = re.split(' |\n', data)

        def get_category(data):
            try:
                first = data[0].upper()
            except IndexError:
                return None

            if "G" == first or "N" == first:
                return "GRID"
            elif "E" == first:
                return "ELEMENT"
            elif "P" == first:
                return "PROPERTY"
            elif "R" == first:
                return "RBE"
            elif "M" == first:
                return "MPC"
            elif "F" == first:
                return "FORCE"
            elif "D" == first:
                return "Disp"
            elif "C" == first:
                return "COORD"
            else:
                return None

        results_ = []
        offset = 0

        for dat_ in data_:
            category = get_category(dat_)
            if category is not None:
                offset = bdf_card_info.categories(category) * 100000000
                continue

            new_list = [i + offset for i in expand_list(dat_)]
            results_.extend(new_list)

        return results_

    def set_from_str(self, data):
        self.set_data(self.from_str(data))
        return self

    def raw_pointer(self):
        return self.data._data

    def __iand__(self, data):
        self.intersect(data)
        return self

    def __ior__(self, data):
        self.add_data(data)
        return self

    def __contains__(self, data):
        return self.data.contains(data)
Пример #23
0
class MrDataTable2(QtWidgets.QWidget):

    row_changed = QtCore.Signal(int)
    column_changed = QtCore.Signal(int)
    selection_changed = QtCore.Signal(int, int)

    @classmethod
    def wrap_obj(cls, obj=None, *args, **kwargs):
        """

        :rtype: MrDataTable
        """

        if obj is None:
            obj = MrDataTable2(None, *args)
            return obj

        elif isinstance(obj, MrDataTable2):
            return obj

        assert isinstance(obj, QtWidgets.QTableView)

        return MrDataTable2(obj, *args)

    def __init__(self, table_view=None, *args):
        super(MrDataTable2, self).__init__(*args)

        if table_view is None:
            table_view = QtWidgets.QTableView(self)

        self.table_view = table_view
        self.table_view.keyPressEvent = self.keyPressEvent
        self.table_view.keyReleaseEvent = self.keyReleaseEvent

        self.table_model = MrTableModel(self.table_view)
        self.table_view.setModel(self.table_model)

        self.selection_model = self.table_view.selectionModel()
        """:type: QtGui.QItemSelectionModel"""

        self.selection_model.selectionChanged.connect(self._selection_changed)

        self._old_row = -1
        self._old_column = -1

        self._enter_down = False

        self.data_changed = self.table_model.data_changed
        self.data_changed.connect(self._data_changed)

        self.copy = MrSignal()
        self.paste = MrSignal()
        self.show()

    def horizontalHeader(self):
        return self.table_view.horizontalHeader()

    def _data_changed(self, row, column):
        if self._enter_down:
            row += 1
            column = column

            if row >= self.table_model.rowCount():
                row -= 1

            self.set_selection([[row, column]])

    def set_selection(self, selections):
        try:
            QtWidgets.QApplication.instance().focusWidget().clearFocus()
        except AttributeError:
            pass

        self.selection_model.clearSelection()

        first_index = None

        for i in range(len(selections)):
            selection = selections[i]
            index = self.table_model.index(selection[0], selection[1])
            self.selection_model.select(index, QtCore.QItemSelectionModel.Select)

            if first_index is None:
                first_index = index

        self.setCurrentIndex(first_index)
        #self.setFocus(True)
        self.setFocus()

    def keyPressEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = True

        elif event.matches(QtGui.QKeySequence.Copy):
            self.copy.emit((self.current_row(), self.current_column()))

        elif event.matches(QtGui.QKeySequence.Paste):
            tmp = QtWidgets.QApplication.clipboard().text().split('\n')
            del tmp[-1]
            paste_data = []

            for tmp_ in tmp:
                paste_data.append([str(i) for i in tmp_.split('\t')])

            self.paste.emit((self.current_row(), self.current_column()), paste_data)

        QtWidgets.QTableView.keyPressEvent(self.table_view, event)

    def keyReleaseEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = False

        QtWidgets.QTableView.keyReleaseEvent(self.table_view, event)

    def setup_data(self, headers, data):
        self.table_model.setup_data(headers, data)

    def set_headers(self, headers):
        self.table_model.set_headers(headers)

    def sizeHint(self):
        return QtCore.QSize(800, 500)

    def update_all(self):
        self.table_model.update_all()

    def current_row(self):
        return self._old_row

    def current_column(self):
        return self._old_column

    def set_editable_columns(self, int_set):
        self.table_model.set_editable_columns(int_set)

    def _selection_changed(self, current, previous):
        """
        :type current: QtGui.QItemSelection
        :type previous:QtGui.QItemSelection
        """

        try:
            first_index = current.indexes()[0]
        except IndexError:
            return

        new_row = first_index.row()
        new_column = first_index.column()

        old_row = self._old_row
        old_column = self._old_column

        selection_changed = False

        if new_row != old_row:
            self._old_row = new_row
            self.row_changed.emit(self._old_row)
            selection_changed = True

        if new_column != old_column:
            self._old_column = new_column
            self.column_changed.emit(self._old_column)
            selection_changed = True

        if selection_changed:
            self.selection_changed.emit(new_row, new_column)

    def select_last_row(self):
        data_len = len(self.table_model._data)

        self.set_selection([[data_len-1, 0]])

    def select_and_edit(self, row, column):
        index = self.table_model.index(row, column)
        self.selectionModel().clear()
        self.selectionModel().select(index, QtCore.QItemSelectionModel.Select)
        self.edit(index)
Пример #24
0
class DockDataTable(QtWidgets.QTableView):

    # row_changed = QtCore.Signal(int)
    # column_changed = QtCore.Signal(int)
    # selection_changed = QtCore.Signal(int, int)

    @classmethod
    def wrap_obj(cls, obj=None, *args, **kwargs):
        """

        :rtype: DockDataTable
        """

        if obj is None:
            obj = cls(*args, **kwargs)
            return obj

        elif isinstance(obj, cls):
            return obj

        assert isinstance(obj, QtWidgets.QTableView)

        obj.__class__ = cls
        # noinspection PyCallByClass,PyTypeChecker
        cls.init(obj)

        return obj

    def __init__(self, *args):
        super(DockDataTable, self).__init__(*args)

        self.table_model = None
        """:type: DockDataTableModel"""

        self.selection_model = None
        """:type: QtGui.QItemSelectionModel"""

        self._old_row = -1
        self._old_column = -1

        self._enter_down = False

        self.set_data = None
        """:type: MrSignal"""

        self.copy = None
        """:type: MrSignal"""
        self.paste = None
        """:type: MrSignal"""
        self.right_click = None
        """:type: MrSignal"""

        self.row_changed = None
        """:type: MrSignal"""
        self.column_changed = None
        """:type: MrSignal"""
        self.selection_changed = None
        """:type: MrSignal"""

        self.init()

    def init(self):
        self.table_model = DockDataTableModel(self)
        self.setModel(self.table_model)

        self.selection_model = self.selectionModel()
        """:type: QtGui.QItemSelectionModel"""
        self.selection_model.selectionChanged.connect(self._selection_changed)

        self._old_row = -1
        self._old_column = -1

        self._enter_down = False

        self.set_data = self.table_model.set_data

        self.copy = MrSignal()
        self.paste = MrSignal()
        self.set_data = self.table_model.set_data
        self.right_click = MrSignal()

        self.row_changed = MrSignal()
        self.column_changed = MrSignal()
        self.selection_changed = MrSignal()

    def set_selection(self, selections):
        try:
            QtWidgets.QApplication.instance().focusWidget().clearFocus()
        except AttributeError:
            pass

        self.selection_model.clearSelection()

        first_index = None

        for i in range(len(selections)):
            selection = selections[i]
            index = self.table_model.index(selection[0], selection[1])
            self.selection_model.select(index,
                                        QtCore.QItemSelectionModel.Select)

            if first_index is None:
                first_index = index

        self.setCurrentIndex(first_index)
        # self.setFocus(True)
        self.setFocus()

    def selection(self):
        selection = self.selectionModel().selectedIndexes()

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

        return [(min_row, min_col), (max_row, max_col)]

    def keyPressEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = True

        elif event.matches(QtGui.QKeySequence.Copy):
            self._copy()
            return

        elif event.matches(QtGui.QKeySequence.Paste):
            paste_data = str(QtWidgets.QApplication.clipboard().text())
            self.paste.emit(self.selection(), paste_data)

        super(DockDataTable, self).keyPressEvent(event)

    def _copy(self):
        model = self.model()
        selection = self.selectionModel().selectedIndexes()

        edit_role = QtCore.Qt.EditRole

        try:
            row1 = selection[0].row()
            col1 = selection[0].column()
        except IndexError:
            return

        copy_data = []

        min_row = 9999999
        max_row = -1
        min_col = 9999999
        max_col = -1

        for index in selection:
            row = index.row()
            col = index.column()

            min_row = min(min_row, row)
            max_row = max(max_row, row)

            min_col = min(min_col, col)
            max_col = max(max_col, col)

            data = str(model.data(index, edit_role))

            copy_data.append([row, col, data])

        rows = max_row - min_row + 1
        columns = max_col - min_col + 1

        if rows == 0 or columns == 0:
            return

        np_data = np.zeros((rows, columns), dtype=object)

        for tmp in copy_data:
            row, col, data = tmp

            row -= min_row
            col -= min_col

            np_data[row, col] = data

        text = ''

        for i in range(np_data.shape[0]):
            for j in range(np_data.shape[1]):
                text += np_data[i, j] + '\t'
            text += '\n'

        # noinspection PyArgumentList
        clipboard = QtWidgets.QApplication.clipboard()
        """:type: QtGui.QClipboard"""

        # print('text to copy = ', text)
        text = text.replace('\t\n', '\n')[:-1]
        # print('text to copy = ', text)

        clipboard.setText(text)

        # may not be needed
        self.copy.emit(self.selection(), text)

    def keyReleaseEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self._enter_down = False

        super(DockDataTable, self).keyReleaseEvent(event)

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.RightButton:
            index = self.indexAt(event.pos())
            self.set_selection([[index.row(), index.column()]])

        super(DockDataTable, self).mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        if event.button() == QtCore.Qt.RightButton:
            index = self.indexAt(event.pos())
            self.right_click.emit(index.row(), index.column())

        super(DockDataTable, self).mouseReleaseEvent(event)

    def setup_data(self, data, headers=None):
        self.table_model.setup_data(data, headers)

    def sizeHint(self):
        return QtCore.QSize(800, 500)

    def update_all(self):
        self.table_model.update_all()

    def current_row(self):
        try:
            self.selectionModel().selectedIndices()[0].row()
        except Exception:
            return self._old_row

    def current_column(self):
        try:
            self.selectionModel().selectedIndices()[0].column()
        except Exception:
            return self._old_column

    def row_count(self):
        return self.table_model.rowCount()

    def column_count(self):
        return self.table_model.columnCount()

    def set_editable_columns(self, int_set):
        self.table_model.set_editable_columns(int_set)

    def _selection_changed(self, current, previous):
        """
        :type current: QtGui.QItemSelection
        :type previous:QtGui.QItemSelection
        """

        try:
            first_index = current.indexes()[0]
        except IndexError:
            return

        new_row = first_index.row()
        new_column = first_index.column()

        old_row = self._old_row
        old_column = self._old_column

        selection_changed = False

        if new_row != old_row:
            self._old_row = new_row
            self.row_changed.emit(self._old_row)
            selection_changed = True

        if new_column != old_column:
            self._old_column = new_column
            self.column_changed.emit(self._old_column)
            selection_changed = True

        if selection_changed:
            self.selection_changed.emit(new_row, new_column)

    def select_last_row(self):
        data_len = len(self.table_model.model_data)

        column = self.current_column()

        if column < 0:
            column = 0

        self.set_selection([[data_len - 1, column]])

    def select_and_edit(self, index):
        index = self.table_model.index(*index)
        self.selectionModel().clear()
        self.selectionModel().select(index, QtCore.QItemSelectionModel.Select)
        self.edit(index)

    def select(self, index):
        index = self.table_model.index(*index)
        self.selectionModel().clear()
        self.selectionModel().select(index, QtCore.QItemSelectionModel.Select)
Пример #25
0
class DoubleTreeHandler(object):
    def __init__(self,
                 tree1,
                 tree2,
                 add_btn,
                 del_btn,
                 add_all=None,
                 remove_all=None):

        self.data_added = MrSignal()
        self.data_removed = MrSignal()
        self.selection_changed = MrSignal()

        if not isinstance(tree1, BasicTreeView):
            tree1 = BasicTreeView.wrap_obj(tree1)

        if not isinstance(tree2, BasicTreeView):
            tree2 = BasicTreeView.wrap_obj(tree2)

        self._tree1 = tree1
        self._tree2 = tree2

        self._tree1.sorting_changed.connect(self.update_trees)
        self._tree2.sorting_changed.connect(self.update_trees)

        self.pushButton_add = add_btn
        """:type: QtGui.QPushButton"""
        self.pushButton_delete = del_btn
        """:type: QtGui.QPushButton"""

        self.pushButton_add_all = add_all
        """:type: QtGui.QPushButton"""
        self.pushButton_remove_all = remove_all
        """:type: QtGui.QPushButton"""

        self.pushButton_add_clicked = MrSignal()
        self.pushButton_delete_clicked = MrSignal()
        self.pushButton_add_all_clicked = MrSignal()
        self.pushButton_remove_all_clicked = MrSignal()

        self.pushButton_add.clicked.connect(self.pushButton_add_clicked.emit)
        self.pushButton_delete.clicked.connect(
            self.pushButton_delete_clicked.emit)

        if self.pushButton_add_all:
            self.pushButton_add_all.clicked.connect(
                self.pushButton_add_all_clicked.emit)

        if self.pushButton_remove_all:
            self.pushButton_remove_all.clicked.connect(
                self.pushButton_remove_all_clicked.emit)

        self.pushButton_add_clicked.connect(self._add_btn_clicked)
        self.pushButton_delete_clicked.connect(self._remove_btn_clicked)
        self.pushButton_add_all_clicked.connect(self.add_all)
        self.pushButton_remove_all_clicked.connect(self.remove_all)

        self._data = OrderedDict()

    def _add_btn_clicked(self, *args):
        self.add_selection(self._tree1.get_selected_items_text())

    def _remove_btn_clicked(self, *args):
        self.remove_selection(self._tree2.get_selected_items_text())

    def get_selected_1(self):
        return self._tree1.get_selected_items_text()

    def get_selected_2(self):
        return self._tree2.get_selected_items_text()

    def add_selection(self, selected_items_text):
        data_keys = list(self._data.keys())

        if not data_keys:
            return

        selection = selected_items_text

        if not selection:
            return

        for item in selection:
            row = data_keys.index(item)
            self._data[data_keys[row]] = 1

        self.update_trees()

        first_index = data_keys.index(selection[0])
        self.data_added.emit(first_index, selection[0])

        self.selection_changed.emit()

    def remove_selection(self, selected_items_text):
        data_keys = list(self._data.keys())

        if not data_keys:
            return

        selection = selected_items_text

        if not selection:
            return

        for item in selection:
            row = data_keys.index(item)
            self._data[data_keys[row]] = 0

        self.update_trees()

        first_index = data_keys.index(selection[0])
        self.data_added.emit(first_index, selection[0])

        self.selection_changed.emit()

    def _add_all_clicked(self):
        self.add_all()

    def add_all(self, *args):
        data_keys = self._data.keys()

        for data in data_keys:
            self._data[data] = 1

        self.update_trees()

        self.selection_changed.emit()

    def _remove_all_clicked(self):
        self.remove_all()

    def remove_all(self, *args):
        data_keys = self._data.keys()

        for data in data_keys:
            self._data[data] = 0

        self.update_trees()

        self.selection_changed.emit()

    def clear(self):
        self._tree1.clear()
        self._tree2.clear()
        self._data.clear()

    def set_data(self, new_data, selected=()):
        self.clear()

        new_dict = OrderedDict()

        for data in new_data:
            new_dict[str(data)] = 0

        for data in selected:
            new_dict[str(data)] = 1

        self._data = new_dict

        self.update_trees()

    def set_data_dict(self, data_dict):

        self.clear()

        new_dict = OrderedDict()

        for key in data_dict.keys():
            new_dict[str(key)] = data_dict[key]

        self._data = new_dict

        self.update_trees()

    def get_data(self):
        return self._data.keys()

    def get_data_dict(self):
        return OrderedDict(self._data)

    def get_selected_data(self):
        data = []

        for key, item in iteritems(self._data):
            if item == 1:
                data.append(key)

        return data

    def get_selected_indices(self):
        data = []

        i = 0

        for key, item in iteritems(self._data):
            if item == 1:
                data.append(i)

            i += 1

        return data

    def get_unselected_indices(self):
        data = []

        i = 0

        for key, item in iteritems(self._data):
            if item != 1:
                data.append(i)

            i += 1

        return data

    def set_selected_indices(self, indices):

        i = 0

        _data = self._data
        for key, item in iteritems(_data):
            if i in indices:
                _data[key] = 1
            else:
                _data[key] = 0

            i += 1

        self.update_trees()

    def update_trees(self):
        tree1_data = []
        tree2_data = []

        for data in self._data.keys():
            if self._data[data]:
                tree2_data.append(data)
            else:
                tree1_data.append(data)

        self._tree1.clear()
        self._tree1.add_items(tree1_data)

        self._tree2.clear()
        self._tree2.add_items(tree2_data)

    def get_tree1(self):
        return self._tree1

    def get_tree2(self):
        return self._tree2

    def set_headers(self, left_header, right_header):
        self._tree1.set_header(left_header)
        self._tree2.set_header(right_header)
Пример #26
0
class DockDataTableModel(QtCore.QAbstractTableModel):
    def __init__(self, *args):
        super(DockDataTableModel, self).__init__(*args)
        self._headers = None
        self.model_data = None

        self.editable_columns = set()

        self.set_data = MrSignal()

        self._count = 0

    def setup_data(self, data, headers=None):

        if data == []:
            self.model_data = []
            self._headers = []
            return

        if headers is None:
            headers = data.headers

        if not isinstance(headers, (list, tuple)):
            headers = [headers]

        self._headers = headers[:]

        if self._headers[-1] is None:
            del self._headers[-1]

        self.model_data = data

        if self.model_data is None:
            return

        self.update_all()

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):

        if role != QtCore.Qt.DisplayRole:
            # if '' is returned, the headers won't show up...
            return QtCore.QVariant()

        if orientation == QtCore.Qt.Horizontal:
            try:
                return self._headers[section]
            except (TypeError, IndexError):
                return ''
        else:
            return section + 1

    def rowCount(self, index=QtCore.QModelIndex()):
        if self.model_data is None:
            return 0

        return len(self.model_data)

    def columnCount(self, index=QtCore.QModelIndex()):
        if self._headers is None:
            return 0

        return len(self._headers)

    def set_editable_columns(self, int_set):
        self.editable_columns = int_set

    def flags(self, index):
        if int(index.column()) in self.editable_columns:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
        else:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if self.model_data is None or self._headers is None:
            return ''

        if role == QtCore.Qt.EditRole:
            row = index.row()
            col = index.column()

            data = self.model_data[row][col]

            if data is None:
                return ''

            return str(data)

        elif role == QtCore.Qt.DisplayRole:
            row = index.row()
            col = index.column()

            data = self.model_data[row][col]

            if data is None:
                return ''

            if isinstance(data, list) and len(data) > 0 and isinstance(
                    data[0], float):
                return str([round(i, 6) for i in data])

            return str(data)

    def setData(self, index, value, role=QtCore.Qt.DisplayRole):
        if self.model_data is None or self._headers is None:
            return False

        self.set_data.emit(index, value, role)

        return self.set_data.results[0]

    def update_all(self):
        self.layoutChanged.emit()
        top_left = self.index(0, 0)
        bot_right = self.index(self.rowCount() - 1, self.columnCount() - 1)
        self.dataChanged.emit(top_left, bot_right)
Пример #27
0
class Configuration(object):
    config_file = config_file
    _major_version = 0
    _minor_version = 0
    _micro_version = 0
    _other_version = 'alpha'

    def __init__(self):
        self._database_exe = None

        self._application_name = 'N/A'

        self._user_manual = None
        self._email_recipient = None

        self._long_name = None
        self._date_created = None
        self._date_modified = None
        self._author = None
        self._description = None

        self._icon = None

        self._file_extension = None
        self._macro_extension = None

        tmp = scriptinfo()

        self._executable = tmp['name']
        self._executable_directory = tmp['dir']
        self._frozen = tmp['frozen']

        self._directory = None
        self._filename = ''

        self._dpi = 0

        self._app_data_path = None
        self._settings_file = None
        self._default_settings_file = None

        self._release_file = None
        self._beta_file = None

        self._app = None
        """:type: PyQt5.QtWidgets.QApplication.QApplication"""

        self._main_window = None
        """:type: PyQt5.QtWidgets.QMainWindow.QMainWindow"""

        self._main_data = None

        self.dispatcher = CommandDispatcher()

        ##############################################################################

        self._msgs = []

        self.message = MrSignal()
        self.msg = MrSignal()

        self._read_config()

        self.picking_manager = None
        """:type: fem.gui.vtk_widget.vtk_graphics.picking.PickingManager"""

    def register_picking_manager(self, picking_manager):
        self.picking_manager = picking_manager

    def database_exe(self):
        return self._database_exe

    def application_name(self):
        return self._application_name

    def major_version(self):
        return self._major_version

    def minor_version(self):
        return self._minor_version

    def micro_version(self):
        return self._micro_version

    def other_version(self):
        return self._other_version

    def user_manual(self):
        return self._user_manual

    def email_recipient(self):
        return self._email_recipient

    def long_name(self):
        return self._long_name

    def date_created(self):
        return self._date_created

    def date_modified(self):
        return self._date_modified

    def author(self):
        return self._author

    def description(self):
        return self._description

    def icon(self):
        return self._icon

    def file_extension(self):
        return self._file_extension

    def macro_extension(self):
        return self._macro_extension

    def executable(self):
        return self._executable

    def executable_directory(self):
        return self._executable_directory

    def frozen(self):
        return self._frozen

    def directory(self):
        # type: () -> str
        if self._directory is None:
            return self.home_directory()

        return self._directory

    def set_directory(self, directory):
        # type: (str) -> None
        directory = os.path.dirname(os.path.realpath(str(directory)))

        assert os.path.isdir(directory)

        self._directory = directory

    def filename(self):
        # type: () -> str
        return self._filename

    def set_filename(self, filename):
        # type: (str) -> None
        self.set_directory(filename)
        self._filename = filename

    def dpi(self):
        return self._dpi

    def app_data_path(self):
        return self._app_data_path

    def settings_file(self):
        return self._settings_file

    def default_settings_file(self):
        if os.path.isfile(self._default_settings_file):
            return self._default_settings_file

        return None

    def release_file(self):
        return self._release_file

    def beta_file(self):
        return self._beta_file

    def app(self):
        if self._app is None:
            self._app = QtWidgets.QApplication([])
            w = QtWidgets.QWidget()
            self._dpi = w.logicalDpiX()

            if self._dpi != 96:
                font = self._app.font()
                font.setPixelSize(13)
                self._app.setFont(font)

        return self._app

    def set_icon(self):
        self.app().setWindowIcon(QtGui.QIcon(self._icon))

    def main_window(self):
        return self._main_window

    def register_main_window(self, mw):
        self._main_window = mw
        try:
            self.dispatcher.register_main_window(mw)
        except AttributeError:
            pass

    def main_data(self):
        return self._main_data

    def register_main_data(self, md):
        self._main_data = md

    def version(self):
        if self._other_version == '':
            return self._major_version, self._minor_version, self._micro_version
        else:
            return self._major_version, self._minor_version, self._micro_version, self._other_version

    def application_version(self):
        return ('%d.%d.%d %s' %
                (self._major_version, self._minor_version, self._micro_version,
                 self._other_version)).strip()

    def program_name(self):
        # type: () -> str
        return '%s %s' % (self._application_name, self.application_version())

    def application_info(self):
        # _data_roles = OrderedDict()
        data = {}

        data['Application Name'] = self._application_name
        data['Application Version'] = self.application_version()

        ts = timestamp().split(' ')

        data['Date'] = ts[0]
        data['Time'] = ts[1]
        data['User ID'] = self.user_id()

        return data

    def window_title(self):
        # type: () -> str
        if self._filename is None:
            filename = "*"
        else:
            filename = self._filename

        if not self.dispatcher.undo_stack.isClean():
            filename += "*"

        return "%s - [%s]" % (self.program_name(), filename)

    def user_id(self):
        return getpass.getuser()

    @staticmethod
    def home_directory():
        # type: () -> str
        return os.path.expanduser('~')

    def view_label(self):
        # type: () -> str
        if self._filename is None:
            filename = '*'
        else:
            filename = self._filename

        return '%s\n%s\n%s' % (self.program_name(), filename, timestamp())

    def about(self):
        about_txt = """
        Program Name: %s
        Version: %s
        Description: %s

        Author: %s
        Date Created: %s
        Date Modified: %s
        """ % (self._long_name, self.application_version(), self._description,
               self._author, self._date_created, self._date_modified)

        return about_txt

    @staticmethod
    def file_in_use(filename):
        if os.path.exists(filename):
            # noinspection PyBroadException
            try:
                os.rename(filename, filename + '_')
                os.rename(filename + '_', filename)
                return False
            except Exception:
                return True

        return False

    def info_message(self, msg):
        # type: (str) -> None
        self.msg.emit('Info: %s' % msg)

    def push_error(self, msg):
        self._msgs.append('Error: %s' % msg)

    def push_info(self, msg):
        self._msgs.append('Info: %s' % msg)

    def flush_msgs(self):
        for msg in self._msgs:
            self.msg.emit(msg)

        del self._msgs[:]

    def clear_msgs(self):
        del self._msgs[:]

    def error_message(self, msg):
        # type: (str) -> None
        self.msg.emit('Error: %s' % msg)

    def _read_config(self):

        config_file = self.config_file

        if config_file is None:
            return

        # config_file = 'configuration.%s.%d.%d.%d.json' % (
        #     self.config_app_name, self._major_version, self._minor_version, self._micro_version
        # )
        # config_file = os.path.join(self.config_directory, config_file)

        with open(config_file, 'r') as f:
            data = json.load(f)

        application = data['application']

        self._author = application['author']
        self._date_created = application['date_created']
        self._date_modified = application['date_modified']
        self._description = application['description']
        self._long_name = application['long_name']
        self._application_name = application['application_name']

        version = application['version']

        major = version['major']
        minor = version['minor']
        micro = version['micro']
        other = version['other']

        files = data['files']

        self._release_file = files['release_file']
        self._beta_file = files['beta_file']
        self._icon = files['icon']
        self._user_manual = files['user_manual']
        # self._default_settings_file = files['default_settings_file']

        feedback = data['feedback']

        self._email_recipient = feedback['email_recipient']

        extensions = data['extensions']

        self._file_extension = extensions['file_extension']
        self._macro_extension = extensions['macro_extension']

        # self._database_exe = data['plugins']['punch_database']

        self._app_data_path = os.getenv(
            'APPDATA') + r'\StressApps\%s' % self._application_name.lower()

        assert (major, minor, micro,
                other) == (self._major_version, self._minor_version,
                           self._micro_version, self._other_version)

        self.set_icon()

        return data
Пример #28
0
class PickingManager(object):

    _instance = None

    @classmethod
    def instance(cls):
        """

        :return:
        :rtype: PickingManager
        """
        if cls._instance is None:
            cls._instance = cls()

        return cls._instance

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(PickingManager, cls).__new__(cls)
        return cls._instance

    def __init__(self):

        from fem.gui.vtk_widget.vtk_graphics import VTKGraphics

        self.vtk_graphics = VTKGraphics.instance()
        """:type: fem.gui.vtk_widget.vtk_graphics.VTKGraphics"""

        self.picked_selection = self.vtk_graphics.picked_selection
        """:type: fem.gui.vtk_widget.vtk_graphics.picked.PickedSelection"""

        self.default_single_picker = DefaultSinglePicker(self)
        self._single_pickers = [self.default_single_picker]
        """:type: list[SinglePicker]"""

        self.single_picker = self.default_single_picker

        self.picking_option = 1

        self._registered_selection = None
        """:type: fem.gui.vtk_widget.vtk_graphics.picked.PickedSelection"""

        self.picking_finished = MrSignal()

    def picking_done(self):
        self.picking_finished.emit()

    def register_selection(self, selection):
        if selection is None:
            self._registered_selection = None
            self.picked_selection.data_changed.disconnect_all()
            return

        self._registered_selection = selection

        self.picked_selection.data_changed.block()
        self.picked_selection.copy(self._registered_selection)
        self.picked_selection.data_changed.unblock()

        self.picked_selection.data_changed.disconnect_all()
        self.picked_selection.data_changed.connect(self._picked_selection_changed)

    def register_single_picker(self, single_picker):
        if single_picker is not self.single_picker:
            if self.single_picker is not None:
                try:
                    last_ = self._single_pickers[-1]
                except IndexError:
                    last_ = None
                if self.single_picker is not last_:
                    self._single_pickers.append(self.single_picker)

        self.single_picker = single_picker

    def unload_single_picker(self, picker):
        if picker is self.single_picker:
            try:
                self.single_picker = self._single_pickers.pop()
            except IndexError:
                self.single_picker = None

    def single_pick(self, screen_pos, cell_pos, picked_global_id):
        if self.single_picker is None:
            return

        self.single_picker.pick(screen_pos, cell_pos, picked_global_id)

    def set_picking_option(self, option):
        assert option in (1, 2, 3)

        self.picking_option = option

    def set_picked_data(self, data):
        option = self.picking_option

        if option == 1:
            self.picked_selection.set_data(data)
        elif option == 2:
            self.picked_selection.add_data(data)
        elif option == 3:
            self.picked_selection.remove_data(data)
        else:
            raise ValueError

        self.vtk_graphics.picked_filter.Modified()
        self.vtk_graphics.render()

    def box_picker_activate(self):
        self.vtk_graphics.interactor_style.box_picker_activate()

    def poly_picker_activate(self):
        self.vtk_graphics.interactor_style.poly_picker_activate()

    def _picked_selection_changed(self, *args):
        if self._registered_selection is None:
            return

        self._registered_selection.copy(self.picked_selection)

    def finalize(self):
        for picker in self._single_pickers:
            picker.finalize()

        del self._single_pickers[:]

        self.default_single_picker.finalize()
        self.default_single_picker = None

        self.vtk_graphics = None