Пример #1
0
    def _loadFile(self, filename=None):
        '''
        Loads a SBML file. It invokes the creation of a data model and 
        a networkx graph based on the SBML data.
        
        @param filename: Name of the SBML file
        @type filename: str
        '''
        if filename is None:
            return

        self.filename = filename

        self.sbmlModel = SBMLMainModel(filename)
        self.treeModel = self.sbmlModel.MainTreeModel
        #        self.connect(self.sbmlModel, SIGNAL("DirtyChanged(bool)"), self.on_dirtyChanged)
        self.sbmlModel.dirtyChanged.connect(self.on_dirtyChanged)

        #        self.proxyModel = self.treeModel   # DEBUGGING: "disabling" the proxy approach
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setSortRole(Qt.UserRole)
        try:
            self.proxyModel.setSourceModel(self.treeModel)
        except Exception, e:
            # try again
            logging.debug(
                "ModelController._loadFile(): Could not set source model for proxy model. Trying again. Original Error: %s"
                % e)
            self._loadFile(filename)
Пример #2
0
class OverviewDock(QDockWidget, Ui_Dock):
    """ Main interface with recent actions """

    def __init__(self, parent=None):
        super(OverviewDock, self).__init__(parent)
        self.setupUi(self)
        self.tableView.setSortingEnabled(True)
        self._model = OverviewTableModel()
        self._proxy = QSortFilterProxyModel()
        self._proxy.setSourceModel(self._model)

        self.tableView.setModel(self._proxy)
        self.initialLoad()

    def initialLoad(self):
        self._model.modelReset.connect(self.setup_view)
        self.dateEdit.setDate(QtCore.QDate.currentDate())

    def setup_view(self):
        self.tableView.setColumnHidden(self._model.ID, True)
        self.tableView.setColumnHidden(self._model.TYPE, True)
        self.tableView.setColumnHidden(self._model.ID_REF, True)
        self.resize_columns()
        #self.tableView.setFocus()
        self.tableView.selectRow(self._model.rowCount() - 1)

    def resize_columns(self):
        self.tableView.resizeColumnsToContents()
        self.tableView.horizontalHeader().setResizeMode(self._model.DESCRIPTION, QHeaderView.Stretch)

    @QtCore.Slot(QtCore.QDate)
    def on_dateEdit_dateChanged(self, date):
        self._model.load_date(date)

    @QtCore.Slot()
    def on_btnRefresh_clicked(self):
        self.refresh()

    def refresh(self):
        self._model.load_date(self.dateEdit.date())

    @QtCore.Slot(QtCore.QModelIndex)
    def on_tableView_doubleClicked(self, index):
        source_index = self._proxy.mapToSource(index)
        record = self._model.get_record(source_index.row())
        record_type = record.value(self._model.TYPE)
        record_id = record.value(self._model.ID)
        record_time = record.value(self._model.DATE).toString("dd/MMM - HH:mm")
        record_user = record.value(self._model.USERNAME)
        record_desc = record.value(self._model.DESCRIPTION)

        print ("%s /// %s /// %s /// %s /// %s") % (record_type, record_id, record_time, record_user, record_desc)
Пример #3
0
class UserListWidget(QListView):
    """
    This actual widget that shows the list of users.
    It contains a proxy that, in turn, contains a UserListModel.
    """
    def __init__(self, users, parent):
        super(UserListWidget, self).__init__(parent)
        self.model = UserListModel(users)

        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.model)
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.setModel(self.proxy)

        self.clicked.connect(parent.user_selected)
        self.adjustSize()
    
    def setUsers(self, users):
        self.model.setUsers(users)

    def getUser(self, index):
        return self.model.data(index, UserListModel.UserRole)

    def filter(self, text):
        self.proxy.setFilterRegExp(text)
        self.proxy.filterRegExp()
Пример #4
0
class NodeTree(QTreeView):
    def __init__(self):
        super(NodeTree, self).__init__()

        self._model = NodeModel(self)
        self._proxy = QSortFilterProxyModel()
        self._proxy.setSortRole(Qt.UserRole)    # sort order is stored in item in Qt.UserRole
        self._proxy.setSourceModel(self._model)

        self.setModel(self._proxy)
        self.setItemDelegate(NodeDelegate())
        self.header().setResizeMode(self.header().ResizeToContents)
        self.header().setStretchLastSection(False)
        self.setSortingEnabled(True)
        self.sortByColumn(self.model().sourceModel().HEADER.index('Node'), Qt.AscendingOrder)
Пример #5
0
    def _loadFile(self, filename=None):
        """
        Loads a SBML file. It invokes the creation of a data model and
        a networkx graph based on the SBML data.

        @param filename: Name of the SBML file
        @type filename: str
        """
        if filename is None:
            return

        self.filename = filename

        self.sbmlModel = SBMLMainModel(filename)
        self.treeModel = self.sbmlModel.MainTreeModel
        self.sbmlModel.dirtyChanged.connect(self.on_dirtyChanged)

        #        self.proxyModel = self.treeModel   # DEBUGGING: "disabling" the proxy approach
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setSortRole(Qt.UserRole)
        try:
            self.proxyModel.setSourceModel(self.treeModel)
        except Exception, e:
            # try again
            logging.debug("ModelController._loadFile(): Could not set source model for proxy model. Trying again. Original Error: %s" % e)
            self._loadFile(filename)
Пример #6
0
    def __init__(self, parent=None):
        super(ComboBoxWithTypingSearch, self).__init__(parent)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.completer = QCompleter(self)

        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setPopup(self.view())
        self.setCompleter(self.completer)

        self.lineEdit().textEdited.connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)
Пример #7
0
    def __init__(self, parent=None):
        super(OverviewDock, self).__init__(parent)
        self.setupUi(self)
        self.tableView.setSortingEnabled(True)
        self._model = OverviewTableModel()
        self._proxy = QSortFilterProxyModel()
        self._proxy.setSourceModel(self._model)

        self.tableView.setModel(self._proxy)
        self.initialLoad()
Пример #8
0
 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)
Пример #9
0
 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)
Пример #10
0
    def __init__(self, users, parent):
        super(UserListWidget, self).__init__(parent)
        self.model = UserListModel(users)

        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.model)
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.setModel(self.proxy)

        self.clicked.connect(parent.user_selected)
        self.adjustSize()
Пример #11
0
    def __init__(self, strategy):
        QListView.__init__(self)

        self.item_strat = strategy

        self.itemmodel = QStandardItemModel()
        self.proxymodel = QSortFilterProxyModel()
        self.proxymodel.setSourceModel(self.itemmodel)
        self.proxymodel.setDynamicSortFilter(True)
        self.setModel(self.proxymodel)
        self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
Пример #12
0
    def init(self, parent):
        super(_FilterTabularEditor, self).init(parent)

        self.control.text.textChanged.connect(self.on_text_change)
        self.control.button.clicked.connect(self.on_action)
        self.proxyModel = proxyModel = QSortFilterProxyModel()
        proxyModel.setSourceModel(self.model)

        self.control.setModel(proxyModel)

        if self.factory.multi_select:
            slot = self._on_rows_selection
        else:
            slot = self._on_row_selection
        signal = 'selectionChanged(QItemSelection,QItemSelection)'
        QtCore.QObject.connect(self.control.selectionModel(),
                               QtCore.SIGNAL(signal), slot)
Пример #13
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()
Пример #14
0
class LibraryListView(QListView):
    def __init__(self, strategy):
        QListView.__init__(self)

        self.item_strat = strategy

        self.itemmodel = QStandardItemModel()
        self.proxymodel = QSortFilterProxyModel()
        self.proxymodel.setSourceModel(self.itemmodel)
        self.proxymodel.setDynamicSortFilter(True)
        self.setModel(self.proxymodel)
        self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)

    def add(self, obj):
        item = self.item_strat.get_item(obj)
        self.itemmodel.appendRow(item)
        return item

    def filter(self, field, value):
        self.proxymodel.setFilterRole(field)
        self.proxymodel.setFilterFixedString(value)
Пример #15
0
 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)
Пример #16
0
    def __init__(self, parent=None):
        """Initialize the window, setup connections, populate initial data."""
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        self.statusCombo.addItems(bug.status_values)
        self.severityCombo.addItems(bug.severity_values)
        self.statusCombo.insertSeparator(len(bug.active_status_def))
        status_def = bug.active_status_def + bug.inactive_status_def
        tooltip = '\n'.join([': '.join(s) for s in status_def])
        self.statusCombo.setToolTip(tooltip)
        tooltip = '\n'.join([': '.join(s) for s in bug.severity_def])
        self.severityCombo.setToolTip(tooltip)

        self.action_New.triggered.connect(self.newProject)
        self.action_Open.triggered.connect(self.openProject)
        self.action_Close.triggered.connect(self.closeProject)
        self.bugFilterCombo.currentIndexChanged.connect(self.filter_bugs)
        self.propertyCombo.currentIndexChanged.connect(self.filter_property)
        self.saveBugButton.clicked.connect(self.create_bug)
        self.saveCommentButton.clicked.connect(self.add_comment)
        self.saveDetailsButton.clicked.connect(self.save_detail)
        self.discardDetailsButton.clicked.connect(self.display_bug)
        self.removeBugButton.clicked.connect(self.remove_bug)
        self.updateAllButton.clicked.connect(self.bulk_update)
        self.addFilterButton.clicked.connect(self.add_filter)
        self.cancelFilterButton.clicked.connect(self.clear_filter)
        self.filterBugsButton.clicked.connect(self.filter_bugs)

        self.project = None
        self.model = BugTableModel()
        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self.model)
        self.bugTable.setModel(self.proxy_model)
        self.bugTable.horizontalHeader().setResizeMode(1, QHeaderView.ResizeToContents)
        self.bugTable.horizontalHeader().setResizeMode(2, QHeaderView.ResizeToContents)
        self.bugTable.horizontalHeader().setResizeMode(0, QHeaderView.Stretch)
        self.bugTable.horizontalHeader().setMinimumSectionSize(60)
        self.bugTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.bugTable.selectionModel().selectionChanged.connect(self.select_bug)

        self.customFilterBox.setVisible(False)
Пример #17
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()
Пример #18
0
    def setup_ui(self):
        main_layout = QHBoxLayout(self)

        edt = QLineEdit(self)
        edt.setPlaceholderText("Wildcard filter")
        btn = QToolButton(self)
        btn.clicked.connect(self.set_icon)

        layout = QHBoxLayout(self)
        layout.addWidget(edt)
        layout.addWidget(btn)

        layout2 = QVBoxLayout()
        layout2.addLayout(layout)

        model = TListModel(self)
        proxy = QSortFilterProxyModel(self)
        proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        proxy.setSourceModel(model)
        edt.textChanged.connect(proxy.setFilterWildcard)

        list = QListView()
        list.setModel(proxy)
        selection_model = list.selectionModel()
        selection_model.currentChanged.connect(self.currentChanged)
        layout2.addWidget(list)

        main_layout.addLayout(layout2)

        image = QLabel("Select icon", self)
        image.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        image.setMinimumWidth(256)
        main_layout.addWidget(image)

        self.btn = btn
        self.edt = edt
        self.image = image
        self.list = list
        self.proxy = proxy
        self.model = model
        self.selection_model = selection_model
Пример #19
0
class ComboBoxWithTypingSearch(QComboBox):
    def __init__(self, parent=None):
        super(ComboBoxWithTypingSearch, self).__init__(parent)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.completer = QCompleter(self)

        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setPopup(self.view())
        self.setCompleter(self.completer)

        self.lineEdit().textEdited.connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)

    def setModel(self, model):
        super(ComboBoxWithTypingSearch, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ComboBoxWithTypingSearch, self).setModelColumn(column)

    def view(self):
        return self.completer.popup()

    def index(self):
        return self.currentIndex()

    def setTextIfCompleterIsClicked(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
Пример #20
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)
Пример #21
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """
    The primary GUI class for the Tracker programme.
    """
    
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        
        self.settings = QSettings()
        openRecent = self.settings.value('AppSettings/OpenRecent', '0')
        if int(openRecent) == int(Qt.Checked):
            self.filename = self.settings.value('AppSettings/LastOpenFile', None)
            print self.filename
            self.currentFilename.setText(self.filename)
        else:
            self.filename = None
        
        if self.filename == None:
            self.filename = self.fileBrowser()
            
        self.db = TrackerDB(self.filename)
        
        # User tab =============================================================
        self.browseFiles.clicked.connect(self.fileBrowser)
        self.userName.editingFinished.connect(self.userNameUpdate)
        self.currentAge.valueChanged.connect(self.calculateBMR)
        self.currentHeight.valueChanged.connect(self.calculateBMR)
        self.currentWeight.valueChanged.connect(self.calculateBMR)
        self.sex.currentIndexChanged.connect(self.calculateBMR)
        self.activity.currentIndexChanged.connect(self.calculateMCN)
        self.goal.currentIndexChanged.connect(self.calculateTCN)
        self.dietMacro.currentIndexChanged.connect(self.calculateSplit)
        self.loadUserData()
        
        # Foods tab ============================================================
        self.foodModel = Foodmodel(self.db, self)
        self.foodView.setModel(self.foodModel)
        
        self.foodView.doubleClicked.connect(self.foodViewEdit)
        self.addFoodButton.clicked.connect(self.editFood)
        self.deleteFoodButton.clicked.connect(self.foodViewDelete)
        
        # Food log tab =========================================================
        self.foodProxyModel = QSortFilterProxyModel(self)
        self.foodProxyModel.setSourceModel(self.foodModel)
        self.foodProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.foodProxyModel.setDynamicSortFilter(True)
        self.foodLogList.setModel(self.foodProxyModel)
        self.filterText.textChanged.connect(self.filterFoodProxyModel)
        
        self.setFoodLogDate()
        
        self.todayButton.clicked.connect(self.setFoodLogDate)
        self.yesterdayButton.clicked.connect(self.setFoodLogYesterday)
        self.nextDayButton.clicked.connect(self.setFoodLogNextDay)
        self.previousDayButton.clicked.connect(self.setFoodLogPreviousDay)
        self.dateEdit.dateChanged.connect(self.changeDate)
        self.removeFoodButton.clicked.connect(self.deleteFoodLogItem)
        self.addFoodtoLog.clicked.connect(self.quantityEditButton)
        
        self.foodLogList.doubleClicked.connect(self.quantityEdit)
        self.foodLogToday.doubleClicked.connect(self.existingQuantityEdit)
        
        self.clearFilterButton.clicked.connect(self.clearFilter)
        
        # Load today's data:
        self.changeDate()
                
        # Weight log tab =======================================================
        self.setWeightLogDate()
        self.todayButton_2.clicked.connect(self.setWeightLogDate)
        self.yesterdayButton_2.clicked.connect(self.setWeightLogYesterday)
        self.nextDayButton_2.clicked.connect(self.setWeightLogNextDay)
        self.previousDayButton_2.clicked.connect(self.setWeightLogPreviousDay)
        self.dateEdit_2.dateChanged.connect(self.changeWeightDate)
        self.weight.valueChanged.connect(self.weightChanged)
        self.changeWeightDate() # set to today's weight
        
        # Exercise log tab =====================================================
        self.setExerciseLogDate()
        self.exerciseTodayButton.clicked.connect(self.setExerciseLogDate)
        self.exerciseYesterdayButton.clicked.connect(self.setExerciseLogYesterday)
        self.exerciseNextDayButton.clicked.connect(self.setExerciseLogNextDay)
        self.exercisePreviousDayButton.clicked.connect(self.setExerciseLogPreviousDay)
        self.exerciseDateEdit.dateChanged.connect(self.changeExerciseDate)
        
        self.exerciseModel = Exercisemodel(self.db, self)
        self.exerciseList.setModel(self.exerciseModel)
        self.exerciseList.doubleClicked.connect(self.logExercise)
        
        self.logExerciseButton.clicked.connect(self.logExerciseClick)
        #self.unlogExerciseButton.clicked.connect()
        self.addExercise.clicked.connect(self.createExercise)
        self.editExercise.clicked.connect(self.modifyExercise)
        self.deleteExercise.clicked.connect(self.removeExercise)
        
        self.changeExerciseDate()
        
        # Saved settings =======================================================
        self.loadState()
    
    def fileBrowser(self):
        """
        Opens a file browser dialog box, and sets the resulting values into the
        file name text box
        """
        
        fileName = QFileDialog.getOpenFileName(self, "Open database", "~", "Database files (*.db)")
        if fileName[0] != '':
            #print fileName[0]
            self.currentFilename.setText(fileName[0])
        
        return fileName[0]
        
    def foodViewEdit(self, QModelIndex):
        row = QModelIndex.row()
        data = []
        for column in range(9):
            data.append(QModelIndex.sibling(row, column).data())
        self.editFood(data[1], data[2], data[3:9], data[0], row)
        
    def foodViewDelete(self):
        if len(self.foodView.selectedIndexes()) != 0:
            QModelIndex = self.foodView.selectedIndexes()[0]
            #row = QModelIndex.row()
            self.foodModel.deleteitem(QModelIndex)
          
    def loadState(self):
        '''Loads saved state of the application'''
        # WINDOW SIZE
        windowSize = self.settings.value('MainWindow/Size', QSize(500, 500))
        self.resize(windowSize)
    
        #FOOD: COLUMN WIDTHS
        foodColumnWidths = self.settings.value('Food/ColumnWidths',
                                    [0, 100, 100, 100, 100, 100, 100, 100, 100])
        for i in range(9):
            self.foodView.setColumnWidth(i, int(foodColumnWidths[i]))
        self.foodView.sortByColumn(1, Qt.AscendingOrder)
        for i in [0]:
            self.foodView.hideColumn(i)
        
        #FOOD LOG: COLUMN WIDTHS
        foodLogFoodwidths = self.settings.value('FoodLog/ColumnWidths1',
                                                [0, 100, 100, 0, 0, 0, 0, 0, 0])
        for i in range(9):
            self.foodLogList.setColumnWidth(i, int(foodLogFoodwidths[i]))
        self.foodLogList.sortByColumn(1, Qt.AscendingOrder)
        for i in [0, 3, 4, 5, 6, 7, 8]:
            self.foodLogList.hideColumn(i)
        
        foodLogFoodwidths2 = self.settings.value('FoodLog/ColumnWidths2',
                                                 [0, 100, 100, 100])
        for i in range(4):
            self.foodLogToday.setColumnWidth(i, int(foodLogFoodwidths2[i]))
        self.foodLogToday.sortByColumn(1, Qt.AscendingOrder)
        for i in [0]:
            self.foodLogToday.hideColumn(i)
            
        #EXERCISE
        exerciseListWidths = self.settings.value('Exercise/ListWidths',[0, 150, 0, 150])
        for i in range(4):
            self.exerciseList.setColumnWidth(i, int(exerciseListWidths[i]))
        self.exerciseList.sortByColumn(1, Qt.AscendingOrder)
        for i in [0, 2]:
            self.exerciseList.hideColumn(i)
        
        exerciseLogWidths = self.settings.value('Exercise/LogWidths',[100, 100, 30, 30, 30])
        for i in range(5):
            self.dailyExerciseLog.setColumnWidth(i, int(exerciseLogWidths[i]))
        self.dailyExerciseLog.sortByColumn(0, Qt.AscendingOrder)
    
    def closeEvent(self, event):
        '''Method to save state of the application'''
        # LAST OPEN FILE
        self.settings.setValue('AppSettings/LastOpenFile', self.filename)
        self.settings.setValue('AppSettings/OpenRecent', self.openRecent.checkState())
        
        # WINDOW SIZE
        self.settings.setValue('MainWindow/Size', self.size())
    
        #FOOD: COLUMN WIDTHS
        columnWidths = []
        for i in range(9):
            columnWidths.append(self.foodView.columnWidth(i))
        self.settings.setValue('Food/ColumnWidths',columnWidths)
        
        # FOOD LOG: COLUMN WIDTHS
        columnWidths = []
        for i in range(9):
            columnWidths.append(self.foodLogList.columnWidth(i))
        self.settings.setValue('FoodLog/ColumnWidths1',columnWidths)
        
        columnWidths = []
        for i in range(4):
            columnWidths.append(self.foodLogToday.columnWidth(i))
        self.settings.setValue('FoodLog/ColumnWidths2',columnWidths)
        
        #EXERCISE: COLUMN WIDTHS
        columnWidths = []
        for i in range(4):
            columnWidths.append(self.exerciseList.columnWidth(i))
        self.settings.setValue('Exercise/ListWidths',columnWidths)
        
        columnWidths = []
        for i in range(5):
            columnWidths.append(self.dailyExerciseLog.columnWidth(i))
        self.settings.setValue('Exercise/LogWidths',columnWidths)
        
    def editFood(self, name='', portion='', data=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
                 foodID=0, row=0):
        dialog = EditFood(name, portion, data, foodID)
        dialog.setModal(True)
        newData = dialog.exec_()
        if newData == False:
            # cancelled add/edit
            pass
        else:
            # create or edit the item
            if newData[0] == 0:
                # brand new item
                self.foodModel.additem(newData[1])
            else:
                # edit existing item
                self.foodModel.edititem(newData[0], row, newData[1])
    
    def currentDate(self):
        '''Returns a QDate object with the date/time set to now'''
        return QDate.currentDate()
        
    def setFoodLogDate(self):
        '''Sets the date on the food Log tab to the current date'''
        self.dateEdit.setDate(self.currentDate())
    
    def setWeightLogDate(self):
        '''Sets the date on the weight log tab to the current date'''
        self.dateEdit_2.setDate(self.currentDate())
        
    def setExerciseLogDate(self, date=QDate.currentDate()):
        '''Sets the date on the weight log tab to the current date'''
        self.exerciseDateEdit.setDate(date)
        
    def setFoodLogYesterday(self):
        '''Sets the date on the food Log tab to yesterday'''
        self.dateEdit.setDate(self.currentDate().addDays(-1))
    
    def setWeightLogYesterday(self):
        '''Sets the date on the weight Log tab to yesterday'''
        self.dateEdit_2.setDate(self.currentDate().addDays(-1))
        
    def setExerciseLogYesterday(self):
        '''Sets the date on the exercise Log tab to yesterday'''
        self.exerciseDateEdit.setDate(self.currentDate().addDays(-1))
     
    def setFoodLogNextDay(self):
        '''Increments current date by 1 day'''
        self.dateEdit.setDate(self.dateEdit.date().addDays(1))
    
    def setWeightLogNextDay(self):
        '''Increments current date by 1 day'''
        self.dateEdit_2.setDate(self.dateEdit_2.date().addDays(1))
    
    def setExerciseLogNextDay(self):
        '''Increments current date by 1 day'''
        self.exerciseDateEdit.setDate(self.exerciseDateEdit.date().addDays(1))
        
    def setFoodLogPreviousDay(self):
        '''Decrements current date by 1 day'''
        self.dateEdit.setDate(self.dateEdit.date().addDays(-1))
    
    def setWeightLogPreviousDay(self):
        '''Decrements current date by 1 day'''
        self.dateEdit_2.setDate(self.dateEdit_2.date().addDays(-1))
    
    def setExerciseLogPreviousDay(self):
        '''Decrements current date by 1 day'''
        self.exerciseDateEdit.setDate(self.exerciseDateEdit.date().addDays(-1))
        
    def changeDate(self, date=QDate.currentDate()):
        '''Actions to conduct when date is changed, e.g. check if date exists in
        database, load existing food log'''
           
        self.foodLogModel = FoodLogModel(self.db, date, self)
        self.foodLogToday.setModel(self.foodLogModel)
        
    def changeWeightDate(self, date=QDate.currentDate()):
        """
        Actions to conduct when the weight date is changed.
        """

        weight = self.db.getWeight(date.toString('yyyy-MM-dd'))
        if weight != None:
            self.weight.setValue(weight['weight'])
        else:
            self.weight.setValue(0.0)
    
    def weightChanged(self):
        """
        Actions to take when the weight value is changed
        """
        
        # Check that the date exists
        dateString = self.dateEdit_2.date().toString('yyyy-MM-dd')
        weight = self.weight.value()
        d = self.db.getDate(dateString)
        if len(d) == 0: # The date does not yet exist in the database
            # has the value been changed to a default zero?
            if weight != 0:
                self.db.addDate(dateString)
                self.db.setWeight(dateString, weight)
        else: # The date exists in the database
            # change existing value
            self.db.setWeight(dateString, weight)
            
        
    def clearFilter(self):
        """
        Clears the filter box string
        """
        
        self.filterText.setText('')
        
    def filterFoodProxyModel(self):
        """
        Applies filter from the text box
        """
        
        self.foodProxyModel.setFilterFixedString(self.filterText.text())
        self.foodProxyModel.setFilterKeyColumn(1)
        
    def quantityEdit(self, QModelIndex):
        """
        Adds a food to from the food list to the daily consumption list
        """
        
        row = QModelIndex.row()
        data = []
        for column in range(9):
            data.append(QModelIndex.sibling(row,column).data())
        dialog = SetQuantity(data[0], data[1], data[2])
        dialog.setModal(True)
        newData = dialog.exec_()
        if newData == False:
            # User cancelled the operation
            pass
        else:
            # newData = [id, name, portion, quantity]
            self.foodLogModel.addFood(newData[0], newData[1],
                                      newData[2], newData[3])
    
    def quantityEditButton(self):
        """
        Adds a food to from the food list to the daily consumption list - as 
        quantityEdit, but using the pushbutton
        """
        if len(self.foodLogList.selectedIndexes()) != 0:
            QModelIndex = self.foodLogList.selectedIndexes()[0]
            self.quantityEdit(QModelIndex)
        
    def existingQuantityEdit(self, QModelIndex):
        row = QModelIndex.row()
        data = []
        for column in range(4):
            data.append(QModelIndex.sibling(row,column).data())
        dialog = SetQuantity(data[0], data[1], data[2], data[3])
        dialog.setModal(True)
        newData = dialog.exec_()
        if newData == False:
            # User cancelled the operation
            pass
        else:
            # newData = [id, name, portion, quantity]
            self.foodLogModel.editFood(newData[0], newData[3], row)
    
    def deleteFoodLogItem(self):
        if len(self.foodLogToday.selectedIndexes()) != 0:
            QModelIndex = self.foodLogToday.selectedIndexes()[0]
            self.foodLogModel.deleteFood(QModelIndex)
    
    def userNameUpdate(self):
        """
        Updates the user's name in the database file
        """

        self.db.setName(self.userName.text())
        
    def calculateBMR(self):
        """
        Calculates Basal metabolic rate and updates the information tab
        http://en.wikipedia.org/wiki/Basal_animal_metabolic_rate
        Mifflin et al. (1990)
        """

        if self.sex.currentIndex() == 0:
            # male
            BMR = 10.0*self.currentWeight.value() + 625*self.currentHeight.value() -5*self.currentAge.value() + 5
        if self.sex.currentIndex() == 1:
            # female
            BMR = 10.0*self.currentWeight.value() + 625*self.currentHeight.value() -5*self.currentAge.value() - 161
        
        self.currentBMR.setText(str(BMR))
        self.calculateMCN()
        
    def calculateMCN(self):
        """
        Calculates maintenance calorific needs, and updates ther information tab
        http://en.wikipedia.org/wiki/Harris-Benedict_equation
        Harris Benedict principle
        """
        
        multiplier = [1.2, 1.375, 1.55, 1.725, 1.9]
        MCN = float(self.currentBMR.text())*multiplier[self.activity.currentIndex()]
        self.currentMCN.setText(str(MCN))
        self.calculateTCN()
        
    def calculateTCN(self):
        """
        Calculates total calorific need based on desired weight change goal
        """
        
        calorieIncrease = [1000, 500, 0, +500, +1000]
        TCN = float(self.currentMCN.text()) + calorieIncrease[self.goal.currentIndex()]
        self.currentTCN.setText(str(TCN))
                        
        self.calculateSplit()
        
    def calculateSplit(self):
        """
        Determines the macronutrient split (by mass) and displays it in the UI
        This function should always be triggered if any of the upstream data 
        changes (i.e. sex, age, weight, height, activity and goal)
        so this function also updates the database with latest values of those
        """
        
        if self.dietMacro.currentIndex() == 0:
            c, p, f = 40.0, 40.0, 20.0    # carb, protein, fat
        if self.dietMacro.currentIndex() == 1:
            c, p, f = 40.0, 30.0, 30.0    # carb, protein, fat
        if self.dietMacro.currentIndex() == 2:
            c, p, f = 50.0, 25.0, 25.0    # carb, protein, fat
        if self.dietMacro.currentIndex() == 3:
            c, p, f = 50.0, 30.0, 20.0    # carb, protein, fat
            
        cg, pg, fg = self.db.macroSplit(c, p, f, float(self.currentTCN.text()))
        
        # set the values in the GUI
        self.targetCarbg.setText('%3i g/ day' % cg)
        self.targetProteing.setText('%3i g/ day' % pg)
        self.targetFatg.setText('%3i g/ day' % fg)
        
        # save values to DB
        self.db.updateUserData(self.userName.text(), self.sex.currentIndex(), self.currentAge.value(), self.currentHeight.value(), self.currentWeight.value(), self.activity.currentIndex(), self.goal.currentIndex(), self.dietMacro.currentIndex())
        
    def loadUserData(self):
        """
        Loads the user data from the SQL file into the GUI
        """
        
        userdata = self.db.getUserData()
        self.userName.setText(userdata['name'])
        self.sex.setCurrentIndex(userdata['sex'])
        self.currentAge.setValue(userdata['age'])
        self.currentHeight.setValue(userdata['height'])
        self.currentWeight.setValue(userdata['weight'])
        self.activity.setCurrentIndex(userdata['activity'])
        self.goal.setCurrentIndex(userdata['goal'])
        self.dietMacro.setCurrentIndex(userdata['macrosplit'])
        
    def createExercise(self, name='', typeID=1, row=False, existingID=-1):
        """
        Brings up the 'create exercise' dialog
        """

        dialog = CreateExercise(self.db, name, typeID)
        dialog.setModal(True)
        exData = dialog.exec_() # [description, typeID]
        if exData != False:
            if row == False:
                # Add a new item
                self.exerciseModel.addItem(exData[0], exData[1])
            else:
                # edit existing item in row row
                self.exerciseModel.editItem(exData[0], exData[1], row, existingID)
    
    def modifyExercise(self):
        if len(self.exerciseList.selectedIndexes()) != 0:
            QModelIndex = self.exerciseList.selectedIndexes()[0]
            row = QModelIndex.row()
            data = []
            for column in range(4):
                data.append(QModelIndex.sibling(row, column).data())
            self.createExercise(data[1], data[2], row, data[0])
    
    def removeExercise(self):
        """
        Deletes exercise from the exercises list (not the log)
        """
        
        if len(self.exerciseList.selectedIndexes()) != 0:
            QModelIndex = self.exerciseList.selectedIndexes()[0]
            row = QModelIndex.row()
            exID = QModelIndex.sibling(row, 0).data()
            self.exerciseModel.deleteItem(exID, row)
    
    def logExercise(self, QModelIndex):
        """
        Logs the exercise to the currently selected day
        """
        row = QModelIndex.row()
        exID = QModelIndex.sibling(row, 0).data()
        
        dialog = LogExercise(self.db, exID)
        dialog.setModal(True)
        exData = dialog.exec_()
        dateString = self.exerciseDateEdit.date().toString('yyyy-MM-dd')
        self.db.logExercise(dateString, exData[0], exData[1], exData[2], exData[3], exData[4])
        # reload model
        self.changeExerciseDate(self.exerciseDateEdit.date())
        
    def logExerciseClick(self):
        """
        Use the button to log the currently selected exercise to the currently
        selected day
        """
        if len(self.exerciseList.selectedIndexes()) != 0:
            QModelIndex = self.exerciseList.selectedIndexes()[0]
            self.logExercise(QModelIndex)
        
    def changeExerciseDate(self, date=QDate.currentDate()):
        """
        Actions to conduct when date is changed, e.g. check if date exists in
        database, load existing exercise log
        """
        
        self.exerciseLogModel = ExerciseLogModel(self.db, date, self)
        self.dailyExerciseLog.setModel(self.exerciseLogModel)
Пример #22
0
class ModelController(QObject):
    """
    The network controller which basically manages all aspects
    revolving around a single SBML model (i.e. SBML file).
    It has references to outside Views (e.g. TreeView). Internally,
    it has a reference to the custom NetworkView.
    A Dirty state is used to handle the need for saving/rejecting changes, etc.

    It inherits from QObject for the use of Signals/Slots.

    @param filename: Filename of the SBML model that should be opened. If None, an empty model is created.
    @type filename: str

    @param views: The views of the main window that are to be associated with the model.
    @type views: L{QAbstractItemView}

    @since: 2010-04-12
    """

    __author__ = "Moritz Wade"
    __contact__ = "*****@*****.**"
    __copyright__ = "Zuse Institute Berlin 2010"

    dirtyChanged = Signal(bool)

    def GetDirty(self):
        return self.__Dirty

    def SetDirty(self, value):
        self.__Dirty = value
        #        self.emit(SIGNAL("DirtyChanged(bool)"), value)
        self.dirtyChanged.emit(value)

    def DelDirty(self):
        del self.__Dirty

    Dirty = property(
        GetDirty, SetDirty, DelDirty,
        "Defines whether this model has any unsaved changes. This is passed through to SbmlMainModel's Dirty."
    )

    def __init__(self, filename=None, views=[], networkViewController=None):
        """
        Sets up some instance variables. Most importantly,
        it executes the loading of a SBML file, if a filename is given.
        """
        super(ModelController, self).__init__()

        self.filename = None  # will be set by self._loadFile
        self.sbmlModel = None
        self.treeModel = None
        self.selectionModel = None
        self.proxyModel = None  # we have the proxy model here, so that all Views can use it and the same SelectionModel still works (!)

        self.views = views
        self.networkViewController = networkViewController  # a special place for the NetworkViewController

        #        self.connect(self, SIGNAL("DirtyChanged(bool)"), self.updateUI)
        #        self.dirtyChanged.connect(self.updateUI)

        if filename is not None:
            self._loadFile(filename)

    def setViews(self, views=None, networkViewController=None):
        """
        Can be used to re-reference the ModelController with Views (either if they
        haven't been given to the Constructor or if they have changed somehow).
        This internally calls self._connectViews to set the correct models and a
        single QSelectionModel on the views.
        """
        if views:
            self.views = views
        if networkViewController:
            self.networkViewController = networkViewController

        self._connectViews()
        if self.networkViewController:
            self.networkViewController._createGraph()

    def _loadFile(self, filename=None):
        '''
        Loads a SBML file. It invokes the creation of a data model and 
        a networkx graph based on the SBML data.
        
        @param filename: Name of the SBML file
        @type filename: str
        '''
        if filename is None:
            return

        self.filename = filename

        self.sbmlModel = SBMLMainModel(filename)
        self.treeModel = self.sbmlModel.MainTreeModel
        #        self.connect(self.sbmlModel, SIGNAL("DirtyChanged(bool)"), self.on_dirtyChanged)
        self.sbmlModel.dirtyChanged.connect(self.on_dirtyChanged)

        #        self.proxyModel = self.treeModel   # DEBUGGING: "disabling" the proxy approach
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setSortRole(Qt.UserRole)
        try:
            self.proxyModel.setSourceModel(self.treeModel)
        except Exception, e:
            # try again
            logging.debug(
                "ModelController._loadFile(): Could not set source model for proxy model. Trying again. Original Error: %s"
                % e)
            self._loadFile(filename)

        self.selectionModel = QItemSelectionModel(self.proxyModel)
        #        self.selectionModel = self.proxyModel.selectionModel()

        self._connectViews(
        )  # probably not needed here, there is no View after __init__
        if self.networkViewController:
            self.networkViewController._createGraph()

        self.Dirty = False
Пример #23
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)
Пример #24
0
 def __init__(self, parent=None):
     super(MainWindow, self).__init__(parent)
     self.setupUi(self)
     
     self.settings = QSettings()
     openRecent = self.settings.value('AppSettings/OpenRecent', '0')
     if int(openRecent) == int(Qt.Checked):
         self.filename = self.settings.value('AppSettings/LastOpenFile', None)
         print self.filename
         self.currentFilename.setText(self.filename)
     else:
         self.filename = None
     
     if self.filename == None:
         self.filename = self.fileBrowser()
         
     self.db = TrackerDB(self.filename)
     
     # User tab =============================================================
     self.browseFiles.clicked.connect(self.fileBrowser)
     self.userName.editingFinished.connect(self.userNameUpdate)
     self.currentAge.valueChanged.connect(self.calculateBMR)
     self.currentHeight.valueChanged.connect(self.calculateBMR)
     self.currentWeight.valueChanged.connect(self.calculateBMR)
     self.sex.currentIndexChanged.connect(self.calculateBMR)
     self.activity.currentIndexChanged.connect(self.calculateMCN)
     self.goal.currentIndexChanged.connect(self.calculateTCN)
     self.dietMacro.currentIndexChanged.connect(self.calculateSplit)
     self.loadUserData()
     
     # Foods tab ============================================================
     self.foodModel = Foodmodel(self.db, self)
     self.foodView.setModel(self.foodModel)
     
     self.foodView.doubleClicked.connect(self.foodViewEdit)
     self.addFoodButton.clicked.connect(self.editFood)
     self.deleteFoodButton.clicked.connect(self.foodViewDelete)
     
     # Food log tab =========================================================
     self.foodProxyModel = QSortFilterProxyModel(self)
     self.foodProxyModel.setSourceModel(self.foodModel)
     self.foodProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
     self.foodProxyModel.setDynamicSortFilter(True)
     self.foodLogList.setModel(self.foodProxyModel)
     self.filterText.textChanged.connect(self.filterFoodProxyModel)
     
     self.setFoodLogDate()
     
     self.todayButton.clicked.connect(self.setFoodLogDate)
     self.yesterdayButton.clicked.connect(self.setFoodLogYesterday)
     self.nextDayButton.clicked.connect(self.setFoodLogNextDay)
     self.previousDayButton.clicked.connect(self.setFoodLogPreviousDay)
     self.dateEdit.dateChanged.connect(self.changeDate)
     self.removeFoodButton.clicked.connect(self.deleteFoodLogItem)
     self.addFoodtoLog.clicked.connect(self.quantityEditButton)
     
     self.foodLogList.doubleClicked.connect(self.quantityEdit)
     self.foodLogToday.doubleClicked.connect(self.existingQuantityEdit)
     
     self.clearFilterButton.clicked.connect(self.clearFilter)
     
     # Load today's data:
     self.changeDate()
             
     # Weight log tab =======================================================
     self.setWeightLogDate()
     self.todayButton_2.clicked.connect(self.setWeightLogDate)
     self.yesterdayButton_2.clicked.connect(self.setWeightLogYesterday)
     self.nextDayButton_2.clicked.connect(self.setWeightLogNextDay)
     self.previousDayButton_2.clicked.connect(self.setWeightLogPreviousDay)
     self.dateEdit_2.dateChanged.connect(self.changeWeightDate)
     self.weight.valueChanged.connect(self.weightChanged)
     self.changeWeightDate() # set to today's weight
     
     # Exercise log tab =====================================================
     self.setExerciseLogDate()
     self.exerciseTodayButton.clicked.connect(self.setExerciseLogDate)
     self.exerciseYesterdayButton.clicked.connect(self.setExerciseLogYesterday)
     self.exerciseNextDayButton.clicked.connect(self.setExerciseLogNextDay)
     self.exercisePreviousDayButton.clicked.connect(self.setExerciseLogPreviousDay)
     self.exerciseDateEdit.dateChanged.connect(self.changeExerciseDate)
     
     self.exerciseModel = Exercisemodel(self.db, self)
     self.exerciseList.setModel(self.exerciseModel)
     self.exerciseList.doubleClicked.connect(self.logExercise)
     
     self.logExerciseButton.clicked.connect(self.logExerciseClick)
     #self.unlogExerciseButton.clicked.connect()
     self.addExercise.clicked.connect(self.createExercise)
     self.editExercise.clicked.connect(self.modifyExercise)
     self.deleteExercise.clicked.connect(self.removeExercise)
     
     self.changeExerciseDate()
     
     # Saved settings =======================================================
     self.loadState()
Пример #25
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """Main window of the app."""

    def __init__(self, parent=None):
        """Initialize the window, setup connections, populate initial data."""
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        self.statusCombo.addItems(bug.status_values)
        self.severityCombo.addItems(bug.severity_values)
        self.statusCombo.insertSeparator(len(bug.active_status_def))
        status_def = bug.active_status_def + bug.inactive_status_def
        tooltip = '\n'.join([': '.join(s) for s in status_def])
        self.statusCombo.setToolTip(tooltip)
        tooltip = '\n'.join([': '.join(s) for s in bug.severity_def])
        self.severityCombo.setToolTip(tooltip)

        self.action_New.triggered.connect(self.newProject)
        self.action_Open.triggered.connect(self.openProject)
        self.action_Close.triggered.connect(self.closeProject)
        self.bugFilterCombo.currentIndexChanged.connect(self.filter_bugs)
        self.propertyCombo.currentIndexChanged.connect(self.filter_property)
        self.saveBugButton.clicked.connect(self.create_bug)
        self.saveCommentButton.clicked.connect(self.add_comment)
        self.saveDetailsButton.clicked.connect(self.save_detail)
        self.discardDetailsButton.clicked.connect(self.display_bug)
        self.removeBugButton.clicked.connect(self.remove_bug)
        self.updateAllButton.clicked.connect(self.bulk_update)
        self.addFilterButton.clicked.connect(self.add_filter)
        self.cancelFilterButton.clicked.connect(self.clear_filter)
        self.filterBugsButton.clicked.connect(self.filter_bugs)

        self.project = None
        self.model = BugTableModel()
        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self.model)
        self.bugTable.setModel(self.proxy_model)
        self.bugTable.horizontalHeader().setResizeMode(1, QHeaderView.ResizeToContents)
        self.bugTable.horizontalHeader().setResizeMode(2, QHeaderView.ResizeToContents)
        self.bugTable.horizontalHeader().setResizeMode(0, QHeaderView.Stretch)
        self.bugTable.horizontalHeader().setMinimumSectionSize(60)
        self.bugTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.bugTable.selectionModel().selectionChanged.connect(self.select_bug)

        self.customFilterBox.setVisible(False)

    def _get_project(self):
        """Getter for project property"""
        return self._project

    def _set_project(self, path):
        """Setter for project property"""
        self._project = path
        if not path:
            self.projectTitle.setText('')
            self.newCommentBox.setVisible(False)
            self.newBugBox.setVisible(False)
            self._enable_controls(False)
        else:
            self.projectTitle.setText(path.split(os.path.sep)[-1])
            self._enable_controls()
        self.enable_bug_view(False)
        self.clear_filter()
    project = property(_get_project, _set_project, doc="the absolute path of the project")

    def _enable_controls(self, enable=True):
        """Enable/disable UI for opened/closed project"""
        self.mainBox.setEnabled(enable)
        self.label.setVisible(not enable)

    def newProject(self):
        """Open a new project"""
        self.openProject(is_new=True)

    def openProject(self, is_new=False):
        """Open an existing project"""
        title = is_new and 'Create new project' or 'Open project'
        path = QFileDialog.getExistingDirectory(self, title)
        if path and self.project != path:
            self._open_store(path, is_new)

    def closeProject(self):
        """Close a project"""
        self.project = None
        self.model.bugs = []
        self.enable_bug_view(False)
        self.newBugButton.setChecked(False)
        self.assignedCombo.clear()
        self.targetCombo.clear()
        self.bugFilterCombo.setCurrentIndex(0)

    def _open_store(self, path, is_new=False):
        """Open the store of the project, initialize the bugdir and load bugs"""
        store = storage.get_storage(path)
        try:
            if is_new:
                store.init()
            else:
                store.connect()
            if self.project:
                self.closeProject()
            self.user = get_user_id(store)
            version = store.version()
            self.vcsLabel.setText('None' if version == '0' else version)
            try:
                self.bd = bugdir.BugDir(store, from_storage=True)
            except:
                self.bd = bugdir.BugDir(store, from_storage=False)
            self.project = path
            self.reload_bugs()
            self.load_assignees()
            self.load_targets()
        except storage.ConnectionError as e:
            print e
            message = 'No project found. Would you like to initialize a new project?'
        except OSError as e:
            print e
            message = 'Project already exists. Would you like to open instead?'
        else:
            message = None
        if message:
            if self.confirm_action(message):
                self._open_store(path, not is_new)

    def reload_bugs(self, active=True):
        """Load all the bugs filtering on active status"""
        # FIXME: lazy loading of bugs should be considered
        self.bd.load_all_bugs()
        if active:
            filter_list = bug.status_values[:len(bug.active_status_def)]
        else:
            filter_list = bug.status_values[len(bug.active_status_def):]
        bugs = [b for b in self.bd if b.status in filter_list]
        self.model.bugs = bugs
        self.current_bug = None
        self.bugsLabel.setText(str(len(bugs)))

    def load_assignees(self):
        """Find and save all assignees for this project including the current user"""
        self.assignees = list(set([unicode(bug.assigned) for bug in self.bd if
            bug.assigned and bug.assigned != EMPTY]))
        if len(self.assignees) > 0:
            if self.user not in self.assignees:
                self.assignees.append(self.user)
            self.assignees.sort(key=unicode.lower)
        else:
            self.assignees = [self.user]
        self.assignedCombo.clear()
        self.assignedCombo.addItems([''] + self.assignees)

    def load_targets(self):
        """Load targets"""
        self.targets = [b for b in self.bd if b.severity == "target"]
        targets = [unicode(b.summary) for b in self.targets]
        targets.sort(key=unicode.lower)
        self.targetCombo.clear()
        self.targetCombo.addItems([''] + targets)

    def select_bug(self, new, old):
        """Slot for the bugTable selection changes. ``old`` is unused for now
        but required by Qt4 slot signature requirement.
        """
        n_select = len(self.bugTable.selectedIndexes())
        n_column = len(self.model.header)
        try:
            index = self.proxy_model.mapToSource(new.indexes()[0])
            bug = self.model.bugs[index.row()]
            if n_select > n_column:
                self.enable_bug_view(False)
                self.current_bug = None
                self.updateAllButton.setEnabled(True)
            else:
                self.display_bug(bug)
                self.updateAllButton.setEnabled(False)
            self.removeBugButton.setEnabled(True)
        except IndexError:
            self.enable_bug_view(False)
            self.removeBugButton.setEnabled(False)

    def select_current_bug(self, bug=None):
        """A convenience method to select a bug in the table"""
        if bug:
            self.current_bug = bug
        row = self.model.bugs.index(self.current_bug)
        index = self.model.index(row, 0)
        index = self.proxy_model.mapFromSource(index)
        self.bugTable.selectRow(index.row())

    def enable_bug_view(self, enable=True):
        """Enable/disable bug view"""
        self.addCommentButton.setEnabled(enable)
        self.saveDetailsButton.setEnabled(enable)
        self.discardDetailsButton.setEnabled(enable)
        self.bugTitle.setText('')
        self.shortLabel.setText('')
        self.idLabel.setText('')
        self.creatorLabel.setText('')
        self.createdLabel.setText('')
        self.reporterLabel.setText('')
        self.bugCommentBrowser.setHtml('')
        self.assignedCombo.setCurrentIndex(0)
        self.targetCombo.setCurrentIndex(0)
        self.addCommentButton.setChecked(False)
        self.updateAllButton.setEnabled(False)
        if not enable:
            self.current_bug = None

    def display_bug(self, bug=None):
        """Display currently selected bug or the bug passed via argument"""
        if bug:
            self.current_bug = bug
        else:
            bug = self.current_bug
        self.enable_bug_view()
        self.bugTitle.setText(bug.summary)
        self.shortLabel.setText(bug.id.user())
        self.idLabel.setText(bug.uuid)
        self.creatorLabel.setText(bug.creator)
        self.createdLabel.setText(handy_time(bug.time))
        self.reporterLabel.setText(bug.reporter)

        self.load_combos()
        self.load_comments()

    def load_comments(self):
        """Load all the comments for current bug"""
        comments = '<hr />'.join([comment_html(c) for c in self.current_bug.comments()])
        if not comments:
            comments = '<i>No comment yet!</i>'
        self.bugCommentBrowser.setHtml(comments)

    def load_combos(self):
        """Update the combo boxes for bug properties"""
        if not self.current_bug:
            return
        target = ''
        bug = self.current_bug
        blocks = get_blocks(self.bd, bug)
        for b in blocks:
            blocker = self.bd.bug_from_uuid(b.uuid)
            if blocker.severity == 'target':
                target = blocker.summary
        combos = [
            (self.statusCombo, bug.status),
            (self.severityCombo, bug.severity),
            (self.assignedCombo, bug.assigned),
            (self.targetCombo, target),
        ]
        self.assignedCombo.setCurrentIndex(0)
        self.targetCombo.setCurrentIndex(0)
        for combo, field in combos:
            for i in range(combo.count()):
                if combo.itemText(i) == field:
                    combo.setCurrentIndex(i)

    def create_bug(self):
        """Create a new bug"""
        summary = self.newBugEdit.text().strip()
        if summary:
            bug = self.bd.new_bug(summary=summary)
            bug.creator = self.user
            bug.reporter = self.user
            bug.save()
            self.reload_bugs()
            self.select_current_bug(bug)
            self.newBugEdit.setText('')
            self.statusbar.showMessage('A new bug {0} has been '
                    'added'.format(self.current_bug.id.user()))

    def add_comment(self):
        """Add a comment to the current bug. Comments are now flat, not threaded."""
        body = self.newCommentEdit.toPlainText().strip()
        if body:
            comment = self.current_bug.comment_root.new_reply(body=body)
            comment.author = self.user
            self.current_bug.save()
            self.display_bug()
            self.newCommentEdit.setPlainText('')
            self.statusbar.showMessage('New comment added to '
                    '{0}'.format(self.current_bug.id.user()))

    def save_detail(self):
        """Save updated properties to the current bug"""
        status = self.statusCombo.currentText()
        severity = self.severityCombo.currentText()
        assigned = self.assignedCombo.currentText()
        target = self.targetCombo.currentText()

        is_changed = self.current_bug.status != status or \
            self.current_bug.severity != severity or \
            self.current_bug.assigned != assigned

        if is_changed:
            self.current_bug.severity = severity
            self.current_bug.status = status
            self.current_bug.assigned = assigned
            self.current_bug.save()
            self.model.reset()
            self.load_targets()

        def remove_all_targets():
            """remove all targets for a bug, b"""
            for b in blocks:
                if b.severity == 'target':
                    remove_block(b, self.current_bug)

        blocks = get_blocks(self.bd, self.current_bug)
        if not target:
            is_changed = True
            remove_all_targets()
        else:
            for t in self.targets:
                if t.summary == target:
                    if t not in blocks:
                        is_changed = True
                        remove_all_targets()
                        add_block(t, self.current_bug)
                    break

        if is_changed:
            self.load_combos()
            self.select_current_bug()
            self.statusbar.showMessage('Changes to details for the bug {0} '
                    'has been saved'.format(self.current_bug.id.user()))

    def bulk_update(self):
        """Bulk update properties of selected bugs"""
        if not self.confirm_action('Are you sure to update all selected bugs?'):
            return
        indexes = set([self.proxy_model.mapToSource(index).row() for index in self.bugTable.selectedIndexes()])
        bugs = [self.model.bugs[index] for index in indexes]

        status = self.statusCombo.currentText()
        severity = self.severityCombo.currentText()
        assigned = self.assignedCombo.currentText()
        target = self.targetCombo.currentText()

        def remove_all_targets():
            for b in blocks:
                if b.severity == 'target':
                    remove_block(b, bug)

        for bug in bugs:
            bug.severity = severity
            bug.status = status
            bug.assigned = assigned
            bug.save()
            blocks = get_blocks(self.bd, bug)
            if not target:
                remove_all_targets()
            else:
                for t in self.targets:
                    if t.summary == target:
                        if t not in blocks:
                            remove_all_targets()
                            add_block(t, bug)
                        break

        self.model.reset()
        self.load_targets()
        self.load_combos()
        self.statusbar.showMessage('Updated all selected bugs')

    def remove_bug(self):
        """Remove selected bugs from the project"""
        indexes = set([self.proxy_model.mapToSource(index).row() for index in self.bugTable.selectedIndexes()])
        bugs = [self.model.bugs[index] for index in indexes]
        if len(bugs) > 0 and not self.confirm_action('Are you sure to remove selected bugs?'):
            return
        ids = []
        for bug in bugs:
            ids.append(bug.id.user())
            self.bd.remove_bug(bug)
        self.reload_bugs()
        self.enable_bug_view(False)
        self.removeBugButton.setEnabled(False)
        self.statusbar.showMessage('Removed %s bug(s)' % ', '.join(ids))

    def filter_bugs(self, value=None):
        """Filter bugs on active status"""
        if not value:
            bugs = self.bd
            if self.filter_set:
                status = self.filter_set.get('status')
                severity = self.filter_set.get('severity')
                target = self.filter_set.get('target')
                assigned = self.filter_set.get('assigned')
                if target:
                    for t in self.targets:
                        if t.summary == target:
                            target = t
                            break
                    bugs = get_blocked_by(self.bd, target)
                if assigned:
                    bugs = [b for b in bugs if b.assigned == assigned]
                if severity:
                    bugs = [b for b in bugs if b.severity == severity]
                if status:
                    bugs = [b for b in bugs if b.status == status]
            self.model.bugs = bugs
            self.current_bug = None
            self.bugsLabel.setText(str(len(bugs)))
            self.enable_bug_view(False)
        elif value == 'custom':
            self.customFilterBox.setVisible(True)
            self.propertyCombo.setCurrentIndex(0)
            self.valueCombo.clear()
            self.valueCombo.addItems(bug.status_values)
        else:
            self.clear_filter()
            self.customFilterBox.setVisible(False)
            self.reload_bugs(value == 'active')
            self.enable_bug_view(False)

    def filter_property(self, value):
        items = {
            'status': bug.status_values,
            'severity': bug.severity_values,
            'target': [t.summary for t in self.targets],
            'assigned': self.assignees,
        }[value]
        self.valueCombo.clear()
        self.valueCombo.addItems(items)

    def add_filter(self):
        try:
            key, value = self.propertyCombo.currentText(), self.valueCombo.currentText()
            self.filter_set[key] = value
        except:
            self.filter_set = {key: value}
        text = ''
        for key in self.filter_set:
            text += '<b>{0}</b>: {1}<br/>'.format(key, self.filter_set[key])
        self.customFilterLabel.setText(text)

    def clear_filter(self):
        self.customFilterLabel.setText('Select filters')
        self.filter_set = None

    def confirm_action(self, message):
        """Convenient method for user confirmation on action"""
        result = QMessageBox.warning(self, self.windowTitle(), message, QMessageBox.Ok | QMessageBox.Cancel)
        return result == QMessageBox.Ok
Пример #26
0
 def __init__(self, parent=None):
     QSortFilterProxyModel.__init__(self, parent)
Пример #27
0
 def __init__(self):
     QSortFilterProxyModel.__init__(self)
     self.library_sort = LibrarySort()
Пример #28
0
    def __init__(self, mw, parent=None):
        """
        Default class constructor.

        :param `mw`: The application's MainWindow instance.
        :type `mw`: `QMainWindow`_
        :param `parent`: Pointer to a parent widget instance.
        :type `parent`: `QWidget`_
        """
        super(LayerManager, self).__init__(parent)

        tr = self.tr

        self.layerModel = layerModel = QStandardItemModel(0, 8, self)

        self.layerModelSorted = layerModelSorted = QSortFilterProxyModel()
        layerModelSorted.setDynamicSortFilter(True)
        layerModelSorted.setSourceModel(layerModel)

        self.treeView = treeView = QTreeView()
        treeView.setRootIsDecorated(False)
        treeView.setAlternatingRowColors(True)
        treeView.setModel(layerModelSorted)
        treeView.setSortingEnabled(True)
        treeView.sortByColumn(0, Qt.AscendingOrder)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(treeView)
        self.setLayout(mainLayout)

        self.setWindowTitle(tr("Layer Manager"))
        self.setMinimumSize(750, 550)

        ## layerModel.setHeaderData(0, Qt.Horizontal, self.tr("Name"))
        ## layerModel.setHeaderData(1, Qt.Horizontal, self.tr("Visible"))
        ## layerModel.setHeaderData(2, Qt.Horizontal, self.tr("Frozen"))
        ## layerModel.setHeaderData(3, Qt.Horizontal, self.tr("Z Value"))
        ## layerModel.setHeaderData(4, Qt.Horizontal, self.tr("Color"))
        ## layerModel.setHeaderData(5, Qt.Horizontal, self.tr("Linetype"))
        ## layerModel.setHeaderData(6, Qt.Horizontal, self.tr("Lineweight"))
        ## layerModel.setHeaderData(7, Qt.Horizontal, self.tr("Print"))
        localMeth = layerModel.setHeaderData
        localQtHorizontal = Qt.Horizontal
        [
            localMeth(i, localQtHorizontal, tr(strng))
            for i, strng in ((0, "Name"), (1, "Visible"), (2, "Frozen"),
                             (3, "Z Value"), (4, "Color"), (5, "Linetype"),
                             (6, "Lineweight"), (7, "Print"))
        ]

        ## addLayer = self.addLayer  # local optimization
        ## addLayer("0", True, False, 0.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("1", True, False, 1.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("2", True, False, 2.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("3", True, False, 3.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("4", True, False, 4.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("5", True, False, 5.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("6", True, False, 6.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("7", True, False, 7.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("8", True, False, 8.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        ## addLayer("9", True, False, 9.0, qRgb(0, 0, 0), "Continuous", "Default", True)
        addLayer = self.addLayer
        [
            addLayer("%s" % i, True, False, float(i), qRgb(0, 0, 0),
                     "Continuous", "Default", True) for i in range(0, 10)
        ]

        ## for i in range(0, layerModel.columnCount()):
        ##     treeView.resizeColumnToContents(i)
        localtreeViewMeth = treeView.resizeColumnToContents
        [localtreeViewMeth(i) for i in range(0, layerModel.columnCount())]

        QApplication.setOverrideCursor(Qt.ArrowCursor)
Пример #29
0
class ModelController(QObject):
    """
    The network controller which basically manages all aspects
    revolving around a single SBML model (i.e. SBML file).
    It has references to outside Views (e.g. TreeView). Internally,
    it has a reference to the custom NetworkView.
    A Dirty state is used to handle the need for saving/rejecting changes, etc.

    It inherits from QObject for the use of Signals/Slots.

    @param filename: Filename of the SBML model that should be opened. If None, an empty model is created.
    @type filename: str

    @param views: The views of the main window that are to be associated with the model.
    @type views: L{QAbstractItemView}

    @since: 2010-04-12
    """

    __author__ = "Moritz Wade"
    __contact__ = "*****@*****.**"
    __copyright__ = "Zuse Institute Berlin 2010"

    dirtyChanged = Signal(bool)

    def GetDirty(self):
        return self.__Dirty


    def SetDirty(self, value):
        self.__Dirty = value
        self.dirtyChanged.emit(value)


    def DelDirty(self):
        del self.__Dirty

    Dirty = property(GetDirty, SetDirty, DelDirty,
        "Defines whether this model has any unsaved changes. This is passed through to SbmlMainModel's Dirty.")


    def __init__(self, filename=None, views=[], networkViewController=None):
        """
        Sets up some instance variables. Most importantly,
        it executes the loading of a SBML file, if a filename is given.
        """
        super(ModelController, self).__init__()

        self.filename = None    # will be set by self._loadFile
        self.sbmlModel = None
        self.treeModel = None
        self.selectionModel = None
        self.proxyModel = None # we have the proxy model here, so that all Views can use it and the same SelectionModel still works (!)

        self.views = views
        self.networkViewController = networkViewController # a special place for the NetworkViewController

        if filename is not None:
            self._loadFile(filename)

    def setViews(self, views=None, networkViewController=None):
        """
        Can be used to re-reference the ModelController with Views (either if they
        haven't been given to the Constructor or if they have changed somehow).
        This internally calls self._connectViews to set the correct models and a
        single QSelectionModel on the views.
        """
        if views:
            self.views = views
        if networkViewController:
            self.networkViewController = networkViewController

        self._connectViews()
        if self.networkViewController:
            self.networkViewController._createGraph()

    def _loadFile(self, filename=None):
        """
        Loads a SBML file. It invokes the creation of a data model and
        a networkx graph based on the SBML data.

        @param filename: Name of the SBML file
        @type filename: str
        """
        if filename is None:
            return

        self.filename = filename

        self.sbmlModel = SBMLMainModel(filename)
        self.treeModel = self.sbmlModel.MainTreeModel
        self.sbmlModel.dirtyChanged.connect(self.on_dirtyChanged)

        #        self.proxyModel = self.treeModel   # DEBUGGING: "disabling" the proxy approach
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setSortRole(Qt.UserRole)
        try:
            self.proxyModel.setSourceModel(self.treeModel)
        except Exception, e:
            # try again
            logging.debug("ModelController._loadFile(): Could not set source model for proxy model. Trying again. Original Error: %s" % e)
            self._loadFile(filename)

        self.selectionModel = QItemSelectionModel(self.proxyModel)

        self._connectViews()    # probably not needed here, there is no View after __init__
        if self.networkViewController:
            self.networkViewController._createGraph()

        self.Dirty = False