Beispiel #1
0
    def __init__(self, parent=None):
        super(TemplateSelectDialog, self).__init__(parent)

        self.setWindowTitle(_("Select a template"))

        self.template_id = []

        self.model = QStandardItemModel()
        self.view = QTableView()
        self.view.setModel(self.model)
        self.view.verticalHeader().setVisible(False)
        self.view.horizontalHeader().setVisible(False)
        self.view.setMinimumSize(500, 200)
        self.view.setShowGrid(True)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)

        l = QVBoxLayout()

        l.addWidget(QLabel(_("Please select one or more template.")))
        self.view.doubleClicked.connect(self._doubleClicked)

        l.addWidget(QLabel(u"<h3>{}</h3>".format(_("Documents Templates"))))
        l.addWidget(self.view)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)
        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

        l.addWidget(self.buttons)

        self.setLayout(l)
Beispiel #2
0
    def __init__(self, parent):
        super(FilteredTable, self).__init__(parent)

        self.model = QStandardItemModel(600, 600)
        for i in range(self.model.rowCount()):
            for j in range(self.model.columnCount()):
                self.model.setData(self.model.index(i, j), str(i * j),
                                   Qt.DisplayRole)

        self.m = FilteringModel(self)
        self.m.setSourceModel(self.model)

        d = ['a'] * 300 + ['b'] * 200 + ['c'] * 99 + ['d']
        self.m.setIndexData(d)

        t = QTableView(self)
        t.setModel(self.m)

        self.line_in = QLineEdit(self)
        self.line_in.textChanged.connect(self.m.setFilterFixedString)

        l = QVBoxLayout()
        l.addWidget(self.line_in)
        l.addWidget(t)
        self.setLayout(l)
 def __init__(self):
     super(PhoneFrame, self).__init__()
     self.setWindowTitle('Phone Book.')
     self.name = QLineEdit()
     self.number = QLineEdit()
     entry = QFormLayout()
     entry.addRow(QLabel('Name'), self.name)
     entry.addRow(QLabel('Number'), self.number)
     buttons = QHBoxLayout()
     button = QPushButton('&Add')
     button.clicked.connect(self._addEntry)
     buttons.addWidget(button)
     button = QPushButton('&Update')
     button.clicked.connect(self._updateEntry)
     buttons.addWidget(button)
     button = QPushButton('&Delete')
     button.clicked.connect(self._deleteEntry)
     buttons.addWidget(button)
     dataDisplay = QTableView()
     dataDisplay.setModel(PhoneDataModel())
     layout = QVBoxLayout()
     layout.addLayout(entry)
     layout.addLayout(buttons)
     layout.addWidget(dataDisplay)
     self.setLayout(layout)
     self.show()
Beispiel #4
0
 def testSetModel(self):
     model = VirtualList()
     model._getItemCalled = False
     table = QTableView()
     table.setModel(model)
     table.show()
     self.assertFalse(model._getItemCalled)
Beispiel #5
0
class QuickOrderViewWidget(SubFrame):
    def __init__(self, parent):
        super(QuickOrderViewWidget, self).__init__("Quick view", None, parent)

        self._table_model = QStandardItemModel(1, 2, None)
        self.table_view = QTableView(self)
        self.table_view.setModel(self._table_model)
        self.layout().addWidget(self.table_view)

        self._table_model.setHorizontalHeaderLabels(
            ['Part Nr.', 'Description'])

        self.table_view.verticalHeader().hide()
        headers_view = self.table_view.horizontalHeader()
        headers_view.setResizeMode(0, QHeaderView.ResizeToContents)
        headers_view.setResizeMode(1, QHeaderView.Stretch)

    def selected_order(self, cur, prev):
        if cur.isValid():
            order_id = cur.model().index(cur.row(), 0).data(Qt.UserRole)

            self._table_model.removeRows(0, self._table_model.rowCount())
            row = 0
            for label, description in dao.order_dao.load_quick_view(order_id):
                self._table_model.appendRow(
                    [QStandardItem(label),
                     QStandardItem(description)])
Beispiel #6
0
    def super_keyPressEvent(self, event):
        """ Reimplemented to support edit, insert, and delete by keyboard.
        
            reimplmented to support no_update context manager.
        
        """
        editor = self._editor
        factory = editor.factory

        # Note that setting 'EditKeyPressed' as an edit trigger does not work on
        # most platforms, which is why we do this here.
        if (event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return) and
            self.state() != QAbstractItemView.EditingState and
            factory.editable and 'edit' in factory.operations):
            if factory.multi_select:
                rows = editor.multi_selected_rows
                row = rows[0] if len(rows) == 1 else -1
            else:
                row = editor.selected_row

            if row != -1:
                event.accept()
                self.edit(editor.model.index(row, 0))

        elif (event.key() in (QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Delete) and
              factory.editable and 'delete' in factory.operations):
            event.accept()
            '''
                sets _no_update and update_needed on the editor.object e.g
            
                editor.object== ExperimentQueue
                editor is editing ExperimentQueue.automated_runs
            
            '''

            with no_update(editor.object):
                if factory.multi_select:
                    for row in reversed(sorted(editor.multi_selected_rows)):
                        editor.model.removeRow(row)
                elif editor.selected_row != -1:
                    editor.model.removeRow(editor.selected_row)

        elif (event.key() == QtCore.Qt.Key_Insert and
              factory.editable and 'insert' in factory.operations):
            event.accept()

            if factory.multi_select:
                rows = sorted(editor.multi_selected_rows)
                row = rows[0] if len(rows) else -1
            else:
                row = editor.selected_row
            if row == -1:
                row = editor.adapter.len(editor.object, editor.name)
            editor.model.insertRow(row)
            self.setCurrentIndex(editor.model.index(row, 0))

        else:
            QTableView.keyPressEvent(self, event)
Beispiel #7
0
 def testReferreedObjectSurvivalAfterContextEnd(self):
     '''Model object assigned to a view object must survive after getting out of context.'''
     def createModelAndSetToView(view):
         model = TestModel()
         model.setObjectName('created model')
         view.setModel(model)
     view = QTableView()
     createModelAndSetToView(view)
     model = view.model()
 def testReferreedObjectSurvivalAfterContextEnd(self):
     '''Model object assigned to a view object must survive after getting out of context.'''
     def createModelAndSetToView(view):
         model = TestModel()
         model.setObjectName('created model')
         view.setModel(model)
     view = QTableView()
     createModelAndSetToView(view)
     model = view.model()
 def setupUi(self):
     centralWidget = QWidget(self)
     centralWidget.setLayout(QVBoxLayout(centralWidget))
     self.view = QTableView(centralWidget)
     self.view.setSortingEnabled(True)
     centralWidget.layout().addWidget(self.view)
     self.searchBox = QLineEdit(centralWidget)
     centralWidget.layout().addWidget(self.searchBox)
     self.setCentralWidget(centralWidget)
     self.searchBox.setFocus()
Beispiel #10
0
    def testReferenceCountingWhenDeletingReferrer(self):
        '''Tests reference count of model object referred by deceased view object.'''
        model = TestModel()
        refcount1 = getrefcount(model)
        view = QTableView()
        view.setModel(model)
        self.assertEqual(getrefcount(view.model()), refcount1 + 1)

        del view
        self.assertEqual(getrefcount(model), refcount1)
    def testReferenceCountingWhenDeletingReferrer(self):
        '''Tests reference count of model object referred by deceased view object.'''
        model = TestModel()
        refcount1 = getrefcount(model)
        view = QTableView()
        view.setModel(model)
        self.assertEqual(getrefcount(view.model()), refcount1 + 1)

        del view
        self.assertEqual(getrefcount(model), refcount1)
Beispiel #12
0
class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        
        
        self.layout = QVBoxLayout(self)
        
        self.grid = QTableView()
        self.grid.setModel(TaskTableModel(TaskView()))
        
        self.layout.addWidget(self.grid)
Beispiel #13
0
    def __init__(self,parent):
        global dao
        super(FindOrderDialog,self).__init__(parent)

        title = _("Find order")
        self.setWindowTitle(title)
        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title,self)
        top_layout.addWidget(self.title_widget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel(_("Search")))
        self.search_criteria = QLineEdit()
        self.search_criteria.setObjectName("search_criteria")
        hlayout.addWidget(self.search_criteria)
        top_layout.addLayout(hlayout)



        self.search_results_view = QTableView()

        self.headers_view = QHeaderView(Qt.Orientation.Horizontal)
        self.header_model = make_header_model([_("Preorder Nr"),_("Order Nr"),_("Customer Nr"),_("Customer"),_("Order Part")])
        self.headers_view.setModel(self.header_model) # qt's doc : The view does *not* take ownership (bt there's something with the selecion mode

        self.search_results_model = QStandardItemModel()
        self.search_results_view.setModel(self.search_results_model)

        self.search_results_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.search_results_view.setHorizontalHeader(self.headers_view)
        self.search_results_view.verticalHeader().hide()
        # self.search_results_view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
        self.search_results_view.horizontalHeader().setResizeMode(3, QHeaderView.Stretch)
        self.search_results_view.horizontalHeader().setResizeMode(4, QHeaderView.Stretch)

        self.search_results_view.setSelectionBehavior(QAbstractItemView.SelectRows)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton( QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton( QDialogButtonBox.Ok)
        self.buttons.button(QDialogButtonBox.Ok).setObjectName("go_search")

        top_layout.addWidget(self.search_results_view)
        top_layout.setStretch(2,1000)
        top_layout.addWidget(self.buttons)
        self.setLayout(top_layout)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.search_results_view.activated.connect(self.row_activated)
        self.search_criteria.returnPressed.connect(self.search_criteria_submitted)

        self.setMinimumSize(800,640)
Beispiel #14
0
class MainWindow(QWidget):
    
    def __init__(self):
        QWidget.__init__(self)
        self.resize(640, 480)
        vbox = QVBoxLayout()
        self.setWindowTitle('TableDemo')
        self.setLayout(vbox)
        self.table = QTableView()
        self.table.setAlternatingRowColors(True)
        self.table.setSortingEnabled(True)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        cards = [Card(u'巫医', u'战吼:恢复2点生命值。', 1, 2, 1), 
                 Card(u'狼骑兵', u'冲锋', 3, 3, 1),
                 Card(u'石牙野猪', u'冲锋', 1, 1, 1),
                 Card(u'森金持盾卫士', u'嘲讽', 4, 3, 5),
                ]
        cardModel = CardModel(cards)
        sortModel = QSortFilterProxyModel()
        sortModel.setSourceModel(cardModel)
        self.table.setModel(sortModel)
        vbox.addWidget(self.table)
        
    def printItem(self, idx):
        print idx.model().persons[idx.row()]
Beispiel #15
0
    def __init__(self, parent):
        super(QuickOrderViewWidget, self).__init__("Quick view", None, parent)

        self._table_model = QStandardItemModel(1, 2, None)
        self.table_view = QTableView(self)
        self.table_view.setModel(self._table_model)
        self.layout().addWidget(self.table_view)

        self._table_model.setHorizontalHeaderLabels(
            ['Part Nr.', 'Description'])

        self.table_view.verticalHeader().hide()
        headers_view = self.table_view.horizontalHeader()
        headers_view.setResizeMode(0, QHeaderView.ResizeToContents)
        headers_view.setResizeMode(1, QHeaderView.Stretch)
def test_database_view(qtbot, session):
    session.add(Person(name="Roger Milla"))
    session.add(Person(name="François Biyik"))
    session.add(Person(name="Salvatore Schillaci"))
    session.commit()

    persons = DatabaseObjectModel(Person, session)
    persons.addAttributeColumn("name", "Name")
    assert persons.data(ModelIndexDuck(0, 0), Qt.DisplayRole) == "Roger Milla"

    view = QTableView()
    view.setModel(persons)
    persons.appendObject(Person(name="Claudio Cannigia"))
    persons.removeObject(0)
    qtbot.addWidget(view)
    view.show()
    def __init__(self, parameter, parent=None):
        _ParameterWidget.__init__(self, parameter, parent)

        # Variables
        model = _LayerModel()
        self._material_class = Material

        # Actions
        act_add = QAction(getIcon("list-add"), "Add layer", self)
        act_remove = QAction(getIcon("list-remove"), "Remove layer", self)
        act_clean = QAction(getIcon('edit-clear'), "Clear", self)

        # Widgets
        self._cb_unit = UnitComboBox('m')
        self._cb_unit.setUnit('um')

        self._tbl_layers = QTableView()
        self._tbl_layers.setModel(model)
        self._tbl_layers.setItemDelegate(_LayerDelegate())
        header = self._tbl_layers.horizontalHeader()
        header.setResizeMode(QHeaderView.Stretch)
        header.setStyleSheet('color: blue')

        self._tlb_layers = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._tlb_layers.addWidget(spacer)
        self._tlb_layers.addAction(act_add)
        self._tlb_layers.addAction(act_remove)
        self._tlb_layers.addAction(act_clean)

        # Layouts
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(QLabel('Thickness unit'))
        sublayout.addWidget(self._cb_unit)
        layout.addLayout(sublayout)

        layout.addWidget(self._tbl_layers)
        layout.addWidget(self._tlb_layers)
        self.setLayout(layout)

        # Signals
        self.valuesChanged.connect(self._onChanged)
        self.validationRequested.connect(self._onChanged)

        act_add.triggered.connect(self._onAdd)
        act_remove.triggered.connect(self._onRemove)
        act_clean.triggered.connect(self._onClear)

        self._tbl_layers.doubleClicked.connect(self._onDoubleClicked)

        model.dataChanged.connect(self.valuesChanged)
        model.rowsInserted.connect(self.valuesChanged)
        model.rowsRemoved.connect(self.valuesChanged)

        self.validationRequested.emit()
Beispiel #18
0
    def __init__(self, table_model, _completerSetupFunction=None, *args):
        QWidget.__init__(self, *args)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(300, 200, 570, 450)
        self.setWindowTitle("QTableView + completer example")
        table_view = QTableView()
        table_view.setModel(table_model)
        # set column width to fit contents (set font first!)
        table_view.resizeColumnsToContents()
        table_view.resizeRowsToContents()
        
        if _completerSetupFunction is not None:
            delegate = CompleterDelegate(table_view, _completerSetupFunction)
            table_view.setItemDelegateForColumn(1, delegate)            

        layout = QVBoxLayout(self)
        layout.addWidget(table_view)
        self.setLayout(layout)
Beispiel #19
0
    def __init__(self):

        QTableView.__init__(self)

        self.__configer = get_config()

        # 拉申最后一列
        self.horizontalHeader().setStretchLastSection(True)

        # ...
        self.resizeColumnToContents(True)

        # 不显示格间距
        self.setShowGrid(False)

        self.alternatingRowColors()

        self.setStyleSheet(get_theme("TableView"))
 def setupUi(self):
     centralWidget = QWidget(self)
     centralWidget.setLayout(QVBoxLayout(centralWidget))
     self.view = QTableView(centralWidget)
     self.view.setSortingEnabled(True)
     centralWidget.layout().addWidget(self.view)
     self.searchBox = QLineEdit(centralWidget)
     centralWidget.layout().addWidget(self.searchBox)
     self.setCentralWidget(centralWidget)
     self.searchBox.setFocus()
class MainWindow(QMainWindow):

    COLUMNS = ['Name', 'Comment']

    ITEMS = [
        ('Ford', "Don't panic"),
        ('Marvin', "I'm feeling so depressed")
    ]

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi()
        # setup a sample model
        self.model = QStandardItemModel(self)
        self.model.setHorizontalHeaderLabels(self.COLUMNS)
        for row, item in enumerate(self.ITEMS):
            for column, cell in enumerate(item):
                self.model.setItem(row, column, QStandardItem(cell))
        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.model)
        # filter all columns (use 0, 1, etc. to only filter by a specific column)
        self.proxy.setFilterKeyColumn(-1)
        # filter text case insensitively
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.view.setModel(self.proxy)
        for column, _ in enumerate(self.COLUMNS):
            self.view.resizeColumnToContents(column)
        self.searchBox.textChanged.connect(self.updateFilter)

    def updateFilter(self, text):
        self.proxy.setFilterFixedString(text)

    def setupUi(self):
        centralWidget = QWidget(self)
        centralWidget.setLayout(QVBoxLayout(centralWidget))
        self.view = QTableView(centralWidget)
        self.view.setSortingEnabled(True)
        centralWidget.layout().addWidget(self.view)
        self.searchBox = QLineEdit(centralWidget)
        centralWidget.layout().addWidget(self.searchBox)
        self.setCentralWidget(centralWidget)
        self.searchBox.setFocus()
    def setup_ui(self):
        splitter = QSplitter(self)
        left = QWidget(splitter)
        left.setLayout(QVBoxLayout(left))
        left.layout().addWidget(QLabel('QTableView', left))
        tableview = QTableView(left)
        tableview.setModel(TableModel(tableview))
        left.layout().addWidget(tableview)
        splitter.addWidget(left)
        right = QWidget(splitter)
        right.setLayout(QVBoxLayout(right))
        right.layout().addWidget(QLabel('QTableWidget', right))
        # create a table widget for DATA
        tablewidget = QTableWidget(len(DATA), len(DATA[1]), right)
        right.layout().addWidget(tablewidget)
        splitter.addWidget(right)
        self.setCentralWidget(splitter)

        # add tablewidget data
        self.add_data(tablewidget)
    def setup_ui(self):
        splitter = QSplitter(self)
        left = QWidget(splitter)
        left.setLayout(QVBoxLayout(left))
        left.layout().addWidget(QLabel('QTableView', left))
        tableview = QTableView(left)
        tableview.setModel(TableModel(tableview))
        left.layout().addWidget(tableview)
        splitter.addWidget(left)
        right = QWidget(splitter)
        right.setLayout(QVBoxLayout(right))
        right.layout().addWidget(QLabel('QTableWidget', right))
        # create a table widget for DATA
        tablewidget = QTableWidget(len(DATA), len(DATA[1]), right)
        right.layout().addWidget(tablewidget)
        splitter.addWidget(right)
        self.setCentralWidget(splitter)

        # add tablewidget data
        self.add_data(tablewidget)
Beispiel #24
0
    def __init__(self):
        super(Blew, self).__init__()
        self.setWindowModality(Qt.NonModal)
        self.setWindowFlags(
            Qt.FramelessWindowHint)  # Qt.Tool | Qt.FramelessWindowHint

        l = QHBoxLayout()
        self.items_view = QTableView()

        # Make the dropdown nice
        l.setContentsMargins(0, 0, 0, 0)
        self.items_view.horizontalHeader().setStretchLastSection(True)
        self.items_view.horizontalHeader().hide()
        self.items_view.verticalHeader().hide()
        self.items_view.setShowGrid(False)
        self.setMinimumSize(300, 100)

        self.model = QuickComboModel(self)
        self.items_view.setModel(self.model)
        l.addWidget(self.items_view)
        self.setLayout(l)
Beispiel #25
0
 def testSetModel(self):
     model = VirtualList()
     model._getItemCalled = False
     table = QTableView()
     table.setModel(model)
     table.show()
     self.assertFalse(model._getItemCalled)
Beispiel #26
0
 def __init__(self, parent=None):
     super(MainWindow, self).__init__(parent)
     database = QSqlDatabase.addDatabase('QSQLITE')
     database.setDatabaseName(
         'astatsscraper.db')  # Better lookup logic needed
     if not database.open():
         print('Error opening database!')
     model = QSqlTableModel(db=database)
     model.setTable('steam_apps')
     table = QTableView()
     table.setEditTriggers(QAbstractItemView.NoEditTriggers)
     table.setModel(model)
     self.setCentralWidget(table)
     table.show()
Beispiel #27
0
    def _initUI(self):
        # Variables
        self._widgets = {}
        tbl_model = self._LimitTableModel()

        # Widgets
        self._cb_limit = QComboBox()
        self._cb_limit.setModel(self._LimitComboBoxModel())

        btn_limit_add = QPushButton()
        btn_limit_add.setIcon(getIcon("list-add"))

        self._tbl_limit = QTableView()
        self._tbl_limit.setModel(tbl_model)
        self._tbl_limit.setItemDelegate(self._LimitTableDelegate())
        header = self._tbl_limit.horizontalHeader()
        header.setResizeMode(QHeaderView.Stretch)
        header.hide()
        policy = self._tbl_limit.sizePolicy()
        policy.setVerticalStretch(True)
        self._tbl_limit.setSizePolicy(policy)

        tlb_limit = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_limit.addWidget(spacer)
        act_remove = tlb_limit.addAction(getIcon("list-remove"), "Remove limit")
        act_clear = tlb_limit.addAction(getIcon("edit-clear"), "Clear")

        # Layouts
        layout = _ExpandableOptionsWizardPage._initUI(self)

        sublayout = QHBoxLayout()
        sublayout.addWidget(self._cb_limit, 1)
        sublayout.addWidget(btn_limit_add)
        layout.addRow("Select", sublayout)

        layout.addRow(self._tbl_limit)
        layout.addRow(tlb_limit)

        # Signals
        btn_limit_add.released.connect(self._onLimitAdd)
        act_remove.triggered.connect(self._onLimitRemove)
        act_clear.triggered.connect(self._onLimitClear)

        self._tbl_limit.doubleClicked.connect(self._onLimitDoubleClicked)

        tbl_model.dataChanged.connect(self.valueChanged)
        tbl_model.rowsInserted.connect(self.valueChanged)
        tbl_model.rowsRemoved.connect(self.valueChanged)

        return layout
Beispiel #28
0
class MainWindow(QMainWindow):

    COLUMNS = ['Name', 'Comment']

    ITEMS = [('Ford', "Don't panic"), ('Marvin', "I'm feeling so depressed")]

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi()
        # setup a sample model
        self.model = QStandardItemModel(self)
        self.model.setHorizontalHeaderLabels(self.COLUMNS)
        for row, item in enumerate(self.ITEMS):
            for column, cell in enumerate(item):
                self.model.setItem(row, column, QStandardItem(cell))
        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.model)
        # filter all columns (use 0, 1, etc. to only filter by a specific column)
        self.proxy.setFilterKeyColumn(-1)
        # filter text case insensitively
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.view.setModel(self.proxy)
        for column, _ in enumerate(self.COLUMNS):
            self.view.resizeColumnToContents(column)
        self.searchBox.textChanged.connect(self.updateFilter)

    def updateFilter(self, text):
        self.proxy.setFilterFixedString(text)

    def setupUi(self):
        centralWidget = QWidget(self)
        centralWidget.setLayout(QVBoxLayout(centralWidget))
        self.view = QTableView(centralWidget)
        self.view.setSortingEnabled(True)
        centralWidget.layout().addWidget(self.view)
        self.searchBox = QLineEdit(centralWidget)
        centralWidget.layout().addWidget(self.searchBox)
        self.setCentralWidget(centralWidget)
        self.searchBox.setFocus()
Beispiel #29
0
 def __init__(self, parent=None):
     super(MainWindow, self).__init__(parent)
     database = QSqlDatabase.addDatabase('QSQLITE')
     database.setDatabaseName('astatsscraper.db') # Better lookup logic needed
     if not database.open():
         print('Error opening database!')
     model = QSqlTableModel(db=database)
     model.setTable('steam_apps')
     table = QTableView()
     table.setEditTriggers(QAbstractItemView.NoEditTriggers)
     table.setModel(model)
     self.setCentralWidget(table)
     table.show()
    def _initUI(self):
        # Widgets
        self._tbl_warnings = QTableView()
        self._tbl_warnings.setModel(self._WarningTableModel())
        header = self._tbl_warnings.horizontalHeader()
        header.setResizeMode(1, QHeaderView.Stretch)
        policy = self._tbl_warnings.sizePolicy()
        policy.setVerticalStretch(True)
        self._tbl_warnings.setSizePolicy(policy)

        # Layouts
        layout = _OptionsWizardPage._initUI(self)
        layout.addRow(self._tbl_warnings)

        return layout
Beispiel #31
0
    def _init_gui(self):
        self._widget = QSplitter(self, Qt.Horizontal)
        self._hierarchy_view = QTreeView(self._widget)
        self._details_view = QTableView(self._widget)

        self._widget.addWidget(self._hierarchy_view)
        self._widget.addWidget(self._details_view)
        self._widget.setStretchFactor(0, 2)
        self._widget.setStretchFactor(1, 1)
        self.setCentralWidget(self._widget)

        self._hierarchy_view.setModel(self._hierarchy_model)
        self._details_view.setModel(self._details_model)

        self._hierarchy_view.expanded.connect(self._mo_item_expand)
Beispiel #32
0
    def _initUI(self):
        # Variables
        model = _PhotonIntensityResultTableModel(self.result())

        # Widgets
        self._table = QTableView()
        self._table.setModel(model)
        header = self._table.horizontalHeader()
        for i in range(1, 9):
            header.setResizeMode(i, QHeaderView.Stretch)

        # Layouts
        layout = _SaveableResultWidget._initUI(self)
        layout.addWidget(self._table)

        return layout
Beispiel #33
0
	def searchTab(self):

		# sFileModel + view tab
		self.sFileTable = QTableView()
		self.sFileTable.setModel(self.sFileModel)
		self.sFileTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
		self.sFileTable.setSelectionBehavior(QAbstractItemView.SelectRows)

		self.setColumnsWidths(self.sFileTable)

		self.searchWidget = QWidget()

		# Horizontal layout
		# Button, Line Edit, Button
		hLayout = QHBoxLayout()
		self.searchBox = QLineEdit()
		self.searchBox.returnPressed.connect(self.searchdb)
		hLayout.addWidget(self.searchBox)

		searchBtn = QPushButton("Search")
		searchBtn.clicked.connect(self.searchdb)
		hLayout.addWidget(searchBtn)

		# Vertical Layout
		vLayout = QVBoxLayout()
		vLayout.addLayout(hLayout)
		vLayout.addWidget(self.sFileTable)

		# sub horiz box
		subHLayout = QHBoxLayout()
		subHLayout.addStretch(1)
		
		editBtn = QPushButton("Edit -->")
		editBtn.clicked.connect(self.addToEditTab)

		subHLayout.addWidget(editBtn)
		vLayout.addLayout(subHLayout)

		self.searchWidget.setLayout(vLayout)
		self.tabWidget.addTab(self.searchWidget, u"Retrieve")
Beispiel #34
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        # Variables
        model = self._ModelTableModel()

        # Widgets
        self._tbl_models = QTableView()
        self._tbl_models.setModel(model)
        header = self._tbl_models.horizontalHeader()
        header.setResizeMode(QHeaderView.Stretch)
        policy = self._tbl_models.sizePolicy()
        policy.setVerticalStretch(True)
        self._tbl_models.setSizePolicy(policy)
        self._tbl_models.setSelectionMode(QTableView.SelectionMode.MultiSelection)

        # Layouts
        layout = QVBoxLayout()
        layout.addWidget(self._tbl_models)
        self.setLayout(layout)

        # Signals
        model.dataChanged.connect(self.dataChanged)
Beispiel #35
0
	def editTab(self):
		
		self.eFileTable = QTableView()
		self.eFileTable.setModel(self.eFileModel)
		self.eFileTable.setSelectionBehavior(QAbstractItemView.SelectRows)

		self.setColumnsWidths(self.eFileTable)

		self.editWidget = QWidget()

		vLayout = QVBoxLayout()
		vLayout.addWidget(self.eFileTable)

		dropBtn = QToolButton()
		dropBtn.setDefaultAction(self.dropEditTabAct)

		undBtn = QPushButton("Undo Delete")
		undBtn.clicked.connect(self.undeleteFiles)

		rmvBtn = QPushButton("Delete")
		rmvBtn.clicked.connect(self.deleteFiles)

		cmtBtn = QPushButton("Update")
		cmtBtn.clicked.connect(self.update)

		hLayout = QHBoxLayout()
		hLayout.addWidget(dropBtn)
		hLayout.addStretch(1)
		hLayout.addWidget(undBtn)
		hLayout.addWidget(rmvBtn)
		hLayout.addWidget(cmtBtn)

		vLayout.addLayout(hLayout)

		self.editWidget.setLayout(vLayout)

		self.tabWidget.addTab(self.editWidget, u"Edit")
Beispiel #36
0
 def __init__(self, dataModel, oberTablo):
     QDialog.__init__(self)
     self.setWindowTitle('All Skills')
     self.setWindowIcon(QIcon('elance.ico'))
     self.oberTablo = oberTablo
     #create & configure tablewiew
     self.table_view = QTableView()
     self.table_view.setModel(dataModel)
     self.table_view.setSortingEnabled(True)
     self.table_view.sortByColumn(1, Qt.DescendingOrder)
     self.table_view.resizeColumnsToContents()
     self.table_view.resizeRowsToContents()
     #http://stackoverflow.com/questions/7189305/set-optimal-size-of-a-dialog-window-containing-a-tablewidget
     #http://stackoverflow.com/questions/8766633/how-to-determine-the-correct-size-of-a-qtablewidget
     w = 0
     w += self.table_view.contentsMargins().left() +\
          self.table_view.contentsMargins().right() +\
          self.table_view.verticalHeader().width()
     w += qApp.style().pixelMetric(QStyle.PM_ScrollBarExtent)
     for i in range(len(self.table_view.model().header)):
         w += self.table_view.columnWidth(i)
     self.table_view.horizontalHeader().setStretchLastSection(True)
     self.table_view.setMinimumWidth(w)
     
     # create two buttons
     self.findEntries = QPushButton('Find entries')
     self.findEntries.clicked.connect(self.ApplyFilterToMainList)
     self.cancel = QPushButton('Cancel')
     self.cancel.clicked.connect(self.winClose)
     
     self.mainLayout = QGridLayout()
     self.mainLayout.addWidget(self.table_view, 0,0,1,3)
     self.mainLayout.addWidget(self.findEntries, 1,0)
     self.mainLayout.addWidget(self.cancel, 1,2)
     self.setLayout(self.mainLayout)
     self.show()
Beispiel #37
0
	def addTab(self):

		self.aFileTable = QTableView()
		self.aFileTable.setModel(self.aFileModel)
		self.aFileTable.setSelectionBehavior(QAbstractItemView.SelectRows)

		self.setColumnsWidths(self.aFileTable)

		self.addWidget = QWidget()

		vLayout = QVBoxLayout()
		vLayout.addWidget(self.aFileTable)

		addBtn = QToolButton()
		addBtn.setDefaultAction(self.findAct)
		# addBtn.clicked.connect(self.findFilesDlg)

		dropBtn = QToolButton()
		dropBtn.setDefaultAction(self.dropAddTabAct)
		# rmvBtn.clicked.connect(self.rmvFiles)

		insBtn = QPushButton("Track")
		insBtn.clicked.connect(self.insert)

		hLayout = QHBoxLayout()

		hLayout.addWidget(addBtn)
		hLayout.addWidget(dropBtn)
		hLayout.addStretch(1)		
		hLayout.addWidget(insBtn)

		vLayout.addLayout(hLayout)

		self.addWidget.setLayout(vLayout)

		self.tabWidget.addTab(self.addWidget, u"Add")
Beispiel #38
0
class RunnerDialog(QDialog):

    options_added = Signal(Options)
    options_running = Signal(Options)
    options_simulated = Signal(Options)
    options_error = Signal(Options, Exception)
    results_saved = Signal(Results, str)
    results_error = Signal(Results, Exception)

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle('Runner')
        self.setMinimumWidth(750)

        # Runner
        self._runner = None

        self._running_timer = QTimer()
        self._running_timer.setInterval(500)

        # Widgets
        self._dlg_progress = QProgressDialog()
        self._dlg_progress.setRange(0, 100)
        self._dlg_progress.setModal(True)
        self._dlg_progress.hide()

        lbl_outputdir = QLabel("Output directory")
        self._txt_outputdir = DirBrowseWidget()

        max_workers = cpu_count() #@UndefinedVariable
        lbl_workers = QLabel('Number of workers')
        self._spn_workers = QSpinBox()
        self._spn_workers.setRange(1, max_workers)
        self._spn_workers.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        lbl_max_workers = QLabel('(max: %i)' % max_workers)

        self._chk_overwrite = QCheckBox("Overwrite existing results in output directory")
        self._chk_overwrite.setChecked(True)

        self._lbl_available = QLabel('Available')
        self._lst_available = QListView()
        self._lst_available.setModel(_AvailableOptionsListModel())
        self._lst_available.setSelectionMode(QListView.SelectionMode.MultiSelection)

        tlb_available = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_available.addWidget(spacer)
        act_open = tlb_available.addAction(getIcon("document-open"), "Open")
        act_open.setShortcut(QKeySequence.Open)
        tlb_available.addSeparator()
        act_remove = tlb_available.addAction(getIcon("list-remove"), "Remove")
        act_clear = tlb_available.addAction(getIcon("edit-clear"), "Clear")

        self._btn_addtoqueue = QPushButton(getIcon("go-next"), "")
        self._btn_addtoqueue.setToolTip("Add to queue")
        self._btn_addtoqueue.setEnabled(False)

        self._btn_addalltoqueue = QPushButton(getIcon("go-last"), "")
        self._btn_addalltoqueue.setToolTip("Add all to queue")
        self._btn_addalltoqueue.setEnabled(False)

        self._lbl_options = QLabel('Queued/Running/Completed')
        self._tbl_options = QTableView()
        self._tbl_options.setModel(_StateOptionsTableModel())
        self._tbl_options.setItemDelegate(_StateOptionsItemDelegate())
        self._tbl_options.setSelectionMode(QListView.SelectionMode.NoSelection)
        self._tbl_options.setColumnWidth(1, 60)
        self._tbl_options.setColumnWidth(2, 80)
        header = self._tbl_options.horizontalHeader()
        header.setResizeMode(0, QHeaderView.Interactive)
        header.setResizeMode(1, QHeaderView.Fixed)
        header.setResizeMode(2, QHeaderView.Fixed)
        header.setResizeMode(3, QHeaderView.Stretch)

        self._btn_start = QPushButton(getIcon("media-playback-start"), "Start")

        self._btn_cancel = QPushButton("Cancel")
        self._btn_cancel.setEnabled(False)

        self._btn_close = QPushButton("Close")

        self._btn_import = QPushButton("Import")
        self._btn_import.setEnabled(False)

        # Layouts
        layout = QVBoxLayout()

        sublayout = QGridLayout()
        sublayout.addWidget(lbl_outputdir, 0, 0)
        sublayout.addWidget(self._txt_outputdir, 0, 1)
        sublayout.addWidget(lbl_workers, 1, 0)

        subsublayout = QHBoxLayout()
        subsublayout.addWidget(self._spn_workers)
        subsublayout.addWidget(lbl_max_workers)
        sublayout.addLayout(subsublayout, 1, 1)
        layout.addLayout(sublayout)

        sublayout.addWidget(self._chk_overwrite, 2, 0, 1, 3)

        sublayout = QGridLayout()
        sublayout.setColumnStretch(0, 1)
        sublayout.setColumnStretch(2, 3)
        sublayout.addWidget(self._lbl_available, 0, 0)
        sublayout.addWidget(self._lst_available, 1, 0)
        sublayout.addWidget(tlb_available, 2, 0)

        subsublayout = QVBoxLayout()
        subsublayout.addStretch()
        subsublayout.addWidget(self._btn_addtoqueue)
        subsublayout.addWidget(self._btn_addalltoqueue)
        subsublayout.addStretch()
        sublayout.addLayout(subsublayout, 1, 1)

        sublayout.addWidget(self._lbl_options, 0, 2)
        sublayout.addWidget(self._tbl_options, 1, 2)
        layout.addLayout(sublayout)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(self._btn_import)
        sublayout.addWidget(self._btn_start)
        sublayout.addWidget(self._btn_cancel)
        sublayout.addWidget(self._btn_close)
        layout.addLayout(sublayout)

        self.setLayout(layout)

        # Signal
        self._running_timer.timeout.connect(self._onRunningTimer)

        act_open.triggered.connect(self._onOpen)
        act_remove.triggered.connect(self._onRemove)
        act_clear.triggered.connect(self._onClear)

        self._btn_addtoqueue.released.connect(self._onAddToQueue)
        self._btn_addalltoqueue.released.connect(self._onAddAllToQueue)
        self._btn_start.released.connect(self._onStart)
        self._btn_cancel.released.connect(self._onCancel)
        self._btn_close.released.connect(self._onClose)
        self._btn_import.released.connect(self._onImport)

        self.options_added.connect(self._onOptionsAdded)
        self.options_running.connect(self._onOptionsRunning)
        self.options_simulated.connect(self._onOptionsSimulated)
        self.options_error.connect(self._onOptionsError)
        self.results_error.connect(self._onResultsError)

        # Defaults
        settings = get_settings()
        section = settings.add_section('gui')
        if hasattr(section, 'outputdir'):
            self._txt_outputdir.setPath(section.outputdir)
        if hasattr(section, 'maxworkers'):
            self._spn_workers.setValue(int(section.maxworkers))
        if hasattr(section, 'overwrite'):
            state = True if section.overwrite.lower() == 'true' else False
            self._chk_overwrite.setChecked(state)

    def _onDialogProgressProgress(self, progress, status):
        self._dlg_progress.setValue(progress * 100)
        self._dlg_progress.setLabelText(status)

    def _onDialogProgressCancel(self):
        self._dlg_progress.hide()
        if self._options_reader_thread is None:
            return
        self._options_reader_thread.cancel()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()

    def _onDialogProgressException(self, ex):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        messagebox.exception(self, ex)

    def _onRunningTimer(self):
        self._tbl_options.model().reset()

    def _onOpen(self):
        settings = get_settings()
        curdir = getattr(settings.gui, 'opendir', os.getcwd())

        filepath, namefilter = \
            QFileDialog.getOpenFileName(self, "Open", curdir,
                                        'Options [*.xml] (*.xml)')

        if not filepath or not namefilter:
            return
        settings.gui.opendir = os.path.dirname(filepath)

        if not filepath.endswith('.xml'):
            filepath += '.xml'

        self._options_reader_thread = _OptionsReaderWrapperThread(filepath)
        self._dlg_progress.canceled.connect(self._onDialogProgressCancel)
        self._options_reader_thread.resultReady.connect(self._onOpened)
        self._options_reader_thread.progressUpdated.connect(self._onDialogProgressProgress)
        self._options_reader_thread.exceptionRaised.connect(self._onDialogProgressException)
        self._options_reader_thread.start()

        self._dlg_progress.reset()
        self._dlg_progress.show()

    def _onOpened(self, options):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        self._options_reader_thread = None

        try:
            self._lst_available.model().addOptions(options)
        except Exception as ex:
            messagebox.exception(self, ex)

    def _onRemove(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.popOptions(row)

    def _onClear(self):
        self._lst_available.model().clearOptions()

    def _onAddToQueue(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onAddAllToQueue(self):
        model = self._lst_available.model()
        for row in reversed(range(0, model.rowCount())):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onStart(self):
        outputdir = self._txt_outputdir.path()
        if not outputdir:
            QMessageBox.critical(self, 'Start', 'Missing output directory')
            return
        max_workers = self._spn_workers.value()
        overwrite = self._chk_overwrite.isChecked()
        self.start(outputdir, overwrite, max_workers)

    def _onCancel(self):
        self.cancel()

    def _onClose(self):
        if self._runner is not None:
            self._runner.close()
        self._running_timer.stop()
        self.close()

    def _onImport(self):
        list_options = self._lst_available.model().listOptions()
        if not list_options:
            return

        # Select options
        dialog = _OptionsSelector(list_options)
        if not dialog.exec_():
            return
        options = dialog.options()

        # Start importer
        outputdir = self._runner.outputdir
        max_workers = self._runner.max_workers
        importer = LocalImporter(outputdir, max_workers)

        importer.start()
        importer.put(options)

        self._dlg_progress.show()
        try:
            while importer.is_alive():
                if self._dlg_progress.wasCanceled():
                    importer.cancel()
                    break
                self._dlg_progress.setValue(importer.progress * 100)
        finally:
            self._dlg_progress.hide()

    def _onOptionsAdded(self, options):
        logging.debug('runner: optionsAdded')
        self._tbl_options.model().addOptions(options)

    def _onOptionsRunning(self, options):
        logging.debug('runner: optionsRunning')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsSimulated(self, options):
        logging.debug('runner: optionsSimulated')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsError(self, options, ex):
        logging.debug('runner: optionsError')
        self._tbl_options.model().resetOptions(options)

    def _onResultsError(self, results, ex):
        logging.debug('runner: resultsError')
        self._tbl_options.model().reset()

    def closeEvent(self, event):
        if self.is_running():
            message = 'Runner is running. Do you want to continue?'
            answer = QMessageBox.question(self, 'Runner', message,
                                          QMessageBox.Yes | QMessageBox.No)
            if answer == QMessageBox.No:
                event.ignore()
                return

        self.cancel()
        self._dlg_progress.close()

        settings = get_settings()
        section = settings.add_section('gui')

        path = self._txt_outputdir.path()
        if path:
            section.outputdir = path
        section.maxworkers = str(self._spn_workers.value())
        section.overwrite = str(self._chk_overwrite.isChecked())

        settings.write()

        event.accept()

    def addAvailableOptions(self, options):
        self._lst_available.model().addOptions(options)

    def removeAvailableOptions(self, options):
        self._lst_available.model().removeOptions(options)

    def clearAvailableOptions(self):
        self._lbl_available.model().clearOptions()

    def start(self, outputdir, overwrite, max_workers):
        self._runner = LocalRunner(outputdir=outputdir,
                                   overwrite=overwrite,
                                   max_workers=max_workers)

        self._tbl_options.setModel(_StateOptionsTableModel(self._runner))

        self._spn_workers.setEnabled(False)
        self._txt_outputdir.setEnabled(False)
        self._chk_overwrite.setEnabled(False)
        self._btn_addtoqueue.setEnabled(True)
        self._btn_addalltoqueue.setEnabled(True)
        self._btn_start.setEnabled(False)
        self._btn_cancel.setEnabled(True)
        self._btn_close.setEnabled(False)
        self._btn_import.setEnabled(True)

        self._runner.options_added.connect(self.options_added.emit)
        self._runner.options_running.connect(self.options_running.emit)
        self._runner.options_simulated.connect(self.options_simulated.emit)
        self._runner.options_error.connect(self.options_error.emit)
        self._runner.results_saved.connect(self.results_saved.emit)
        self._runner.results_error.connect(self.results_error.emit)

        self._running_timer.start()
        self._runner.start()

    def cancel(self):
        if self._runner is None:
            return
        self._runner.cancel()
        self._running_timer.stop()

        self._runner.options_added.disconnect(self.options_added.emit)
        self._runner.options_running.disconnect(self.options_running.emit)
        self._runner.options_simulated.disconnect(self.options_simulated.emit)
        self._runner.options_error.disconnect(self.options_error.emit)
        self._runner.results_saved.disconnect(self.results_saved.emit)
        self._runner.results_error.disconnect(self.results_error.emit)

        self._runner = None

        self._spn_workers.setEnabled(True)
        self._txt_outputdir.setEnabled(True)
        self._chk_overwrite.setEnabled(True)
        self._btn_addtoqueue.setEnabled(False)
        self._btn_addalltoqueue.setEnabled(False)
        self._btn_start.setEnabled(True)
        self._btn_cancel.setEnabled(False)
        self._btn_close.setEnabled(True)
        self._btn_import.setEnabled(False)

    def is_running(self):
        return self._runner is not None and self._runner.is_alive()
 def __init__(self, parent=None):
     QTableView.__init__(self, parent)
     self.auto_resize_columns = False
Beispiel #40
0
class BrowserWindow(QMainWindow):

    MO_ROLE = Qt.UserRole+1

    def __init__(self, conn):
        super(BrowserWindow, self).__init__()
        self._conn = conn
        self._resolver = AsyncResolver()
        self._resolver.object_resolved.connect(self._data_resolved)
        self._resolver.start()
        self._init_models()
        self._init_gui()
        self._init_data()
        self._init_connections()

    def __del__(self):
        self._resolver.stop_work()
        self._resolver.terminate()

    def _init_models(self):
        self._hierarchy_model = QStandardItemModel()
        self._hierarchy_model.setColumnCount(2)
        self._hierarchy_model.setHorizontalHeaderLabels(['class', 'dn'])
        self._details_model = QStandardItemModel()
        self._details_model.setColumnCount(2)
        self._details_model.setHorizontalHeaderLabels(['Property', 'Value'])

    def _init_gui(self):
        self._widget = QSplitter(self, Qt.Horizontal)
        self._hierarchy_view = QTreeView(self._widget)
        self._details_view = QTableView(self._widget)

        self._widget.addWidget(self._hierarchy_view)
        self._widget.addWidget(self._details_view)
        self._widget.setStretchFactor(0, 2)
        self._widget.setStretchFactor(1, 1)
        self.setCentralWidget(self._widget)

        self._hierarchy_view.setModel(self._hierarchy_model)
        self._details_view.setModel(self._details_model)

        self._hierarchy_view.expanded.connect(self._mo_item_expand)

    def _init_data(self):
        item = self._row_for_mo(self._conn.resolve_dn(''))
        self._hierarchy_model.insertRow(0, item)

    def _init_connections(self):
        self.connect(self._resolver,
                        SIGNAL('object_resolved(QVariant)'),
                     self,
                        SLOT('_data_resolved(QVariant)'))
        self._hierarchy_view.activated.connect(self._item_activated)
        #self.connect(self._hierarchy_view.selectionModel(),
        #                SIGNAL('currentChanged(QModelIndex,QModelIndex)'),
        #             self,
        #                SLOT('_current_changed(QModelIndex, QModelIndex)'))
        self.connect(self._hierarchy_view.selectionModel(),
                        SIGNAL('activated(QModelIndex)'),
                     self,
                        SLOT('_item_activated(QModelIndex)'))


    def _row_for_mo(self, mo):
        row = [QStandardItem(mo.ucs_class), QStandardItem(mo.dn)]
        for item in row:
            item.setEditable(False)
        row[0].appendColumn([QStandardItem('Loading...')])
        row[0].setData(mo, self.MO_ROLE)
        return row

    def _add_mo_in_tree(self, mo, index=QtCore.QModelIndex()):
        item = None
        if index.isValid():
            item = self._hierarchy_model.itemFromIndex(index)
        else:
            item = self._get_item_for_dn(self._parent_dn(mo.dn))
        if item:
            item.appendColumn([self._row_for_mo(mo)[0]])
        self.auto_width()

    def _add_mos_in_tree(self, mos, index=QtCore.QModelIndex()):
        item = None
        if index.isValid():
            item = self._hierarchy_model.itemFromIndex(index)
        else:
            if not mos:
                return
            item = self._get_item_for_dn(self._parent_dn(mos[0].dn))
        while item.columnCount():
            item.removeColumn(0)
        items = map(self._row_for_mo, mos)
        if items:
            for x in xrange(len(items[0])):
                item.appendColumn([row[x] for row in items])
        self.auto_width()

    @staticmethod
    def _parent_dn(dn):
        parent_dn, _, rn = dn.rpartition('/')
        return parent_dn

    def _get_item_for_dn(self, dn):
        parent_dn = dn
        items = self._hierarchy_model.findItems(parent_dn, column=1)
        if items:
            return self._hierarchy_model.item(items[0].row())
        return None

    @QtCore.Slot('_data_resolved(QVariant)')
    def _data_resolved(self, datav):
        print 'Data resolved: ', datav
        index, data = datav
        if isinstance(data, UcsmObject):
            self._add_mo_in_tree(data, index=index)
        else:
            self._add_mos_in_tree(data, index=index)

    @QtCore.Slot('_current_changed(QModelIndex,QModelIndex)')
    def _current_changed(self, curr, prev):
        self._item_activated(curr)

    @QtCore.Slot('_item_activated(QModelIndex)')
    def _item_activated(self, index):
        print 'Activated: %s data %s' % (index, index.data(self.MO_ROLE))
        if index.sibling(0, 0).isValid():
            index = index.sibling(0, 0)
            data = index.data(self.MO_ROLE)
            self.set_detail_object(data)

    def _mo_item_expand(self, index):
        obj = index.data(self.MO_ROLE)
        print 'Expanded object: %s' % obj
        try:
            self._resolver.add_task(lambda: (index,
                                        self._conn.resolve_children(obj.dn)))
        except (KeyError, AttributeError):
            QtGui.QMessageBox.critical(0, 'Error', 'Object does not have dn')

    def auto_width(self):
        for view in [self._hierarchy_view, self._details_view]:
            for col in xrange(view.model().columnCount()):
                view.resizeColumnToContents(col)

    def set_detail_object(self, object):
        self._details_model.removeRows(0, self._details_model.rowCount())
        for k, v in object.attributes.iteritems():
            row = [QStandardItem(k), QStandardItem(v)]
            for item in row:
                item.setEditable(False)
            self._details_model.appendRow(row)
        self.auto_width()
Beispiel #41
0
    def __init__(self, parent, header, device_settings, firmware_settings,
                 error_codes, *args):
        QDialog.__init__(self, parent, *args)
        self.setGeometry(300, 200, 570, 450)
        self.setWindowTitle("Device information")
        table_model = DeviceInformationTable(self, header, device_settings)
        dev_settings_table = QTableView()
        dev_settings_table.setModel(table_model)

        table_model = DeviceInformationTable(self, header, firmware_settings)
        fw_settings_table = QTableView()
        fw_settings_table.setModel(table_model)

        table_model = DeviceInformationTable(self, header, error_codes)
        error_code_table = QTableView()
        error_code_table.setModel(table_model)

        # set font
        # font = QFont("monospace", 10)
        font = QFont("", 10)
        dev_settings_table.setFont(font)
        fw_settings_table.setFont(font)
        # set column width to fit contents (set font first!)
        dev_settings_table.resizeColumnsToContents()
        fw_settings_table.resizeColumnsToContents()
        error_code_table.resizeColumnsToContents()

        tab_view = QTabWidget()
        tab_view.addTab(dev_settings_table, "User settings")
        tab_view.addTab(fw_settings_table, "Firmware settings")
        tab_view.addTab(error_code_table, "Error Codes")

        layout = QVBoxLayout(self)
        layout.addWidget(tab_view)
        self.setLayout(layout)
Beispiel #42
0
 def __init__(self, parent=None):
     QTableView.__init__(self, parent)
     self.progbar = ProgressBarDelegate(self)
     self.setItemDelegateForColumn(1, CheckBoxDelegate(self))
     self.setItemDelegateForColumn(3, self.progbar)
Beispiel #43
0
 def __init__(self, QWidget_parent=None):
     QTableView.__init__(self, QWidget_parent)
     self.clicked.connect(self.click)
Beispiel #44
0
class PenelopeMaterialDialog(_MaterialDialog):

    def __init__(self, parent=None):
        _MaterialDialog.__init__(self, parent)
        self.setWindowTitle('Material')
        self.setMinimumWidth(1000)

    def _initUI(self):
        # Variables
        model_forcing = _InteractionForcingTableModel()

        # Actions
        act_add_forcing = QAction(getIcon("list-add"), "Add interaction forcing", self)
        act_remove_forcing = QAction(getIcon("list-remove"), "Remove interaction forcing", self)

        # Widgets
        self._lbl_elastic_scattering_c1 = QLabel('C1')
        self._lbl_elastic_scattering_c1.setStyleSheet("color: blue")
        self._txt_elastic_scattering_c1 = MultiNumericalLineEdit()
        self._txt_elastic_scattering_c1.setValidator(_ElasticScatteringValidator())
        self._txt_elastic_scattering_c1.setValues([0.0])

        self._lbl_elastic_scattering_c2 = QLabel('C2')
        self._lbl_elastic_scattering_c2.setStyleSheet("color: blue")
        self._txt_elastic_scattering_c2 = MultiNumericalLineEdit()
        self._txt_elastic_scattering_c2.setValidator(_ElasticScatteringValidator())
        self._txt_elastic_scattering_c2.setValues([0.0])

        self._lbl_cutoff_energy_inelastic = QLabel('Inelastic collisions')
        self._lbl_cutoff_energy_inelastic.setStyleSheet("color: blue")
        self._txt_cutoff_energy_inelastic = MultiNumericalLineEdit()
        self._txt_cutoff_energy_inelastic.setValidator(_CutoffEnergyValidator())
        self._txt_cutoff_energy_inelastic.setValues([50.0])
        self._cb_cutoff_energy_inelastic = UnitComboBox('eV')

        self._lbl_cutoff_energy_bremsstrahlung = QLabel('Bremsstrahlung emission')
        self._lbl_cutoff_energy_bremsstrahlung.setStyleSheet("color: blue")
        self._txt_cutoff_energy_bremsstrahlung = MultiNumericalLineEdit()
        self._txt_cutoff_energy_bremsstrahlung.setValidator(_CutoffEnergyValidator())
        self._txt_cutoff_energy_bremsstrahlung.setValues([50.0])
        self._cb_cutoff_energy_bremsstrahlung = UnitComboBox('eV')

        self._lbl_maximum_step_length = QLabel('Maximum step length')
        self._lbl_maximum_step_length.setStyleSheet("color: blue")
        self._txt_maximum_step_length = MultiNumericalLineEdit()
        self._txt_maximum_step_length.setValidator(_MaximumStepLengthValidator())
        self._txt_maximum_step_length.setValues([1e15])
        self._cb_maximum_step_length_unit = UnitComboBox('m')

        self._tbl_forcing = QTableView()
        self._tbl_forcing.setModel(model_forcing)
        self._tbl_forcing.setItemDelegate(_InteractionForcingDelegate())
        header = self._tbl_forcing.horizontalHeader()
        header.setResizeMode(QHeaderView.Stretch)

        self._tlb_forcing = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._tlb_forcing.addWidget(spacer)
        self._tlb_forcing.addAction(act_add_forcing)
        self._tlb_forcing.addAction(act_remove_forcing)

        # Layouts
        layout = QHBoxLayout()

        layout.addLayout(_MaterialDialog._initUI(self), 1)

        frame = QFrame()
        frame.setFrameShape(QFrame.VLine)
        frame.setFrameShadow(QFrame.Sunken)
        layout.addWidget(frame)

        sublayout = QVBoxLayout()

        box_elastic_scattering = QGroupBox("Elastic scattering")
        boxlayout = QFormLayout()
        boxlayout.addRow(self._lbl_elastic_scattering_c1, self._txt_elastic_scattering_c1)
        boxlayout.addRow(self._lbl_elastic_scattering_c2, self._txt_elastic_scattering_c2)
        box_elastic_scattering.setLayout(boxlayout)
        sublayout.addWidget(box_elastic_scattering)

        box_cutoff_energy = QGroupBox("Cutoff energy")
        boxlayout = QFormLayout()
        boxsublayout = QHBoxLayout()
        boxsublayout.addWidget(self._txt_cutoff_energy_inelastic, 1)
        boxsublayout.addWidget(self._cb_cutoff_energy_inelastic)
        boxlayout.addRow(self._lbl_cutoff_energy_inelastic, boxsublayout)
        boxsublayout = QHBoxLayout()
        boxsublayout.addWidget(self._txt_cutoff_energy_bremsstrahlung, 1)
        boxsublayout.addWidget(self._cb_cutoff_energy_bremsstrahlung)
        boxlayout.addRow(self._lbl_cutoff_energy_bremsstrahlung, boxsublayout)
        box_cutoff_energy.setLayout(boxlayout)
        sublayout.addWidget(box_cutoff_energy)

        subsublayout = QFormLayout()
        subsubsublayout = QHBoxLayout()
        subsubsublayout.addWidget(self._txt_maximum_step_length, 1)
        subsubsublayout.addWidget(self._cb_maximum_step_length_unit)
        subsublayout.addRow(self._lbl_maximum_step_length, subsubsublayout)
        sublayout.addLayout(subsublayout)

        box_forcing = QGroupBox('Interaction forcing')
        boxlayout = QVBoxLayout()
        boxlayout.addWidget(self._tbl_forcing)
        boxlayout.addWidget(self._tlb_forcing)
        box_forcing.setLayout(boxlayout)
        sublayout.addWidget(box_forcing)

        sublayout.addStretch()

        layout.addLayout(sublayout, 1)

        # Signals
        self._txt_elastic_scattering_c1.textChanged.connect(self._onElasticScatteringC1Changed)
        self._txt_elastic_scattering_c2.textChanged.connect(self._onElasticScatteringC2Changed)
        self._txt_cutoff_energy_inelastic.textChanged.connect(self._onCutoffEnergyInelasticChanged)
        self._txt_cutoff_energy_bremsstrahlung.textChanged.connect(self._onCutoffEnergyBremsstrahlungChanged)
        self._txt_maximum_step_length.textChanged.connect(self._onMaximumStepLengthChanged)

        act_add_forcing.triggered.connect(self._onForcingAdd)
        act_remove_forcing.triggered.connect(self._onForcingRemove)

        return layout

    def _onElasticScatteringC1Changed(self):
        if self._txt_elastic_scattering_c1.hasAcceptableInput():
            self._txt_elastic_scattering_c1.setStyleSheet('background: none')
        else:
            self._txt_elastic_scattering_c1.setStyleSheet('background: pink')

    def _onElasticScatteringC2Changed(self):
        if self._txt_elastic_scattering_c2.hasAcceptableInput():
            self._txt_elastic_scattering_c2.setStyleSheet('background: none')
        else:
            self._txt_elastic_scattering_c2.setStyleSheet('background: pink')

    def _onCutoffEnergyInelasticChanged(self):
        if self._txt_cutoff_energy_inelastic.hasAcceptableInput():
            self._txt_cutoff_energy_inelastic.setStyleSheet('background: none')
        else:
            self._txt_cutoff_energy_inelastic.setStyleSheet('background: pink')

    def _onCutoffEnergyBremsstrahlungChanged(self):
        if self._txt_cutoff_energy_bremsstrahlung.hasAcceptableInput():
            self._txt_cutoff_energy_bremsstrahlung.setStyleSheet('background: none')
        else:
            self._txt_cutoff_energy_bremsstrahlung.setStyleSheet('background: pink')

    def _onMaximumStepLengthChanged(self):
        if self._txt_maximum_step_length.hasAcceptableInput():
            self._txt_maximum_step_length.setStyleSheet('background: none')
        else:
            self._txt_maximum_step_length.setStyleSheet('background: pink')

    def _onForcingAdd(self):
        index = self._tbl_forcing.selectionModel().currentIndex()
        model = self._tbl_forcing.model()
        model.insertRows(index.row() + 1)

    def _onForcingRemove(self):
        selection = self._tbl_forcing.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Interaction forcing", "Select a row")
            return

        model = self._tbl_forcing.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.removeRow(row)

    def _getParametersDict(self):
        params = _MaterialDialog._getParametersDict(self)

        params['c1'] = self._txt_elastic_scattering_c1.values().tolist()
        params['c2'] = self._txt_elastic_scattering_c2.values().tolist()

        wcc = self._txt_cutoff_energy_inelastic.values() * self._cb_cutoff_energy_inelastic.factor()
        params['wcc'] = wcc.tolist()

        wcr = self._txt_cutoff_energy_bremsstrahlung.values() * self._cb_cutoff_energy_bremsstrahlung.factor()
        params['wcr'] = wcr.tolist()

        dsmax = self._txt_maximum_step_length.values() * self._cb_maximum_step_length_unit.factor()
        params['dsmax'] = dsmax.tolist()

        params['forcings'] = \
            self._tbl_forcing.model().interaction_forcings()

        return params

    def _generateName(self, parameters, varied):
        name = parameters.pop('name')
        if name is None:
            name = PenelopeMaterial.generate_name(parameters['composition'])

        parts = [name]
        for key in varied:
            if key == 'composition':
                continue
            elif key == 'forcings':
                forcing = parameters[key][0]
                forcer = forcing.forcer
                wlow = forcing.weight[0]
                whigh = forcing.weight[1]
                parts.append('forcings={0:n}_{1:n}_{2:n}'.format(forcer, wlow, whigh))
            else:
                parts.append('{0:s}={1:n}'.format(key, parameters[key]))
        return '+'.join(parts)

    def _createMaterial(self, parameters, varied):
        mat = _MaterialDialog._createMaterial(self, parameters, varied)

        c1 = parameters['c1']
        c2 = parameters['c2']
        wcc = parameters['wcc']
        wcr = parameters['wcr']
        dsmax = parameters['dsmax']
        forcings = parameters['forcings']

        return PenelopeMaterial(mat.composition, mat.name, mat.density_kg_m3,
                                mat.absorption_energy_eV,
                                elastic_scattering=(c1, c2),
                                cutoff_energy_inelastic_eV=wcc,
                                cutoff_energy_bremsstrahlung_eV=wcr,
                                interaction_forcings=forcings,
                                maximum_step_length_m=dsmax)

    def setValue(self, material):
        _MaterialDialog.setValue(self, material)

        # Elastic scattering
        c1, c2 = material.elastic_scattering
        self._txt_elastic_scattering_c1.setValues(c1)
        self._txt_elastic_scattering_c2.setValues(c2)

        # Cutoff energy
        self._txt_cutoff_energy_inelastic.setValues(material.cutoff_energy_inelastic_eV)
        self._cb_cutoff_energy_inelastic.setUnit('eV')

        self._txt_cutoff_energy_bremsstrahlung.setValues(material.cutoff_energy_bremsstrahlung_eV)
        self._cb_cutoff_energy_bremsstrahlung.setUnit('eV')

        # Maximum step length
        self._txt_maximum_step_length.setValues(material.maximum_step_length_m)
        self._cb_maximum_step_length_unit.setUnit('m')

        # Interaction forcings
        forcings = material.interaction_forcings

        model = self._tbl_forcing.model()
        model.removeRows(0, model.rowCount())
        model.insertRows(1, len(forcings))

        for row, forcing in enumerate(forcings):
            model.setData(model.index(row, 0), forcing.particle)
            model.setData(model.index(row, 1), forcing.collision)
            model.setData(model.index(row, 2), forcing.forcer)
            model.setData(model.index(row, 3), forcing.weight[0])
            model.setData(model.index(row, 4), forcing.weight[1])

    def setReadOnly(self, state):
        _MaterialDialog.setReadOnly(self, state)

        style = 'color: none' if state else 'color: blue'
        self._lbl_elastic_scattering_c1.setStyleSheet(style)
        self._txt_elastic_scattering_c1.setReadOnly(state)

        self._lbl_elastic_scattering_c2.setStyleSheet(style)
        self._txt_elastic_scattering_c2.setReadOnly(state)

        self._lbl_cutoff_energy_inelastic.setStyleSheet(style)
        self._txt_cutoff_energy_inelastic.setReadOnly(state)
        self._cb_cutoff_energy_inelastic.setEnabled(not state)

        self._lbl_cutoff_energy_bremsstrahlung.setStyleSheet(style)
        self._txt_cutoff_energy_bremsstrahlung.setReadOnly(state)
        self._cb_cutoff_energy_bremsstrahlung.setEnabled(not state)

        self._lbl_maximum_step_length.setStyleSheet(style)
        self._txt_maximum_step_length.setReadOnly(state)
        self._cb_maximum_step_length_unit.setEnabled(not state)

        self._tbl_forcing.setEnabled(not state)
        self._tlb_forcing.setVisible(not state)

    def isReadOnly(self):
        return _MaterialDialog.isReadOnly(self) and \
            self._txt_elastic_scattering_c1.isReadOnly() and \
            self._txt_elastic_scattering_c2.isReadOnly() and \
            self._txt_cutoff_energy_inelastic.isReadOnly() and \
            self._txt_cutoff_energy_bremsstrahlung.isReadOnly() and \
            self._txt_maximum_step_length.isReadOnly() and \
            not self._tbl_forcing.isEnabled() and \
            not self._tlb_forcing.isVisible()
Beispiel #45
0
class TemplateSelectDialog(QDialog):
    def refresh_templates_list(self):

        documents = documents_service.all_templates()

        self.model.removeRows(0, self.model.rowCount())

        if documents:
            for doc in sorted(list(documents), key=lambda d: d.filename):
                self._add_one_document(doc.filename, doc.template_document_id,
                                       doc.file_size, doc.description)

    def __init__(self, parent=None):
        super(TemplateSelectDialog, self).__init__(parent)

        self.setWindowTitle(_("Select a template"))

        self.template_id = []

        self.model = QStandardItemModel()
        self.view = QTableView()
        self.view.setModel(self.model)
        self.view.verticalHeader().setVisible(False)
        self.view.horizontalHeader().setVisible(False)
        self.view.setMinimumSize(500, 200)
        self.view.setShowGrid(True)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)

        l = QVBoxLayout()

        l.addWidget(QLabel(_("Please select one or more template.")))
        self.view.doubleClicked.connect(self._doubleClicked)

        l.addWidget(QLabel(u"<h3>{}</h3>".format(_("Documents Templates"))))
        l.addWidget(self.view)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton(QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton(QDialogButtonBox.Ok)
        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

        l.addWidget(self.buttons)

        self.setLayout(l)

    def _add_one_document(self, file_name, doc_id, file_size, description):
        """ Adds a document to the list
        """

        # file_name is either an absolute path or just a file name
        # If it is an absolute path, then the file is expected
        # to exist locally (at it absolute path location of course).
        # If not, then the file is expected to be a remote file
        # and shall be downloaded before opening.

        mainlog.debug(u"{} {} {} {}".format(file_name, doc_id, file_size,
                                            description))
        short_name = file_name
        if os.path.isabs(file_name):
            short_name = os.path.basename(file_name)
            if not os.path.isfile(file_name):
                raise Exception(u"The file {} doesn't exist".format(file_name))

        items = [QStandardItem(short_name)]
        items.append(QStandardItem(description))

        self.model.appendRow(items)
        self.model.setData(self.model.index(self.model.rowCount() - 1, 0),
                           doc_id, Qt.UserRole + 1)

        self.view.horizontalHeader().setResizeMode(0, QHeaderView.Stretch)
        self.view.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)
        self.view.resizeRowsToContents()

    @Slot()
    def accept(self):
        selected_rows = self.view.selectionModel().selectedRows()
        if selected_rows:
            self.template_id = []
            for row in selected_rows:
                ndx_row = row.row()
                self.template_id.append(
                    self.model.data(self.model.index(ndx_row, 0),
                                    Qt.UserRole + 1))
        else:
            self.template_id = []
        return super(TemplateSelectDialog, self).accept()

    @Slot()
    def reject(self):
        return super(TemplateSelectDialog, self).reject()

    @Slot(QModelIndex)
    def _doubleClicked(self, ndx):
        self.accept()
Beispiel #46
0
class LimitWizardPage(_ExpandableOptionsWizardPage):

    class _LimitComboBoxModel(QAbstractListModel):

        def __init__(self, limits_text=None):
            QAbstractListModel.__init__(self)

            if limits_text is None:
                limits_text = {}
            self._limits_text = limits_text.copy()

            self._limits = list(limits_text.keys())

        def rowCount(self, *args, **kwargs):
            return len(self._limits)

        def data(self, index, role=Qt.DisplayRole):
            if not index.isValid() or \
                    not (0 <= index.row() < self.rowCount()):
                return None

            if role == Qt.TextAlignmentRole:
                return Qt.AlignCenter

            if role != Qt.DisplayRole:
                return None

            limit_class = self._limits[index.row()]
            return self._limits_text[limit_class]

        def add(self, limit_class):
            if limit_class not in self._limits_text:
                raise ValueError('No text defined for limit: %s' % limit_class)
            self._limits.append(limit_class)
            self.reset()

        def remove(self, limit_class):
            self._limits.remove(limit_class)
            self.reset()

        def limitClass(self, index):
            return self._limits[index]

    class _LimitTableModel(QAbstractTableModel):

        def __init__(self):
            QAbstractTableModel.__init__(self)
            self._limits = []

        def rowCount(self, *args, **kwargs):
            return len(self._limits)

        def columnCount(self, *args, **kwargs):
            return 1

        def data(self, index, role=Qt.DisplayRole):
            if not index.isValid() or \
                    not (0 <= index.row() < len(self._limits)):
                return None

            if role == Qt.TextAlignmentRole:
                return Qt.AlignCenter

            if role == Qt.DisplayRole or role == Qt.ToolTipRole:
                limit = self._limits[index.row()]
                return str(limit) if limit is not None else ''

            return None

        def headerData(self, section , orientation, role):
            if role != Qt.DisplayRole:
                return None
            if orientation == Qt.Vertical:
                return str(section + 1)

        def flags(self, index):
            if not index.isValid():
                return Qt.ItemIsEnabled

            return Qt.ItemFlags(QAbstractTableModel.flags(self, index) |
                                Qt.ItemIsEditable)

        def setData(self, index, value, role=Qt.EditRole):
            if not index.isValid() or \
                    not (0 <= index.row() < len(self._limits)):
                return False

            row = index.row()
            self._limits[row] = value

            self.dataChanged.emit(index, index)
            return True

        def insertRows(self, row, count=1, parent=None):
            if parent is None:
                parent = QModelIndex()
            self.beginInsertRows(parent, row, row + count - 1)

            for _ in range(count):
                self._limits.insert(row, None)

            self.endInsertRows()
            return True

        def removeRows(self, row, count=1, parent=None):
            if parent is None:
                parent = QModelIndex()
            self.beginRemoveRows(parent, row, row + count - 1)

            for index in reversed(range(row, row + count)):
                self._limits.pop(index)

            self.endRemoveRows()
            return True

        def append(self, limit):
            self.insert(self.rowCount(), limit)

        def insert(self, index, limit):
            self.insertRows(index)
            self.setData(self.createIndex(index, 0), limit)

        def remove(self, limit):
            index = self._limits.index(limit)
            self.removeRows(index)

        def modify(self, index, limit):
            self.setData(self.createIndex(index, 0), limit)

        def clear(self):
            self.removeRows(0, self.rowCount())

        def limits(self):
            limits = set(self._limits)
            limits.discard(None)
            return limits

        def limit(self, index):
            return self._limits[index.row()]

    class _LimitTableDelegate(QItemDelegate):

        def __init__(self, parent=None):
            QItemDelegate.__init__(self, parent)

        def createEditor(self, parent, option, index):
            return None

        def setEditorData(self, editor, index):
            pass

        def setModelData(self, editor, model, index):
            return None

    def __init__(self, options, parent=None):
        _ExpandableOptionsWizardPage.__init__(self, options, parent)
        self.setTitle('Limit')

    def _initUI(self):
        # Variables
        self._widgets = {}
        tbl_model = self._LimitTableModel()

        # Widgets
        self._cb_limit = QComboBox()
        self._cb_limit.setModel(self._LimitComboBoxModel())

        btn_limit_add = QPushButton()
        btn_limit_add.setIcon(getIcon("list-add"))

        self._tbl_limit = QTableView()
        self._tbl_limit.setModel(tbl_model)
        self._tbl_limit.setItemDelegate(self._LimitTableDelegate())
        header = self._tbl_limit.horizontalHeader()
        header.setResizeMode(QHeaderView.Stretch)
        header.hide()
        policy = self._tbl_limit.sizePolicy()
        policy.setVerticalStretch(True)
        self._tbl_limit.setSizePolicy(policy)

        tlb_limit = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_limit.addWidget(spacer)
        act_remove = tlb_limit.addAction(getIcon("list-remove"), "Remove limit")
        act_clear = tlb_limit.addAction(getIcon("edit-clear"), "Clear")

        # Layouts
        layout = _ExpandableOptionsWizardPage._initUI(self)

        sublayout = QHBoxLayout()
        sublayout.addWidget(self._cb_limit, 1)
        sublayout.addWidget(btn_limit_add)
        layout.addRow("Select", sublayout)

        layout.addRow(self._tbl_limit)
        layout.addRow(tlb_limit)

        # Signals
        btn_limit_add.released.connect(self._onLimitAdd)
        act_remove.triggered.connect(self._onLimitRemove)
        act_clear.triggered.connect(self._onLimitClear)

        self._tbl_limit.doubleClicked.connect(self._onLimitDoubleClicked)

        tbl_model.dataChanged.connect(self.valueChanged)
        tbl_model.rowsInserted.connect(self.valueChanged)
        tbl_model.rowsRemoved.connect(self.valueChanged)

        return layout

    def _onLimitAdd(self):
        tbl_model = self._tbl_limit.model()
        cb_model = self._cb_limit.model()

        index = self._cb_limit.currentIndex()
        try:
            limit_class = cb_model.limitClass(index)
        except IndexError:
            return
        widget_class = self._widgets[limit_class]
        wdg_limit = widget_class()

        dialog = _LimitDialog(wdg_limit)
        if not dialog.exec_():
            return

        limit = dialog.limit()
        tbl_model.append(limit) # Insert table row
        cb_model.remove(limit.__class__) # Remove limit from combo box

    def _onLimitRemove(self):
        selection = self._tbl_limit.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Limit", "Select a row")
            return

        tbl_model = self._tbl_limit.model()
        cb_model = self._cb_limit.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            limit = tbl_model.limit(tbl_model.createIndex(row, 0))
            cb_model.add(limit.__class__) # Show limit to combo box
            tbl_model.removeRow(row) # Remove row

        if self._cb_limit.currentIndex() < 0:
            self._cb_limit.setCurrentIndex(0)

    def _onLimitClear(self):
        tbl_model = self._tbl_limit.model()
        cb_model = self._cb_limit.model()
        for row in reversed(range(tbl_model.rowCount())):
            limit = tbl_model.limit(tbl_model.createIndex(row, 0))
            cb_model.add(limit.__class__) # Show limit to combo box
            tbl_model.removeRow(row) # Remove row

        if self._cb_limit.currentIndex() < 0:
            self._cb_limit.setCurrentIndex(0)

    def _onLimitDoubleClicked(self, index):
        tbl_model = self._tbl_limit.model()
        limit = tbl_model.limit(index)
        widget_class = self._widgets[limit.__class__]
        wdg_limit = widget_class()
        wdg_limit.setValue(limit)

        dialog = _LimitDialog(wdg_limit)
        if not dialog.exec_():
            return

        tbl_model.modify(index.row(), dialog.limit())

    def initializePage(self):
        _ExpandableOptionsWizardPage.initializePage(self)

        # Clear
        self._widgets.clear()
        limits_text = {}

        # Populate combo box
        it = self._iter_widgets('pymontecarlo.ui.gui.options.limit', 'LIMITS')
        for limit_class, widget_class, programs in it:
            widget = widget_class()
            self._widgets[limit_class] = widget_class

            program_text = ', '.join(map(attrgetter('name'), programs))
            text = '{0} ({1})'.format(widget.accessibleName(), program_text)
            limits_text[limit_class] = text

            del widget

        cb_model = self._LimitComboBoxModel(limits_text)
        self._cb_limit.setModel(cb_model)
        self._cb_limit.setCurrentIndex(0)

        # Add limit(s)
        tbl_model = self._tbl_limit.model()
        tbl_model.clear()

        for limit in self.options().limits:
            tbl_model.append(limit)

    def validatePage(self):
        tbl_model = self._tbl_limit.model()

        self.options().limits.clear()
        for limit in tbl_model.limits():
            if not limit.__class__ in self._widgets:
                continue
            self.options().limits.add(limit)

        return True

    def expandCount(self):
        if self._tbl_limit.model().rowCount() == 0:
            return 0

        try:
            count = 1

            for limit in self._tbl_limit.model().limits():
                count *= len(expand(limit))

            return count
        except:
            return 0
Beispiel #47
0
    def setupTabs(self):
        """ Setup the various tabs in the AddressWidget. """
        groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"]

        for group in groups:
            proxyModel = QSortFilterProxyModel(self)
            proxyModel.setSourceModel(self.tableModel)
            proxyModel.setDynamicSortFilter(True)

            tableView = QTableView()
            tableView.setModel(proxyModel)
            tableView.setSortingEnabled(True)
            tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
            tableView.horizontalHeader().setStretchLastSection(True)
            tableView.verticalHeader().hide()
            tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
            tableView.setSelectionMode(QAbstractItemView.SingleSelection)

            # This here be the magic: we use the group name (e.g. "ABC") to
            # build the regex for the QSortFilterProxyModel for the group's
            # tab. The regex will end up looking like "^[ABC].*", only 
            # allowing this tab to display items where the name starts with 
            # "A", "B", or "C". Notice that we set it to be case-insensitive.
            reFilter = "^[%s].*" % group

            proxyModel.setFilterRegExp(QRegExp(reFilter, Qt.CaseInsensitive))
            proxyModel.setFilterKeyColumn(0) # Filter on the "name" column
            proxyModel.sort(0, Qt.AscendingOrder)

            tableView.selectionModel().selectionChanged.connect(self.selectionChanged)

            self.addTab(tableView, group)
 def testModelWithParent(self):
     view = QTableView()
     model = TestModel(None)
     view.setModel(model)
     samemodel = view.model()
     self.assertEqual(model, samemodel)
Beispiel #49
0
    def copy_table_view_to_csv(self,
                               view: QTableView,
                               special_headers=[],
                               special_formatters=dict()):
        """ Copies the selected rows in the view to the clipboard

        Will use the Horse delegates if any (because they display information in a different way).

        :param view:
        :return:
        """

        rows_ndx = self._selected_rows(view.selectedIndexes())

        model = view.model()
        visible_cols = []
        for c in range(model.columnCount()):
            if not view.isColumnHidden(c):
                visible_cols.append(c)

        s = ""

        if special_headers:
            h = special_headers
        else:
            h = []
            mh = view.horizontalHeader().model()
            for col in visible_cols:
                h.append(mh.headerData(col, Qt.Horizontal, Qt.DisplayRole))

        s += self._line_to_csv(h)

        for row in rows_ndx:

            r = []
            for col in visible_cols:

                model_index = model.index(row, col)

                if col in special_formatters:
                    formatted = special_formatters[col](model_index)

                    if type(formatted) in (list, tuple):
                        r += list(formatted)
                    elif type(formatted) == float:
                        r.append(format_csv(formatted))
                    else:
                        r.append(str(formatted))
                else:
                    d = view.itemDelegateForColumn(col)
                    if d:
                        displayed_data = d.get_displayed_data(model_index)
                    else:
                        displayed_data = model_index.data(Qt.DisplayRole)

                    if displayed_data and type(model_index.data(
                            Qt.UserRole)) == float:
                        # FIXME This a hack to convert float representations to
                        # the convert decimal format for CSV pasting. Rmemeber that MS Excel
                        # might have different decimal point, based on the locale...
                        # This is sub optimal because a float might not always be represented
                        # as a float... But it's not the case for now => not a problem.
                        r.append(displayed_data.replace(u".", decimal_point))
                    else:
                        r.append(displayed_data)

            s += self._line_to_csv(r)

        mainlog.debug("copy_table_view: {}".format(s))
        QApplication.clipboard().setText(s)
Beispiel #50
0
class Blew(QWidget):
    def __init__(self):
        super(Blew, self).__init__()
        self.setWindowModality(Qt.NonModal)
        self.setWindowFlags(
            Qt.FramelessWindowHint)  # Qt.Tool | Qt.FramelessWindowHint

        l = QHBoxLayout()
        self.items_view = QTableView()

        # Make the dropdown nice
        l.setContentsMargins(0, 0, 0, 0)
        self.items_view.horizontalHeader().setStretchLastSection(True)
        self.items_view.horizontalHeader().hide()
        self.items_view.verticalHeader().hide()
        self.items_view.setShowGrid(False)
        self.setMinimumSize(300, 100)

        self.model = QuickComboModel(self)
        self.items_view.setModel(self.model)
        l.addWidget(self.items_view)
        self.setLayout(l)

    def get_current_completion(self):
        """ Get the currently selected completion """
        return self.items_view.currentIndex().data()

    @Slot(list)
    def set_possible_completions(self, completions):
        if completions:
            self.model.buildModelFromArray(completions)
            # self.show()
        else:
            self.model.clear()
            self.hide()

    completion_discarded = Signal()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            event.ignore()
            self.hide()
            self.completion_discarded.emit()

        return super(Blew, self).keyPressEvent(event)
Beispiel #51
0
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle('Runner')
        self.setMinimumWidth(750)

        # Runner
        self._runner = None

        self._running_timer = QTimer()
        self._running_timer.setInterval(500)

        # Widgets
        self._dlg_progress = QProgressDialog()
        self._dlg_progress.setRange(0, 100)
        self._dlg_progress.setModal(True)
        self._dlg_progress.hide()

        lbl_outputdir = QLabel("Output directory")
        self._txt_outputdir = DirBrowseWidget()

        max_workers = cpu_count() #@UndefinedVariable
        lbl_workers = QLabel('Number of workers')
        self._spn_workers = QSpinBox()
        self._spn_workers.setRange(1, max_workers)
        self._spn_workers.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        lbl_max_workers = QLabel('(max: %i)' % max_workers)

        self._chk_overwrite = QCheckBox("Overwrite existing results in output directory")
        self._chk_overwrite.setChecked(True)

        self._lbl_available = QLabel('Available')
        self._lst_available = QListView()
        self._lst_available.setModel(_AvailableOptionsListModel())
        self._lst_available.setSelectionMode(QListView.SelectionMode.MultiSelection)

        tlb_available = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_available.addWidget(spacer)
        act_open = tlb_available.addAction(getIcon("document-open"), "Open")
        act_open.setShortcut(QKeySequence.Open)
        tlb_available.addSeparator()
        act_remove = tlb_available.addAction(getIcon("list-remove"), "Remove")
        act_clear = tlb_available.addAction(getIcon("edit-clear"), "Clear")

        self._btn_addtoqueue = QPushButton(getIcon("go-next"), "")
        self._btn_addtoqueue.setToolTip("Add to queue")
        self._btn_addtoqueue.setEnabled(False)

        self._btn_addalltoqueue = QPushButton(getIcon("go-last"), "")
        self._btn_addalltoqueue.setToolTip("Add all to queue")
        self._btn_addalltoqueue.setEnabled(False)

        self._lbl_options = QLabel('Queued/Running/Completed')
        self._tbl_options = QTableView()
        self._tbl_options.setModel(_StateOptionsTableModel())
        self._tbl_options.setItemDelegate(_StateOptionsItemDelegate())
        self._tbl_options.setSelectionMode(QListView.SelectionMode.NoSelection)
        self._tbl_options.setColumnWidth(1, 60)
        self._tbl_options.setColumnWidth(2, 80)
        header = self._tbl_options.horizontalHeader()
        header.setResizeMode(0, QHeaderView.Interactive)
        header.setResizeMode(1, QHeaderView.Fixed)
        header.setResizeMode(2, QHeaderView.Fixed)
        header.setResizeMode(3, QHeaderView.Stretch)

        self._btn_start = QPushButton(getIcon("media-playback-start"), "Start")

        self._btn_cancel = QPushButton("Cancel")
        self._btn_cancel.setEnabled(False)

        self._btn_close = QPushButton("Close")

        self._btn_import = QPushButton("Import")
        self._btn_import.setEnabled(False)

        # Layouts
        layout = QVBoxLayout()

        sublayout = QGridLayout()
        sublayout.addWidget(lbl_outputdir, 0, 0)
        sublayout.addWidget(self._txt_outputdir, 0, 1)
        sublayout.addWidget(lbl_workers, 1, 0)

        subsublayout = QHBoxLayout()
        subsublayout.addWidget(self._spn_workers)
        subsublayout.addWidget(lbl_max_workers)
        sublayout.addLayout(subsublayout, 1, 1)
        layout.addLayout(sublayout)

        sublayout.addWidget(self._chk_overwrite, 2, 0, 1, 3)

        sublayout = QGridLayout()
        sublayout.setColumnStretch(0, 1)
        sublayout.setColumnStretch(2, 3)
        sublayout.addWidget(self._lbl_available, 0, 0)
        sublayout.addWidget(self._lst_available, 1, 0)
        sublayout.addWidget(tlb_available, 2, 0)

        subsublayout = QVBoxLayout()
        subsublayout.addStretch()
        subsublayout.addWidget(self._btn_addtoqueue)
        subsublayout.addWidget(self._btn_addalltoqueue)
        subsublayout.addStretch()
        sublayout.addLayout(subsublayout, 1, 1)

        sublayout.addWidget(self._lbl_options, 0, 2)
        sublayout.addWidget(self._tbl_options, 1, 2)
        layout.addLayout(sublayout)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(self._btn_import)
        sublayout.addWidget(self._btn_start)
        sublayout.addWidget(self._btn_cancel)
        sublayout.addWidget(self._btn_close)
        layout.addLayout(sublayout)

        self.setLayout(layout)

        # Signal
        self._running_timer.timeout.connect(self._onRunningTimer)

        act_open.triggered.connect(self._onOpen)
        act_remove.triggered.connect(self._onRemove)
        act_clear.triggered.connect(self._onClear)

        self._btn_addtoqueue.released.connect(self._onAddToQueue)
        self._btn_addalltoqueue.released.connect(self._onAddAllToQueue)
        self._btn_start.released.connect(self._onStart)
        self._btn_cancel.released.connect(self._onCancel)
        self._btn_close.released.connect(self._onClose)
        self._btn_import.released.connect(self._onImport)

        self.options_added.connect(self._onOptionsAdded)
        self.options_running.connect(self._onOptionsRunning)
        self.options_simulated.connect(self._onOptionsSimulated)
        self.options_error.connect(self._onOptionsError)
        self.results_error.connect(self._onResultsError)

        # Defaults
        settings = get_settings()
        section = settings.add_section('gui')
        if hasattr(section, 'outputdir'):
            self._txt_outputdir.setPath(section.outputdir)
        if hasattr(section, 'maxworkers'):
            self._spn_workers.setValue(int(section.maxworkers))
        if hasattr(section, 'overwrite'):
            state = True if section.overwrite.lower() == 'true' else False
            self._chk_overwrite.setChecked(state)
class LayerListWidget(_ParameterWidget):

    def __init__(self, parameter, parent=None):
        _ParameterWidget.__init__(self, parameter, parent)

        # Variables
        model = _LayerModel()
        self._material_class = Material

        # Actions
        act_add = QAction(getIcon("list-add"), "Add layer", self)
        act_remove = QAction(getIcon("list-remove"), "Remove layer", self)
        act_clean = QAction(getIcon('edit-clear'), "Clear", self)

        # Widgets
        self._cb_unit = UnitComboBox('m')
        self._cb_unit.setUnit('um')

        self._tbl_layers = QTableView()
        self._tbl_layers.setModel(model)
        self._tbl_layers.setItemDelegate(_LayerDelegate())
        header = self._tbl_layers.horizontalHeader()
        header.setResizeMode(QHeaderView.Stretch)
        header.setStyleSheet('color: blue')

        self._tlb_layers = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._tlb_layers.addWidget(spacer)
        self._tlb_layers.addAction(act_add)
        self._tlb_layers.addAction(act_remove)
        self._tlb_layers.addAction(act_clean)

        # Layouts
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(QLabel('Thickness unit'))
        sublayout.addWidget(self._cb_unit)
        layout.addLayout(sublayout)

        layout.addWidget(self._tbl_layers)
        layout.addWidget(self._tlb_layers)
        self.setLayout(layout)

        # Signals
        self.valuesChanged.connect(self._onChanged)
        self.validationRequested.connect(self._onChanged)

        act_add.triggered.connect(self._onAdd)
        act_remove.triggered.connect(self._onRemove)
        act_clean.triggered.connect(self._onClear)

        self._tbl_layers.doubleClicked.connect(self._onDoubleClicked)

        model.dataChanged.connect(self.valuesChanged)
        model.rowsInserted.connect(self.valuesChanged)
        model.rowsRemoved.connect(self.valuesChanged)

        self.validationRequested.emit()

    def _onChanged(self):
        if self.hasAcceptableInput():
            self._tbl_layers.setStyleSheet("background: none")
        else:
            self._tbl_layers.setStyleSheet("background: pink")

    def _onDoubleClicked(self, index):
        if index.column() != 0:
            return

        model = self._tbl_layers.model()
        materials = model.materials(index)

        if len(materials) == 0:
            dialog = get_material_dialog_class(self._material_class)()
        elif len(materials) == 1:
            dialog = get_material_dialog_class(self._material_class)()
            dialog.setValue(materials[0])
        else:
            dialog = MaterialListDialog()
            dialog.setMaterialClass(self._material_class)
            dialog.setValues(materials)

        dialog.setReadOnly(self.isReadOnly())

        if not dialog.exec_():
            return

        model.setData(index, dialog.values())

    def _onAdd(self):
        index = self._tbl_layers.selectionModel().currentIndex()
        model = self._tbl_layers.model()
        model.insertRows(index.row() + 1)

        # Show material dialog right away
        index = model.createIndex(index.row() + 1, 0)
        self._onDoubleClicked(index)

    def _onRemove(self):
        selection = self._tbl_layers.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Layer", "Select a row")
            return

        model = self._tbl_layers.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.removeRow(row)

    def _onClear(self):
        model = self._tbl_layers.model()
        for row in reversed(range(model.rowCount())):
            model.removeRow(row)

    def values(self):
        factor = self._cb_unit.factor()

        layers = []
        for material, thickness in self._tbl_layers.model().layers():
            if not material or not thickness:
                continue
            thickness_m = np.array(thickness, ndmin=1) * factor
            layers.append(_MockLayer(material, thickness_m))

        return layers

    def setValues(self, layers):
        layers = np.array(layers, ndmin=1)
        factor = self._cb_unit.factor()

        model = self._tbl_layers.model()
        model.removeRows(0, model.rowCount())
        model.insertRows(0, len(layers))

        for i, layer in enumerate(layers):
            model.setData(model.index(i, 0), layer.material)
            model.setData(model.index(i, 1), layer.thickness_m / factor)

    def isReadOnly(self):
        return not self._cb_unit.isEnabled() and \
            not self._tlb_layers.isVisible()

    def setReadOnly(self, state):
        self._cb_unit.setEnabled(not state)
        self._tlb_layers.setVisible(not state)

        style = 'color: none' if state else 'color: blue'
        self._tbl_layers.horizontalHeader().setStyleSheet(style)
        self._tbl_layers.itemDelegate().setReadOnly(state)

    def setMaterialClass(self, clasz):
        self._material_class = clasz
Beispiel #53
0
class uiManager(QMainWindow):
	def __init__(self):
		super(uiManager, self).__init__()

		self.setMinimumSize(900,500)
		self.setWindowTitle("Manage")

		self.aFileModel = FileModel() # Add files
		self.sFileModel = FileModel() # Queried files
		self.eFileModel = FileModel() # Editing files

		self.tabWidget = QTabWidget()
		self.setCentralWidget(self.tabWidget)

		self.defActions()

		self.addTab()
		self.searchTab()
		self.editTab()
		self.testtab()

		self.statusBar().showMessage("Hi.")


	def defActions(self):
		self.findAct = QAction("+", self, triggered=self.findFilesDlg)
		self.dropAddTabAct = QAction("-", self, shortcut="Delete",
			triggered=self.dropAddTabRows)
		self.dropEditTabAct = QAction("-", self, shortcut="Delete",
			triggered=self.dropEditTabRows)


	def dropEditTabRows(self):
		self.dropFiles(self.eFileTable, self.eFileModel)


	def dropAddTabRows(self):
		self.dropFiles(self.aFileTable, self.aFileModel)


	def testtab(self):
		self.test = QWidget()
		self.tabWidget.addTab(self.test, "WORDS")
		self.tabWidget.setCornerWidget(self.test)


	def addTab(self):

		self.aFileTable = QTableView()
		self.aFileTable.setModel(self.aFileModel)
		self.aFileTable.setSelectionBehavior(QAbstractItemView.SelectRows)

		self.setColumnsWidths(self.aFileTable)

		self.addWidget = QWidget()

		vLayout = QVBoxLayout()
		vLayout.addWidget(self.aFileTable)

		addBtn = QToolButton()
		addBtn.setDefaultAction(self.findAct)
		# addBtn.clicked.connect(self.findFilesDlg)

		dropBtn = QToolButton()
		dropBtn.setDefaultAction(self.dropAddTabAct)
		# rmvBtn.clicked.connect(self.rmvFiles)

		insBtn = QPushButton("Track")
		insBtn.clicked.connect(self.insert)

		hLayout = QHBoxLayout()

		hLayout.addWidget(addBtn)
		hLayout.addWidget(dropBtn)
		hLayout.addStretch(1)		
		hLayout.addWidget(insBtn)

		vLayout.addLayout(hLayout)

		self.addWidget.setLayout(vLayout)

		self.tabWidget.addTab(self.addWidget, u"Add")


	def searchTab(self):

		# sFileModel + view tab
		self.sFileTable = QTableView()
		self.sFileTable.setModel(self.sFileModel)
		self.sFileTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
		self.sFileTable.setSelectionBehavior(QAbstractItemView.SelectRows)

		self.setColumnsWidths(self.sFileTable)

		self.searchWidget = QWidget()

		# Horizontal layout
		# Button, Line Edit, Button
		hLayout = QHBoxLayout()
		self.searchBox = QLineEdit()
		self.searchBox.returnPressed.connect(self.searchdb)
		hLayout.addWidget(self.searchBox)

		searchBtn = QPushButton("Search")
		searchBtn.clicked.connect(self.searchdb)
		hLayout.addWidget(searchBtn)

		# Vertical Layout
		vLayout = QVBoxLayout()
		vLayout.addLayout(hLayout)
		vLayout.addWidget(self.sFileTable)

		# sub horiz box
		subHLayout = QHBoxLayout()
		subHLayout.addStretch(1)
		
		editBtn = QPushButton("Edit -->")
		editBtn.clicked.connect(self.addToEditTab)

		subHLayout.addWidget(editBtn)
		vLayout.addLayout(subHLayout)

		self.searchWidget.setLayout(vLayout)
		self.tabWidget.addTab(self.searchWidget, u"Retrieve")


	def editTab(self):
		
		self.eFileTable = QTableView()
		self.eFileTable.setModel(self.eFileModel)
		self.eFileTable.setSelectionBehavior(QAbstractItemView.SelectRows)

		self.setColumnsWidths(self.eFileTable)

		self.editWidget = QWidget()

		vLayout = QVBoxLayout()
		vLayout.addWidget(self.eFileTable)

		dropBtn = QToolButton()
		dropBtn.setDefaultAction(self.dropEditTabAct)

		undBtn = QPushButton("Undo Delete")
		undBtn.clicked.connect(self.undeleteFiles)

		rmvBtn = QPushButton("Delete")
		rmvBtn.clicked.connect(self.deleteFiles)

		cmtBtn = QPushButton("Update")
		cmtBtn.clicked.connect(self.update)

		hLayout = QHBoxLayout()
		hLayout.addWidget(dropBtn)
		hLayout.addStretch(1)
		hLayout.addWidget(undBtn)
		hLayout.addWidget(rmvBtn)
		hLayout.addWidget(cmtBtn)

		vLayout.addLayout(hLayout)

		self.editWidget.setLayout(vLayout)

		self.tabWidget.addTab(self.editWidget, u"Edit")


	def setColumnsWidths(self, table):
		table.setColumnWidth(0, 438)
		table.horizontalHeader().setStretchLastSection(True)


	def undeleteFiles(self):
		delfiles = self.eFileModel.delfiles
		for file in delfiles:
			path, tags = file.path, file.tags
			self.addToModel(self.eFileModel, path, tags, True)
		self.eFileModel.delfiles = []


	# Adds files to the models delete list
	# for removal from the DB on next update()
	def deleteFiles(self):
		indexes = self.getSRIndexes(self.eFileTable)

		for index in indexes:
			self.eFileModel.delList(index.row())
			self.eFileModel.removeRows(index.row())
		self.statusBar().showMessage("Pending Changes")


	# Drop files from a table and model
	def dropFiles(self, table, model):
		indexes = self.getSRIndexes(table)

		for index in indexes:
			model.removeRows(index.row())


	# Inserts files into the DB from the add model
	def insert(self):
		p = self.aFileModel.insert()
		if p:
			msgDuplBox = QMessageBox()
			msgDuplBox.setText('\n'.join(p) + 
				"\n\n...file(s) already being tracked.")
			msgDuplBox.exec_()


	def update(self):
		self.eFileModel.update()

	
	''' Order of user selection matters in the view. As a user
	selects an item it is entered into the list of selected rows.
	To remove the correct items first you have to sort the list,
	then reverse it to remove items from the bottom up to prevent
	a row number pointing at the wrong entry because an entry
	above it was already removed.'''
	def getSRIndexes(self, table):
		indexes = table.selectionModel().selectedRows()
		indexes.sort()
		indexes.reverse()
		return indexes


	def findFilesDlg(self):
		finder = getFilesDlg(self)
		finder.sendPaths.connect(self.addToAddTab)
		finder.show()


	@Slot(list)
	def addToAddTab(self, list):
		for path in list:

			if self.colCheck(self.aFileModel, path):

				self.addToModel(self.aFileModel, path)


	def addToSearchTab(self, qresults):
		if qresults:

			self.sFileModel.reset()

			for file in qresults:

				path,tags = file
				self.addToModel(self.sFileModel, path, tags)


	def addToEditTab(self):
		# Need to make sure what they are adding isn't already
		# present in the edit model's files or delfiles lists
		indexes = self.getSRIndexes(self.sFileTable)

		# save original path as update reference for db
		oldpath = True

		for index in indexes:

			path, tags = self.sFileModel.dataTuple(index)

			if self.colCheck(self.eFileModel, path):
			
				self.addToModel(self.eFileModel, path, tags, oldpath)

				self.sFileModel.removeRows(index.row())


	def addToModel(self, model, path, tags=None, oldpath=False):

			model.insertRows(0)

			ix = model.index(0, 0, QModelIndex())
			model.setData(ix, path, Qt.EditRole, oldpath)

			ix = model.index(0, 1, QModelIndex())
			model.setData(ix, tags, Qt.EditRole, oldpath)


	def colCheck(self, model, path):
		# THIS IS REALLY SLOW
		# Linear search, 
		if model.files:
			for file in model.files:
				if path == file.path:
					return False
		return True


	def searchdb(self):
		thedb = myDB()
		query = thedb.query(self.searchBox.text())
		self.addToSearchTab(query)
Beispiel #54
0
    def _make_total_days_off_panel(self):

        widget = QFrame()
        widget.setObjectName('HorseRegularFrame')

        widget.setFrameShape(QFrame.Panel)
        widget.setFrameShadow(QFrame.Sunken)
        layout = QVBoxLayout()

        #layout.addWidget(QLabel(_("Days off to date")))
        self.day_off_total_duration_labels = dict()
        self.day_off_month_duration_labels = dict()
        self.day_off_labels = dict()

        self._day_off_table_model = QStandardItemModel(10, 3)
        self._day_off_table_model.setHorizontalHeaderLabels(
            [None, None, _("This\nmonth"),
             _("Before")])
        self.day_off_table_view = QTableView(None)
        self.day_off_table_view.setModel(self._day_off_table_model)

        # self.day_off_table_view.setHorizontalHeader(self.headers_view)
        self.day_off_table_view.verticalHeader().hide()
        self.day_off_table_view.setAlternatingRowColors(True)
        self.day_off_table_view.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

        self.day_off_table_view.hide()

        row = 0
        for det in DayEventType.symbols():
            ndx = self._day_off_table_model.index(row, 0)
            self._day_off_table_model.setData(ndx, det.description,
                                              Qt.DisplayRole)

            ndx = self._day_off_table_model.index(row, 1)
            fg, bg = self.DAY_EVENT_PALETTE[det]
            self._day_off_table_model.setData(ndx, QBrush(bg),
                                              Qt.BackgroundRole)
            self._day_off_table_model.setData(ndx, QBrush(fg),
                                              Qt.TextColorRole)
            self._day_off_table_model.setData(ndx,
                                              DayEventType.short_code(det),
                                              Qt.DisplayRole)

            row += 1

        layout.addWidget(self.day_off_table_view)

        grid = QGridLayout()
        self.days_off_layout = grid
        grid.setColumnStretch(3, 1)
        row = 0

        grid.addWidget(QLabel(_('Year')), row, self.YEAR_EVENT_COLUMN)
        grid.addWidget(QLabel(_('Month')), row, self.MONTH_EVENT_COLUMN)
        row += 1

        for det in DayEventType.symbols():
            self.day_off_total_duration_labels[det] = QLabel("-")
            self.day_off_month_duration_labels[det] = QLabel("-")
            self.day_off_labels[det] = QLabel(det.description)

            hlayout = QHBoxLayout()

            sl = QLabel()
            fg, bg = self.DAY_EVENT_PALETTE[det]

            def to_html_rgb(color):
                i = color.red() * 256 * 256 + color.green() * 256 + color.blue(
                )
                return "#{:06X}".format(i)

            p = QPalette()
            p.setColor(QPalette.Window, QColor(bg))
            p.setColor(QPalette.WindowText, QColor(fg))
            sl.setPalette(p)
            sl.setAlignment(Qt.AlignCenter)
            sl.setStyleSheet("border: 2px solid black; background: {}".format(
                to_html_rgb(QColor(bg))))

            t = DayEventType.short_code(det)
            mainlog.debug(t)
            sl.setAutoFillBackground(True)
            sl.setText(t)

            grid.addWidget(sl, row, 0)
            grid.addWidget(self.day_off_labels[det], row, 1)
            grid.addWidget(self.day_off_total_duration_labels[det], row,
                           self.YEAR_EVENT_COLUMN)
            grid.addWidget(self.day_off_month_duration_labels[det], row,
                           self.MONTH_EVENT_COLUMN)

            hlayout.addStretch()

            row += 1

        layout.addLayout(grid)
        layout.addStretch()

        self.day_off_table_view.resizeColumnsToContents()
        # self.day_off_table_view.setMinimumWidth( self.day_off_table_view.width())
        # self.day_off_table_view.resize( self.day_off_table_view.minimumWidth(),
        #                                 self.day_off_table_view.minimumHeight(),)

        widget.setLayout(layout)
        return widget
Beispiel #55
0
    def setupTabs(self):
        """ Setup the various tabs in the AddressWidget. """
        groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"]

        for group in groups:
            proxyModel = QSortFilterProxyModel(self)
            proxyModel.setSourceModel(self.tableModel)
            proxyModel.setDynamicSortFilter(True)

            tableView = QTableView()
            tableView.setModel(proxyModel)
            tableView.setSortingEnabled(True)
            tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
            tableView.horizontalHeader().setStretchLastSection(True)
            tableView.verticalHeader().hide()
            tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
            tableView.setSelectionMode(QAbstractItemView.SingleSelection)

            # This here be the magic: we use the group name (e.g. "ABC") to
            # build the regex for the QSortFilterProxyModel for the group's
            # tab. The regex will end up looking like "^[ABC].*", only
            # allowing this tab to display items where the name starts with
            # "A", "B", or "C". Notice that we set it to be case-insensitive.
            reFilter = "^[%s].*" % group

            proxyModel.setFilterRegExp(QRegExp(reFilter, Qt.CaseInsensitive))
            proxyModel.setFilterKeyColumn(0)  # Filter on the "name" column
            proxyModel.sort(0, Qt.AscendingOrder)

            #tableView.selectionModel().selectionChanged.connect(self.selectionChanged)

            self.addTab(tableView, group)
Beispiel #56
0
class PresenceOverviewWidget(HorsePanel):
    @Slot(QModelIndex)
    def cell_entered(self, ndx):
        employee_id = self._employee_id_on_row(ndx)

        if not employee_id:
            self._show_totals_day_off(None)

        elif employee_id:
            chrono.chrono_start()

            employee = None
            for i in self.employees:
                if i.employee_id == employee_id:
                    employee = i
                    break

            self.detail_subframe.set_title(employee.fullname)
            self._show_totals_day_off(employee_id)

            d = date(
                self.base_date.year, self.base_date.month,
                min(
                    calendar.monthrange(self.base_date.year,
                                        self.base_date.month)[1],
                    max(1, ndx.column())))

            chrono.chrono_click("Retrieveing data")
            tars = dao.task_action_report_dao.get_reports_for_employee_id_on_date(
                employee_id, d)
            work_timetracks = dao.timetrack_dao.all_work_for_employee_date_manual(
                employee_id, d)
            presence_timetracks = dao.timetrack_dao.all_presence_for_employee_date_managed_by_code_full(
                employee_id, d)
            # employee = dao.employee_dao.find_by_id(employee_id)
            special_activities = dao.special_activity_dao.find_on_day(
                employee_id, d)

            chrono.chrono_click("Redrawing")
            self.time_report_view.redraw(datetime(d.year, d.month, d.day, 6,
                                                  0),
                                         tars,
                                         employee_id,
                                         work_timetracks,
                                         presence_timetracks,
                                         special_activities,
                                         view_title=_("Work on {}").format(
                                             date_to_dmy(d, full_month=True)))
            session().close(
            )  # FIXME Put his one line above; but that's tough ! SQLA doesn't help us much here !
            chrono.chrono_click("Session closed")

            # for event_type, duration in self.day_event_totals[employee_id].items():
            #     mainlog.debug("{}{}".format(event_type, duration))

        self._toggle_days_off_actions()

    def _employee_id_on_row(self, row_or_ndx):
        r = row_or_ndx
        if type(r) != int:
            r = row_or_ndx.row()

        return self._table_model.data(self._table_model.index(r, 0),
                                      Qt.UserRole)

    DAY_EVENT_PALETTE = {
        DayEventType.holidays: (Qt.GlobalColor.white, Qt.GlobalColor.red),
        DayEventType.day_off: (Qt.GlobalColor.white, Qt.GlobalColor.darkRed),
        DayEventType.unpaid_day_off:
        (Qt.GlobalColor.black, Qt.GlobalColor.magenta),
        DayEventType.free_day:
        (Qt.GlobalColor.white, Qt.GlobalColor.darkMagenta),
        DayEventType.overtime: (Qt.GlobalColor.black, Qt.GlobalColor.green),
        DayEventType.recuperation:
        (Qt.GlobalColor.white, Qt.GlobalColor.darkGreen),
        DayEventType.unemployment: (Qt.GlobalColor.white, Qt.GlobalColor.blue),
        DayEventType.unemployment_short:
        (Qt.GlobalColor.white, Qt.GlobalColor.darkBlue),
        DayEventType.work_accident: (Qt.GlobalColor.black,
                                     Qt.GlobalColor.yellow),
        DayEventType.sick_leave: (Qt.GlobalColor.white,
                                  Qt.GlobalColor.darkYellow)
    }

    MONTH_EVENT_COLUMN = 2
    YEAR_EVENT_COLUMN = 3

    def _make_total_days_off_panel(self):

        widget = QFrame()
        widget.setObjectName('HorseRegularFrame')

        widget.setFrameShape(QFrame.Panel)
        widget.setFrameShadow(QFrame.Sunken)
        layout = QVBoxLayout()

        #layout.addWidget(QLabel(_("Days off to date")))
        self.day_off_total_duration_labels = dict()
        self.day_off_month_duration_labels = dict()
        self.day_off_labels = dict()

        self._day_off_table_model = QStandardItemModel(10, 3)
        self._day_off_table_model.setHorizontalHeaderLabels(
            [None, None, _("This\nmonth"),
             _("Before")])
        self.day_off_table_view = QTableView(None)
        self.day_off_table_view.setModel(self._day_off_table_model)

        # self.day_off_table_view.setHorizontalHeader(self.headers_view)
        self.day_off_table_view.verticalHeader().hide()
        self.day_off_table_view.setAlternatingRowColors(True)
        self.day_off_table_view.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

        self.day_off_table_view.hide()

        row = 0
        for det in DayEventType.symbols():
            ndx = self._day_off_table_model.index(row, 0)
            self._day_off_table_model.setData(ndx, det.description,
                                              Qt.DisplayRole)

            ndx = self._day_off_table_model.index(row, 1)
            fg, bg = self.DAY_EVENT_PALETTE[det]
            self._day_off_table_model.setData(ndx, QBrush(bg),
                                              Qt.BackgroundRole)
            self._day_off_table_model.setData(ndx, QBrush(fg),
                                              Qt.TextColorRole)
            self._day_off_table_model.setData(ndx,
                                              DayEventType.short_code(det),
                                              Qt.DisplayRole)

            row += 1

        layout.addWidget(self.day_off_table_view)

        grid = QGridLayout()
        self.days_off_layout = grid
        grid.setColumnStretch(3, 1)
        row = 0

        grid.addWidget(QLabel(_('Year')), row, self.YEAR_EVENT_COLUMN)
        grid.addWidget(QLabel(_('Month')), row, self.MONTH_EVENT_COLUMN)
        row += 1

        for det in DayEventType.symbols():
            self.day_off_total_duration_labels[det] = QLabel("-")
            self.day_off_month_duration_labels[det] = QLabel("-")
            self.day_off_labels[det] = QLabel(det.description)

            hlayout = QHBoxLayout()

            sl = QLabel()
            fg, bg = self.DAY_EVENT_PALETTE[det]

            def to_html_rgb(color):
                i = color.red() * 256 * 256 + color.green() * 256 + color.blue(
                )
                return "#{:06X}".format(i)

            p = QPalette()
            p.setColor(QPalette.Window, QColor(bg))
            p.setColor(QPalette.WindowText, QColor(fg))
            sl.setPalette(p)
            sl.setAlignment(Qt.AlignCenter)
            sl.setStyleSheet("border: 2px solid black; background: {}".format(
                to_html_rgb(QColor(bg))))

            t = DayEventType.short_code(det)
            mainlog.debug(t)
            sl.setAutoFillBackground(True)
            sl.setText(t)

            grid.addWidget(sl, row, 0)
            grid.addWidget(self.day_off_labels[det], row, 1)
            grid.addWidget(self.day_off_total_duration_labels[det], row,
                           self.YEAR_EVENT_COLUMN)
            grid.addWidget(self.day_off_month_duration_labels[det], row,
                           self.MONTH_EVENT_COLUMN)

            hlayout.addStretch()

            row += 1

        layout.addLayout(grid)
        layout.addStretch()

        self.day_off_table_view.resizeColumnsToContents()
        # self.day_off_table_view.setMinimumWidth( self.day_off_table_view.width())
        # self.day_off_table_view.resize( self.day_off_table_view.minimumWidth(),
        #                                 self.day_off_table_view.minimumHeight(),)

        widget.setLayout(layout)
        return widget

    def _show_totals_day_off(self, employee_id):

        mainlog.debug("_show_totals_day_off : {}".format(employee_id))

        def form_layout_row_set_visible(layout, row_ndx, is_visible):
            for i in range(layout.columnCount()):
                l = layout.itemAtPosition(row_ndx, i)
                if l and l.widget():
                    l.widget().setVisible(is_visible)

        det_to_show = dict()

        row = 0
        for det in DayEventType.symbols():

            yearly = 0
            if employee_id in self.all_events_in_year:
                if det in self.all_events_in_year[employee_id]:
                    yearly = nice_round(
                        self.all_events_in_year[employee_id][det])

            monthly = 0
            if employee_id in self.day_event_totals:
                if det in self.day_event_totals[employee_id]:
                    monthly = nice_round(
                        self.day_event_totals[employee_id][det])

                # ndx = self._day_off_table_model.index(row,self.YEAR_EVENT_COLUMN)
                # self._day_off_table_model.setData(ndx, v, Qt.DisplayRole)

            if yearly or monthly:
                det_to_show[det] = {'monthly': monthly, 'yearly': yearly}

        if det_to_show:
            # If there are some days spent on some counters, then we display
            # those counters *only*
            mainlog.debug("_show_totals_day_off : showing some events ".format(
                str(det_to_show)))
            row = 0
            for det in DayEventType.symbols():
                if det in det_to_show:
                    monthly = det_to_show[det]['monthly']
                    yearly = det_to_show[det]['yearly']
                    form_layout_row_set_visible(self.days_off_layout, row + 1,
                                                True)
                    self.day_off_total_duration_labels[det].setText(yearly
                                                                    or '-')
                    self.day_off_month_duration_labels[det].setText(monthly
                                                                    or '-')
                else:
                    form_layout_row_set_visible(self.days_off_layout, row + 1,
                                                False)
        else:
            # If there are no days spent on any counter, then we display
            # all counters at the 0 mark.
            mainlog.debug("_show_totals_day_off : showing no event")
            row = 0
            for det in DayEventType.symbols():
                form_layout_row_set_visible(self.days_off_layout, row + 1,
                                            True)
                row += 1

        # self.day_off_table_view.resizeColumnsToContents()

        self.days_off_panel.parent().update()

    @Slot()
    def refresh_action(self):
        global dao

        # mainlog.debug("refresh action started")
        self.hours_per_pers_subframe.set_title(date_to_my(
            self.base_date, True))

        chrono.chrono_start()
        all_events_in_month = people_admin_service.events_for_month(
            self.base_date)

        employee_with_events = [
            event.employee_id for event in all_events_in_month
        ]

        # mainlog.debug(all_events_in_month)

        self.all_events_in_year = people_admin_service.events_for_year(
            self.base_date.year)
        self.all_presences = all_presences = dao.employee_dao.presence_overview_for_month(
            self.base_date)

        all_correction_times = dict()
        for s in dao.month_time_synthesis_dao.load_all_synthesis(
                self.base_date.year, self.base_date.month):
            all_correction_times[s.employee_id] = s.correction_time

        special_activities = dao.special_activity_dao.find_on_month(
            self.base_date)

        employees = list(
            filter(
                lambda e: e.is_active or e.employee_id in all_presences or e.
                employee_id in all_correction_times or e.employee_id in
                special_activities or e.employee_id in employee_with_events,
                dao.employee_dao.list_overview()))
        self.employees = employees

        chrono.chrono_click()

        day_max = calendar.monthrange(self.base_date.year,
                                      self.base_date.month)[1]
        t_start = datetime(self.base_date.year, self.base_date.month, 1)
        t_end = datetime(self.base_date.year, self.base_date.month, day_max,
                         23, 59, 59, 999999)

        self._table_model.setRowCount(len(employees))
        self._table_model.setColumnCount(1 + day_max + 3)

        headers = QStandardItemModel(1, 1 + day_max + 3)

        headers.setHeaderData(0, Qt.Orientation.Horizontal, _("Employee"))
        for i in range(day_max):
            headers.setHeaderData(i + 1, Qt.Orientation.Horizontal,
                                  "{}".format(i + 1))
        headers.setHeaderData(day_max + 1, Qt.Orientation.Horizontal,
                              _("Correction"))
        headers.setHeaderData(day_max + 2, Qt.Orientation.Horizontal,
                              _("Total"))
        headers.setHeaderData(day_max + 3, Qt.Orientation.Horizontal,
                              _("Days off"))

        self.headers_view.setModel(
            headers)  # qt's doc : The view does *not* take ownership
        self.header_model = headers
        self.headers_view.setModel(
            self.header_model)  # qt's doc : The view does *not* take ownership

        # Compute all mondays indices
        monday = 0
        if t_start.weekday() > 0:
            monday = 7 - t_start.weekday()
        all_mondays = []

        while monday < day_max:
            all_mondays.append(monday)
            monday += 7

        today = date.today()

        # mainlog.debug("Running on employees")
        for row in range(self._table_model.rowCount()):

            # Clear the line
            for col in range(0, 32):
                ndx = self._table_model.index(row, col)
                self._table_model.setData(ndx, None, Qt.BackgroundRole)
                self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black),
                                          Qt.TextColorRole)
                self._table_model.setData(ndx, None, Qt.DisplayRole)
                self._table_model.setData(ndx, None, Qt.UserRole)
                self._table_model.setData(ndx, None, Qt.UserRole + 1)
                #     else:
                #         self._table_model.setData(ndx,None,Qt.BackgroundRole)

                # else:
                #     self._table_model.setData(ndx,None,Qt.DisplayRole)
                #     self._table_model.setData(ndx,None,Qt.BackgroundRole)

            # Mark mondays
            for col in all_mondays:
                # col + 1 to account for the employee column
                self._table_model.setData(
                    self._table_model.index(row, col + 1),
                    QBrush(QColor(230, 230, 255)), Qt.BackgroundRole)

            # Mark today
            if today.month == self.base_date.month and today.year == self.base_date.year:
                self._table_model.setData(
                    self._table_model.index(row, today.day),
                    QBrush(QColor(255, 255, 128)), Qt.BackgroundRole)

        row = 0
        for employee in employees:  # employees are sorted

            self._table_model.setData(self._table_model.index(row, 0),
                                      employee.fullname,
                                      Qt.DisplayRole)  # FIXME Use a delegate
            self._table_model.setData(self._table_model.index(row, 0),
                                      employee.employee_id,
                                      Qt.UserRole)  # FIXME Use a delegate

            correction = 0
            if employee.employee_id in all_correction_times:
                correction = all_correction_times[employee.employee_id]
                self._table_model.setData(
                    self._table_model.index(row, day_max + 1),
                    duration_to_hm(correction, short_unit=True),
                    Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 1), None,
                    Qt.DisplayRole)

            presence = 0
            if employee.employee_id in all_presences and len(
                    all_presences[employee.employee_id]) > 0:
                import functools
                presence = functools.reduce(
                    lambda acc, s: acc + s,
                    all_presences[employee.employee_id], 0)
            presence += correction

            if presence != 0:
                self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black),
                                          Qt.TextColorRole)
                self._table_model.setData(
                    self._table_model.index(row, day_max + 2),
                    duration_to_hm(presence, short_unit=True), Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 2), None,
                    Qt.DisplayRole)

            if employee.employee_id in all_presences and len(
                    all_presences[employee.employee_id]) > 0:
                for b in range(len(all_presences[employee.employee_id])):
                    ndx = self._table_model.index(row, b + 1)

                    p = all_presences[employee.employee_id][b]

                    if p > 0:
                        self._table_model.setData(
                            ndx, duration_to_hm(p, short_unit=True),
                            Qt.DisplayRole)
                        self._table_model.setData(ndx, p, Qt.UserRole)

                        if p >= 4 and p <= 8:
                            # Regular work load
                            self._table_model.setData(
                                ndx, QBrush(QColor(192, 255, 192)),
                                Qt.BackgroundRole)
                        elif p > 8 or (p < 4 and p > 0):
                            # Problematic work load
                            self._table_model.setData(
                                ndx, QBrush(QColor(255, 192, 192)),
                                Qt.BackgroundRole)

            if employee.employee_id in special_activities:
                sa_of_employee = special_activities[employee.employee_id]

                for sa in sa_of_employee:
                    start = max(t_start, sa.start_time)
                    end = min(t_end, sa.end_time)

                    for i in range(start.day, end.day + 1):
                        ndx = self._table_model.index(row, i)
                        self._table_model.setData(ndx,
                                                  QBrush(QColor(255, 128, 0)),
                                                  Qt.BackgroundRole)

                # self._table_model.setData(self._table_model.index(row,b+1),Qt.AlignRight | Qt.AlignVCenter,Qt.TextAlignmentRole)
            row += 1

        # Display day events

        employee_id_to_row = dict()  # little accelerator
        for row in range(len(employees)):
            employee_id_to_row[employees[row].employee_id] = row

        # Compute days off totals and show them

        self.day_event_totals = dict([(e.employee_id, dict())
                                      for e in employees])
        for day_event in all_events_in_month:
            # mainlog.debug("employee_id = {}".format(day_event.employee_id))
            # if day_event.employee_id not in self.day_event_totals:
            #    mainlog.debug(self.day_event_totals)

            t = self.day_event_totals[day_event.employee_id]
            if day_event.event_type not in t:
                t[day_event.event_type] = day_event.duration
            else:
                t[day_event.event_type] += day_event.duration

        for employee in employees:  # employees are sorted
            t = self.day_event_totals[employee.employee_id]
            mainlog.debug(t)
            total_off = sum(t.values())
            mainlog.debug(total_off)
            row = employee_id_to_row[employee.employee_id]
            mainlog.debug(row)
            if total_off:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 3),
                    nice_round(total_off), Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 3), None,
                    Qt.DisplayRole)

        # Show days off

        for day_event in all_events_in_month:
            row = employee_id_to_row[day_event.employee_id]
            col = day_event.date.day

            fg = bg = None
            if day_event.event_type in self.DAY_EVENT_PALETTE:
                fg, bg = self.DAY_EVENT_PALETTE[day_event.event_type]
            else:
                fg, bg = Qt.GlobalColor.red, Qt.GlobalColor.gray

            ndx = self._table_model.index(row, col)

            self._table_model.setData(ndx, day_event.day_event_id,
                                      Qt.UserRole + 1)

            # The problem here is to nicely blend the fact
            # that you can have a day event mixed with actual work
            # the very same day. Here's a poor man solution.

            active_time = self._table_model.data(ndx, Qt.UserRole)
            if not active_time:
                self._table_model.setData(
                    ndx, DayEventType.short_code(day_event.event_type),
                    Qt.DisplayRole)

                self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole)
                self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole)
            else:
                self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole)
                self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole)

                self._table_model.setData(
                    ndx,
                    duration_to_hm(active_time, short_unit=True) +
                    DayEventType.short_code(day_event.event_type),
                    Qt.DisplayRole)

        chrono.chrono_click()

        #for i in range(len(all_mondays)):
        self.table_view.resizeColumnsToContents()

        # mainlog.debug("Reset selection")
        ndx = self.table_view.currentIndex()

        self.table_view.selectionModel().clear()
        # self.table_view.selectionModel().clearSelection()
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        self.table_view.selectionModel().setCurrentIndex(
            self.table_view.model().index(ndx.row(), ndx.column()),
            QItemSelectionModel.Select)

        self.cell_entered(self.table_view.currentIndex())

    @Slot()
    def edit_tars(self):

        employee_id = self._employee_id_on_row(self.table_view.currentIndex())

        d = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1],
                max(1, ndx.column())))

        dialog = TimeReportingScannerDialog(self)
        dialog.set_data(datetime(d.year, d.month, d.day, 6, 0), employee_id)
        dialog.exec_()

        if dialog.result() == QDialog.Accepted:
            # pub.sendMessage('time_report.changed')
            self.timetrack_changed.emit()
            self.refresh_action()

    @Slot()
    def show_actions(self):
        button = self.action_menu.parent()
        p = button.mapToGlobal(QPoint(0, button.height()))
        self.action_menu.exec_(p)

    @Slot()
    def delete_holidays(self):
        ndx = self.table_view.currentIndex()
        employee_id = self._employee_id_on_row(ndx)
        d = date(self.base_date.year, self.base_date.month, ndx.column())

        if dao.special_activity_dao.delete_by_employee_and_date(
                employee_id, d):
            self.refresh_panel()

    @Slot()
    def create_holidays(self):
        employee_id = self._employee_id_on_row(self.table_view.currentIndex())

        left_col = 1000
        right_col = 0
        for ndx in self.table_view.selectionModel().selectedIndexes():
            c = ndx.column()
            left_col = min(c, left_col)
            right_col = max(c, right_col)

        d_start = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1], max(1,
                                                                  left_col)))

        d_end = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1],
                max(1, right_col)))

        dialog = HolidaysDialog(self)

        sa = SpecialActivity()
        sa.employee_id = employee_id
        sa.reporter_id = user_session.user_id
        sa.encoding_date = date.today()
        sa.start_time = datetime(d_start.year, d_start.month, d_start.day, 6,
                                 0)
        sa.end_time = datetime(d_end.year, d_end.month, d_end.day, 14, 0)

        dialog.setup(sa, dao.employee_dao.find_by_id(employee_id).fullname)

        # dialog.set_data(employee,self.base_date,c)
        dialog.exec_()
        if dialog.result() == QDialog.Accepted:
            dao.special_activity_dao.save(sa)
            self.refresh_action()

    @Slot()
    def edit_month_correction(self):
        employee_id = self._employee_id_on_row(self.table_view.currentIndex())

        if employee_id:
            employee = dao.employee_dao.find_by_id(employee_id)
            c = dao.month_time_synthesis_dao.load_correction_time(
                employee_id, self.base_date.year, self.base_date.month)

            dialog = MonthTimeCorrectionDialog(self)
            dialog.set_data(employee.fullname, self.base_date, c)
            dialog.exec_()
            if dialog.result() == QDialog.Accepted:
                c = dao.month_time_synthesis_dao.save(employee_id,
                                                      self.base_date.year,
                                                      self.base_date.month,
                                                      dialog.correction_time)
                self.refresh_action()

    @Slot()
    def month_today(self):
        self.base_date = date.today()
        self.refresh_action()

    @Slot()
    def month_before(self):
        m = self.base_date.month

        if m > 1:
            self.base_date = date(self.base_date.year, m - 1, 1)
        else:
            self.base_date = date(self.base_date.year - 1, 12, 1)
        self.refresh_action()

    @Slot()
    def month_after(self):
        m = self.base_date.month

        if self.base_date.year < date.today().year + 1 \
                or m < date.today().month:
            if m < 12:
                self.base_date = date(self.base_date.year, m + 1, 1)
            else:
                self.base_date = date(self.base_date.year + 1, 1, 1)
            self.refresh_action()

    @Slot()
    def edit_timetrack_no_ndx(self):
        ndx = self.table_view.currentIndex()
        if ndx.isValid() and ndx.column() >= 0 and ndx.row() >= 0:
            self.edit_timetrack(ndx)
        else:
            showWarningBox(_("Can't edit"),
                           _("You must first select a day/person."))

    timetrack_changed = Signal()

    @Slot(QModelIndex)
    def edit_timetrack(self, ndx):
        global dao
        global user_session

        if ndx.column() >= 1:
            edit_date = date(
                self.base_date.year, self.base_date.month,
                ndx.column())  # +1 already in because of employee's names
            employee_id = self._employee_id_on_row(ndx)

            tars = dao.task_action_report_dao.get_reports_for_employee_id_on_date(
                employee_id, edit_date)

            if len(tars) == 0:

                d = EditTimeTracksDialog(self, dao, edit_date)
                d.set_employee_and_date(employee_id, edit_date)
                d.exec_()
                if d.result() == QDialog.Accepted:
                    self.refresh_action()
                    self.timetrack_changed.emit()
                d.deleteLater()

            else:
                edit_date = datetime(self.base_date.year,
                                     self.base_date.month,
                                     ndx.column(),
                                     hour=6)
                from koi.TimeReportingScanner import TimeReportingScannerDialog
                d = TimeReportingScannerDialog(self)
                d.set_data(edit_date, employee_id)  # or 16
                d.exec_()
                if d.result() == QDialog.Accepted:
                    self.refresh_action()
                    self.timetrack_changed.emit()
                d.deleteLater()

    @Slot()
    def editTaskActionReports(self):
        if not user_session.has_any_roles(['TimeTrackModify']):
            return

        m = self.base_date.month
        ndx = self.table_view.currentIndex()

        if ndx.isValid() and ndx.column() >= 0 and ndx.row() >= 0:
            edit_date = date(
                self.base_date.year, m,
                ndx.column())  # +1 already in because of employee's names
            employee = self._table_model.data(
                self._table_model.index(ndx.row(), 0),
                Qt.UserRole)  # FIXME Use a delegate

            d = EditTaskActionReportsDialog(dao, self, edit_date)
            d.set_employee_date(employee, edit_date)
            d.exec_()
            if d.result() == QDialog.Accepted:
                self.refresh_action()
            d.deleteLater()
        else:
            showWarningBox(_("Can't edit"),
                           _("You must first select a day/person."))

    # @Slot(QModelIndex)
    # def timetrack_changed(self,ndx):

    #     selected_timetrack = self.controller.model.object_at(ndx)

    #     # Update the colors in the timetrack views
    #     # to show what action reports correspond to the
    #     # selected timetrack

    #     self.controller_actions.model.current_timetrack = selected_timetrack
    #     self.controller_actions.model.beginResetModel()
    #     self.controller_actions.model.endResetModel()

    #     # Make sure the first of the action reports is shown in the
    #     # table

    #     action_reports = self.controller_actions.model.objects
    #     for i in range(len(action_reports)-1,-1,-1):
    #         if action_reports[i] and action_reports[i].timetrack == selected_timetrack:
    #             self.controller_actions.view.scrollTo(self.controller_actions.model.index(i,0))
    #             break

    def _make_table_header(self):
        pass

    def __init__(self, parent, find_order_action_slot):
        super(PresenceOverviewWidget, self).__init__(parent)

        self.set_panel_title(_("Presence overview"))
        self.base_date = date.today()

        headers = QStandardItemModel(1, 31 + 3)
        self._table_model = QStandardItemModel(1, 31 + 3, None)

        self.headers_view = QHeaderView(Qt.Orientation.Horizontal, self)
        self.header_model = headers
        self.headers_view.setResizeMode(QHeaderView.ResizeToContents)
        self.headers_view.setModel(
            self.header_model)  # qt's doc : The view does *not* take ownership

        self.table_view = TableViewSignaledEvents(None)
        self.table_view.setModel(self._table_model)

        self.table_view.setHorizontalHeader(self.headers_view)
        self.table_view.verticalHeader().hide()
        self.table_view.setAlternatingRowColors(True)
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.table_view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table_view.customContextMenuRequested.connect(
            self.popup_context_menu)

        self.copy_action = QAction(_("Copy order parts"), self.table_view)
        self.copy_action.triggered.connect(self.copy_slot)
        self.copy_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_C))
        self.copy_action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        self.table_view.addAction(self.copy_action)

        self.select_all_action = QAction(_("Select all"), self.table_view)
        self.select_all_action.triggered.connect(self.select_all_slot)
        self.select_all_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_A))
        self.select_all_action.setShortcutContext(
            Qt.WidgetWithChildrenShortcut)
        self.table_view.addAction(self.select_all_action)

        # self.table_view.setSelectionBehavior(QAbstractItemView.SelectItems)
        # self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)

        navbar = NavBar(self, [(_("Month before"), self.month_before),
                               (_("Today"), self.month_today),
                               (_("Action"), self.show_actions),
                               (_("Month after"), self.month_after),
                               (_("Find"), find_order_action_slot)])

        self.action_menu = QMenu(navbar.buttons[2])
        navbar.buttons[2].setObjectName("specialMenuButton")
        navbar.buttons[4].setObjectName("specialMenuButton")

        self._make_days_off_menu_and_action_group()

        list_actions = [  # (_("Edit"),self.edit_tars, None, None),
            (_("Edit"), self.edit_timetrack_no_ndx, None, None),
            (_("Month correction"), self.edit_month_correction, None,
             [RoleType.modify_monthly_time_track_correction]),
            (self.days_off_menu, None), (self.copy_action, None),
            (self.select_all_action, None)
        ]

        # (_("Insert holidays"),self.create_holidays, None, None),
        # (_("Delete holidays"),self.delete_holidays, None, None) ]

        populate_menu(self.action_menu, self, list_actions)

        # mainlog.debug("tile widget")
        self.title_box = TitleWidget(_("Presence Overview"), self, navbar)
        self.vlayout = QVBoxLayout(self)
        self.vlayout.setObjectName("Vlayout")
        self.vlayout.addWidget(self.title_box)

        self.hours_per_pers_subframe = SubFrame(_("Overview"), self.table_view,
                                                self)
        self.vlayout.addWidget(self.hours_per_pers_subframe)

        self.time_report_view = TimeReportView(self)

        self.days_off_panel = self._make_total_days_off_panel()
        vbox = QVBoxLayout()
        vbox.addWidget(self.days_off_panel)
        vbox.addStretch()
        vbox.setStretch(0, 0)
        vbox.setStretch(1, 1)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.time_report_view)
        hlayout.addLayout(vbox)
        hlayout.setStretch(0, 1)
        self.detail_subframe = SubFrame(_("Day"), hlayout, self)

        self.vlayout.addWidget(self.detail_subframe)

        self.setLayout(self.vlayout)

        # dbox = QVBoxLayout()
        # dbox.addWidget(QLabel("kjkljkj"))

        # self.total_active_hours = LabeledValue(_("Total activity"))
        # dbox.addWidget(self.total_active_hours)

        # hbox = QHBoxLayout()
        # hbox.addWidget(self.table_view)
        # hbox.addLayout(dbox)

        # self.selection_model = self.table_view.selectionModel()
        # mainlog.debug(m)
        #sm = QItemSelectionModel(self.table_view.model())
        #sm.setModel(self.table_view.model())
        # self.table_view.setSelectionModel(self.selection_model)

        self.table_view.selectionModel().currentChanged.connect(
            self.cell_entered)

        self.table_view.doubleClickedCell.connect(self.edit_timetrack)

    def _selection_to_period(self):
        left_col = 1000
        right_col = 0
        for ndx in self.table_view.selectionModel().selectedIndexes():
            c = ndx.column()
            left_col = min(c, left_col)
            right_col = max(c, right_col)

        d_start = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1], max(1,
                                                                  left_col)))

        d_end = date(
            self.base_date.year, self.base_date.month,
            min(
                calendar.monthrange(self.base_date.year,
                                    self.base_date.month)[1],
                max(1, right_col)))

        return d_start, d_end

    def _toggle_days_off_actions(self):
        day_max = calendar.monthrange(self.base_date.year,
                                      self.base_date.month)[1]

        ndx = self.table_view.currentIndex()

        can_add = can_remove = False

        if ndx.column() >= 1 and ndx.column() <= day_max:

            day_event_id = ndx.data(Qt.UserRole + 1)

            can_add = True

            # if not day_event_id:
            #     day = ndx.column() - 1
            #
            #     employee_id = self._employee_id_on_row(ndx)
            #     if employee_id in self.all_presences:
            #         if not self.all_presences[employee_id][day]:
            #             can_add = True
            #         else:
            #             can_add = True
            #     else:
            #         can_add = True

            can_remove = day_event_id is not None

        self.days_off_add_submenu.setEnabled(can_add)
        for actions in self.days_off_action_group.actions():
            actions.setEnabled(can_add)

        self.day_off_remove_action.setEnabled(can_remove)

    def _add_day_off(self, action):

        if action.data() != 'Remove':

            day_event_type, day_event_duration = action.data()
            day_event_type = DayEventType.from_str(day_event_type)

            mainlog.debug("selected action {} {}".format(
                day_event_type, day_event_duration))

            ndx = self.table_view.currentIndex()
            day_event_id = ndx.data(Qt.UserRole + 1)

            # if day_event_id:
            #     showWarningBox(_("There's already a day off here"))
            #     return

            employee_id = self._employee_id_on_row(ndx)
            if employee_id in self.all_presences:
                day = ndx.column() - 1
                mainlog.debug("_add_day_off : employee_id={}, day={}".format(
                    employee_id, day))
                mainlog.debug(self.all_presences[employee_id])
                mainlog.debug(type(self.all_presences[employee_id]))

                # if self.all_presences[employee_id][day]:
                #     showWarningBox(_("One can't add day off where there is activity"))
                #     return
            else:
                mainlog.debug(
                    "_add_day_off : employee_id={} not yet known".format(
                        employee_id))

            day_event = DayEvent()
            day_event.employee_id = employee_id
            day_event.event_type = day_event_type

            day, last_day = self._selection_to_period()

            if day_event_duration in (0.5, 1):
                days_durations = [(day, day_event_duration)]
            else:
                days_durations = []
                day, last_day = self._selection_to_period()
                while day <= last_day:
                    days_durations.append(
                        (day, 1))  # One full work day on the day
                    day += timedelta(1)

            # mainlog.debug(days_durations)
            mainlog.debug("Creating day event of type {}".format(
                day_event.event_type))

            try:
                people_admin_service.set_event_on_days(day_event,
                                                       days_durations)
            except ServerException as ex:
                showErrorBox(ex.translated_message)

            self.refresh_action()

    def _remove_day_off(self):
        # Grab all the selected events

        event_ids = []
        for ndx in self.table_view.selectionModel().selectedIndexes():
            day_event_id = ndx.data(Qt.UserRole + 1)
            if day_event_id:
                mainlog.debug("Removing event: {}".format(day_event_id))
                event_ids.append(day_event_id)

        # Remove them

        if event_ids:
            people_admin_service.remove_events(event_ids)
            self.refresh_action()

    def _make_days_off_menu_and_action_group(self):
        # We use a action group to be able to use the data() of actions
        # when action is tigerred

        # Call this ONLY ONCE because there are signal/slot connections.

        self.days_off_menu = QMenu(_("Day off"))
        self.days_off_add_submenu = QMenu(_("Set day off"))
        self.days_off_action_group = QActionGroup(self)

        for det in DayEventType.symbols():
            a_one = QAction(_("Set one day"), self.days_off_action_group)
            a_one.setData((det.value, 1))

            a_half = QAction(_("Set half day"), self.days_off_action_group)
            a_half.setData((det.value, 0.5))

            a_period = QAction(_("Set period"), self.days_off_action_group)
            a_period.setData((det.value, 2))

            self.days_off_action_group.addAction(a_one)
            self.days_off_action_group.addAction(a_half)
            self.days_off_action_group.addAction(a_period)

            m = QMenu(_("Set time off for {}").format(det.description))
            m.addAction(a_one)
            m.addAction(a_half)
            m.addAction(a_period)
            self.days_off_add_submenu.addMenu(m)

        self.days_off_action_group.triggered.connect(self._add_day_off)

        self.day_off_remove_action = QAction(_("Remove day off"), self)
        self.day_off_remove_action.triggered.connect(self._remove_day_off)

        # Now we have the actions, we build the menu

        self.days_off_menu.addMenu(self.days_off_add_submenu)
        self.days_off_menu.addAction(self.day_off_remove_action)

    @Slot(QPoint)
    def popup_context_menu(self, position):
        self.days_off_menu.exec_(QCursor.pos())

    @Slot()
    def select_all_slot(self):
        m = self.table_view.model()
        all = QItemSelection(m.index(0, 0),
                             m.index(m.rowCount() - 1,
                                     m.columnCount() - 1))
        self.table_view.selectionModel().select(all,
                                                QItemSelectionModel.Select)

    @Slot()
    def copy_slot(self):

        # Collect the rows indices

        indices = self.table_view.selectedIndexes()

        if not indices:
            return

        min_row = max_row = indices[0].row()
        min_col = max_col = indices[0].column()

        def min_max(minimum, v, maximum):
            if v < minimum:
                return v, maximum
            elif v > maximum:
                return minimum, v
            else:
                return minimum, maximum

        for ndx in self.table_view.selectedIndexes():
            min_row, max_row = min_max(min_row, ndx.row(), max_row)
            min_col, max_col = min_max(min_col, ndx.column(), max_col)

        mainlog.debug("Copy from {},{} to {},{}".format(
            min_row, min_col, max_row, max_col))

        day_max = calendar.monthrange(self.base_date.year,
                                      self.base_date.month)[1]

        s = ""
        for r in range(min_row, max_row + 1):
            d = []
            for c in range(min_col, max_col + 1):
                ndx = self._table_model.item(r, c)

                if c == 0 or c > day_max:
                    d.append(ndx.data(Qt.DisplayRole) or "")
                else:
                    t = ndx.data(Qt.UserRole + 1)  # Day off
                    if t:
                        t = ndx.data(Qt.DisplayRole)
                    else:
                        hours = ndx.data(Qt.UserRole)  # Activity hours
                        if hours is not None:
                            t = str(hours).replace('.', ',')
                        else:
                            t = ""

                    d.append(t)

            s += "\t".join(d) + u"\n"

        QApplication.clipboard().setText(s)
    def testReferenceCounting(self):
        '''Tests reference count of model object referred by view objects.'''
        model1 = TestModel()
        refcount1 = getrefcount(model1)
        view1 = QTableView()
        view1.setModel(model1)
        self.assertEqual(getrefcount(view1.model()), refcount1 + 1)

        view2 = QTableView()
        view2.setModel(model1)
        self.assertEqual(getrefcount(view2.model()), refcount1 + 2)

        model2 = TestModel()
        view2.setModel(model2)
        self.assertEqual(getrefcount(view1.model()), refcount1 + 1)
Beispiel #58
0
    def _addtabondemand(self, thread):
        """Adds a new tab for the given thread, if it doesn't exist yet.
        If it does, it will be made the current tab.
        @param thread Instance of FourChanThreahHeader
        """
        i = thread.id_()
        if not i in self._openthreads.keys():
            table = QTableView(self)
            table.setModel(LiveFeedModel(self))
            table.setAlternatingRowColors(True)
            table.setEditTriggers(QAbstractItemView.NoEditTriggers)
            table.setIconSize(QSize(192, 192))
            table.horizontalHeader().setVisible(False)
            table.horizontalHeader().setDefaultSectionSize(192)
            table.horizontalHeader().setStretchLastSection(True)
            table.verticalHeader().setVisible(False)
            table.verticalHeader().setDefaultSectionSize(192)

            table.doubleClicked.connect(self._showlivepost)

            idx = self.tabPosts.addTab(table, "/%s/%s" % (thread.forum(), i))
            self._openthreads[i] = (idx, thread, table)
            fct = FourChanThread(
                    FourChanThreadUrl(thread.url()), self._masterobserver)
            fct.postadded.connect(self._updatethread)
            self._masterobserver.addobserver(
                    FourChanThreadObserver(fct, parent=self))
            fct.refresh(True)
        else:
            idx = self._openthreads[i][0]
        self.tabPosts.setCurrentIndex(idx)
Beispiel #59
0
    def _initUI(self):
        # Variables
        model_forcing = _InteractionForcingTableModel()

        # Actions
        act_add_forcing = QAction(getIcon("list-add"), "Add interaction forcing", self)
        act_remove_forcing = QAction(getIcon("list-remove"), "Remove interaction forcing", self)

        # Widgets
        self._lbl_elastic_scattering_c1 = QLabel('C1')
        self._lbl_elastic_scattering_c1.setStyleSheet("color: blue")
        self._txt_elastic_scattering_c1 = MultiNumericalLineEdit()
        self._txt_elastic_scattering_c1.setValidator(_ElasticScatteringValidator())
        self._txt_elastic_scattering_c1.setValues([0.0])

        self._lbl_elastic_scattering_c2 = QLabel('C2')
        self._lbl_elastic_scattering_c2.setStyleSheet("color: blue")
        self._txt_elastic_scattering_c2 = MultiNumericalLineEdit()
        self._txt_elastic_scattering_c2.setValidator(_ElasticScatteringValidator())
        self._txt_elastic_scattering_c2.setValues([0.0])

        self._lbl_cutoff_energy_inelastic = QLabel('Inelastic collisions')
        self._lbl_cutoff_energy_inelastic.setStyleSheet("color: blue")
        self._txt_cutoff_energy_inelastic = MultiNumericalLineEdit()
        self._txt_cutoff_energy_inelastic.setValidator(_CutoffEnergyValidator())
        self._txt_cutoff_energy_inelastic.setValues([50.0])
        self._cb_cutoff_energy_inelastic = UnitComboBox('eV')

        self._lbl_cutoff_energy_bremsstrahlung = QLabel('Bremsstrahlung emission')
        self._lbl_cutoff_energy_bremsstrahlung.setStyleSheet("color: blue")
        self._txt_cutoff_energy_bremsstrahlung = MultiNumericalLineEdit()
        self._txt_cutoff_energy_bremsstrahlung.setValidator(_CutoffEnergyValidator())
        self._txt_cutoff_energy_bremsstrahlung.setValues([50.0])
        self._cb_cutoff_energy_bremsstrahlung = UnitComboBox('eV')

        self._lbl_maximum_step_length = QLabel('Maximum step length')
        self._lbl_maximum_step_length.setStyleSheet("color: blue")
        self._txt_maximum_step_length = MultiNumericalLineEdit()
        self._txt_maximum_step_length.setValidator(_MaximumStepLengthValidator())
        self._txt_maximum_step_length.setValues([1e15])
        self._cb_maximum_step_length_unit = UnitComboBox('m')

        self._tbl_forcing = QTableView()
        self._tbl_forcing.setModel(model_forcing)
        self._tbl_forcing.setItemDelegate(_InteractionForcingDelegate())
        header = self._tbl_forcing.horizontalHeader()
        header.setResizeMode(QHeaderView.Stretch)

        self._tlb_forcing = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._tlb_forcing.addWidget(spacer)
        self._tlb_forcing.addAction(act_add_forcing)
        self._tlb_forcing.addAction(act_remove_forcing)

        # Layouts
        layout = QHBoxLayout()

        layout.addLayout(_MaterialDialog._initUI(self), 1)

        frame = QFrame()
        frame.setFrameShape(QFrame.VLine)
        frame.setFrameShadow(QFrame.Sunken)
        layout.addWidget(frame)

        sublayout = QVBoxLayout()

        box_elastic_scattering = QGroupBox("Elastic scattering")
        boxlayout = QFormLayout()
        boxlayout.addRow(self._lbl_elastic_scattering_c1, self._txt_elastic_scattering_c1)
        boxlayout.addRow(self._lbl_elastic_scattering_c2, self._txt_elastic_scattering_c2)
        box_elastic_scattering.setLayout(boxlayout)
        sublayout.addWidget(box_elastic_scattering)

        box_cutoff_energy = QGroupBox("Cutoff energy")
        boxlayout = QFormLayout()
        boxsublayout = QHBoxLayout()
        boxsublayout.addWidget(self._txt_cutoff_energy_inelastic, 1)
        boxsublayout.addWidget(self._cb_cutoff_energy_inelastic)
        boxlayout.addRow(self._lbl_cutoff_energy_inelastic, boxsublayout)
        boxsublayout = QHBoxLayout()
        boxsublayout.addWidget(self._txt_cutoff_energy_bremsstrahlung, 1)
        boxsublayout.addWidget(self._cb_cutoff_energy_bremsstrahlung)
        boxlayout.addRow(self._lbl_cutoff_energy_bremsstrahlung, boxsublayout)
        box_cutoff_energy.setLayout(boxlayout)
        sublayout.addWidget(box_cutoff_energy)

        subsublayout = QFormLayout()
        subsubsublayout = QHBoxLayout()
        subsubsublayout.addWidget(self._txt_maximum_step_length, 1)
        subsubsublayout.addWidget(self._cb_maximum_step_length_unit)
        subsublayout.addRow(self._lbl_maximum_step_length, subsubsublayout)
        sublayout.addLayout(subsublayout)

        box_forcing = QGroupBox('Interaction forcing')
        boxlayout = QVBoxLayout()
        boxlayout.addWidget(self._tbl_forcing)
        boxlayout.addWidget(self._tlb_forcing)
        box_forcing.setLayout(boxlayout)
        sublayout.addWidget(box_forcing)

        sublayout.addStretch()

        layout.addLayout(sublayout, 1)

        # Signals
        self._txt_elastic_scattering_c1.textChanged.connect(self._onElasticScatteringC1Changed)
        self._txt_elastic_scattering_c2.textChanged.connect(self._onElasticScatteringC2Changed)
        self._txt_cutoff_energy_inelastic.textChanged.connect(self._onCutoffEnergyInelasticChanged)
        self._txt_cutoff_energy_bremsstrahlung.textChanged.connect(self._onCutoffEnergyBremsstrahlungChanged)
        self._txt_maximum_step_length.textChanged.connect(self._onMaximumStepLengthChanged)

        act_add_forcing.triggered.connect(self._onForcingAdd)
        act_remove_forcing.triggered.connect(self._onForcingRemove)

        return layout