Пример #1
0
class ScheduleTable(Table):
    COLUMNS = [
        Column('start_date', 80),
        Column('stop_date', 80),
        Column('repeat_type', 80),
        Column('interval', 50),
        Column('description', 110),
        Column('payee', 110),
        Column('checkno', 70),
        Column('from', 100),
        Column('to', 100),
        Column('amount',
               97,
               alignment=Qt.AlignRight,
               painter=AMOUNT_PAINTER,
               resizeToFit=True),
    ]

    def __init__(self, model, view):
        Table.__init__(self, model, view)
        self.view.sortByColumn(
            0, Qt.AscendingOrder)  # sorted by start_date by default
        self.view.deletePressed.connect(self.model.delete)
        self.view.doubleClicked.connect(self.model.edit)
        # we have to prevent Return from initiating editing.
        self.view.editSelected = lambda: None
Пример #2
0
class PluginListTable(Table):
    COLUMNS = [
        Column('enabled', 60),
        Column('name', 300),
        Column('type', 150),
        Column('author', 120),
    ]

    # --- Override
    def _getData(self, row, column, role):
        if column.name == 'enabled':
            if role == Qt.CheckStateRole:
                return Qt.Checked if row.enabled else Qt.Unchecked
            else:
                return None
        else:
            return Table._getData(self, row, column, role)

    def _getFlags(self, row, column):
        flags = Table._getFlags(self, row, column)
        if column.name == 'enabled':
            flags |= Qt.ItemIsUserCheckable
        return flags

    def _setData(self, row, column, value, role):
        if column.name == 'enabled':
            if role == Qt.CheckStateRole:
                row.enabled = not row.enabled
                return True
            else:
                return False
        else:
            return Table._setData(self, row, column, value, role)
Пример #3
0
class IgnoreListTable(Table):
    """ Ignore list model"""

    COLUMNS = [
        Column("path1", defaultWidth=230),
        Column("path2", defaultWidth=230),
    ]
Пример #4
0
class ProblemTable(Table):
    COLUMNS = [
        Column('path', defaultWidth=150),
        Column('msg', defaultWidth=150),
    ]

    def __init__(self, model, view, **kwargs):
        super().__init__(model, view, **kwargs)
Пример #5
0
class ProblemTable(Table):
    COLUMNS = [
        Column('path', defaultWidth=150),
        Column('msg', defaultWidth=150),
    ]

    def __init__(self, model, view):
        Table.__init__(self, model, view)
Пример #6
0
class ProblemTable(Table):
    COLUMNS = [
        Column("path", default_width=150),
        Column("msg", default_width=150),
    ]

    def __init__(self, model, view, **kwargs):
        super().__init__(model, view, **kwargs)
Пример #7
0
class ExcludeListTable(Table):
    """Model for exclude list"""
    COLUMNS = [
        Column("marked", defaultWidth=15),
        Column("regex", defaultWidth=230)
    ]

    def __init__(self, app, view, **kwargs):
        model = app.model.exclude_list_dialog.exclude_list_table  # pointer to GUITable
        super().__init__(model, view, **kwargs)
        font = view.font()
        font.setPointSize(app.prefs.tableFontSize)
        view.setFont(font)
        fm = QFontMetrics(font)
        view.verticalHeader().setDefaultSectionSize(fm.height() + 2)
        # app.willSavePrefs.connect(self.appWillSavePrefs)

    def _getData(self, row, column, role):
        if column.name == "marked":
            if role == Qt.CheckStateRole and row.markable:
                return Qt.Checked if row.marked else Qt.Unchecked
            if role == Qt.ToolTipRole and not row.markable:
                return tr("Compilation error: ") + row.get_cell_value("error")
            if role == Qt.DecorationRole and not row.markable:
                return QIcon.fromTheme("dialog-error", QIcon(":/error"))
            return None
        if role == Qt.DisplayRole:
            return row.data[column.name]
        elif role == Qt.FontRole:
            return QFont(self.view.font())
        elif role == Qt.BackgroundRole and column.name == "regex":
            if row.highlight:
                return QColor(10, 200, 10)  # green
        elif role == Qt.EditRole:
            if column.name == "regex":
                return row.data[column.name]
        return None

    def _getFlags(self, row, column):
        flags = Qt.ItemIsEnabled
        if column.name == "marked":
            if row.markable:
                flags |= Qt.ItemIsUserCheckable
        elif column.name == "regex":
            flags |= Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled
        return flags

    def _setData(self, row, column, value, role):
        if role == Qt.CheckStateRole:
            if column.name == "marked":
                row.marked = bool(value)
                return True
        elif role == Qt.EditRole:
            if column.name == "regex":
                return self.model.rename_selected(value)
        return False
Пример #8
0
class TransactionTable(TableWithTransactions):
    COLUMNS = [
        Column('status', 25, cantTruncate=True),
        Column('date', 86, editor=DATE_EDIT, cantTruncate=True),
        Column('description', 230, editor=DESCRIPTION_EDIT),
        Column('payee', 150, editor=PAYEE_EDIT),
        Column('checkno', 80),
        Column('from', 120, editor=ACCOUNT_EDIT),
        Column('to', 120, editor=ACCOUNT_EDIT),
        Column('amount',
               100,
               alignment=Qt.AlignRight,
               cantTruncate=True,
               painter=AMOUNT_PAINTER,
               resizeToFit=True),
        Column('mtime', 140),
    ]

    def __init__(self, model, view):
        TableWithTransactions.__init__(self, model, view)
        self.tableDelegate = TransactionTableDelegate(self.model)
        self.view.setItemDelegate(self.tableDelegate)
        self.view.sortByColumn(1,
                               Qt.AscendingOrder)  # sorted by date by default
        self.view.deletePressed.connect(self.model.delete)
Пример #9
0
class ResultsModel(ResultsModelBase):
    COLUMNS = [
        Column("marked", default_width=30),
        Column("name", default_width=200),
        Column("folder_path", default_width=180),
        Column("size", default_width=60),
        Column("extension", default_width=40),
        Column("dimensions", default_width=100),
        Column("exif_timestamp", default_width=120),
        Column("mtime", default_width=120),
        Column("percentage", default_width=60),
        Column("dupe_count", default_width=80),
    ]
Пример #10
0
class ResultsModel(ResultsModelBase):
    COLUMNS = [
        Column('marked', defaultWidth=30),
        Column('name', defaultWidth=200),
        Column('folder_path', defaultWidth=180),
        Column('size', defaultWidth=60),
        Column('extension', defaultWidth=40),
        Column('dimensions', defaultWidth=100),
        Column('exif_timestamp', defaultWidth=120),
        Column('mtime', defaultWidth=120),
        Column('percentage', defaultWidth=60),
        Column('dupe_count', defaultWidth=80),
    ]
Пример #11
0
class SplitTable(Table):
    COLUMNS = [
        Column('account', 100, editor=ACCOUNT_EDIT),
        Column('memo', 70),
        Column('debit', 90, alignment=Qt.AlignRight),
        Column('credit', 90, alignment=Qt.AlignRight),
    ]
    INVALID_INDEX_FLAGS = Qt.ItemIsEnabled | Qt.ItemIsDropEnabled

    def __init__(self, model, view):
        Table.__init__(self, model, view)
        # XXX If we don't call that, our columns will all be very small. Find a more elegant way,
        # prefeably in the core, to avoid these situations.
        self.columns.setColumnsWidth(None)
        view.keyPressed.connect(self.keyPressed)

    def _getFlags(self, row, column):
        flags = Table._getFlags(self, row, column)
        return flags | Qt.ItemIsDragEnabled

    # --- Drag & Drop
    def dropMimeData(self, mimeData, action, row, column, parentIndex):
        if not mimeData.hasFormat(MIME_INDEX):
            return False
        # Since we only drop in between items, parentIndex must be invalid, and we use the row arg
        # to know where the drop took place.
        if parentIndex.isValid():
            return False
        index = int(bytes(mimeData.data(MIME_INDEX)).decode())
        self.model.move_split(index, row)
        return True

    def mimeData(self, indexes):
        data = str(indexes[0].row())
        mimeData = QMimeData()
        mimeData.setData(MIME_INDEX, QByteArray(data.encode()))
        return mimeData

    def mimeTypes(self):
        return [MIME_INDEX]

    def supportedDropActions(self):
        return Qt.MoveAction

    # --- Event Handlers
    def keyPressed(self, event):
        # return
        if (event.key() == Qt.Key_Down) and (self.model.selected_index
                                             == len(self.model) - 1):
            event.ignore()
            self.model.add()
Пример #12
0
class ElementTable(Table):
    COLUMNS = [
        Column('page', 50),
        Column('order', 50),
        Column('x', 50),
        Column('y', 50),
        Column('fontsize', 70),
        Column('text_length', 70),
        Column('state', 75),
        Column('text', 150),
    ]

    def __init__(self, model, view):
        Table.__init__(self, model, view)
        self._setupKeyBindings()

    def _setupKeyBindings(self):
        # we have to keep a reference to the shortcuts for them not to be freed right away
        self.shortcuts = []
        for c in SHORTCUTKEY2FLAG:
            seq = QKeySequence(c)
            shortcut = QShortcut(seq, self.view, None, None, Qt.WidgetShortcut)
            shortcut.activated.connect(self.keyActivated)
            self.shortcuts.append(shortcut)

    #--- Event Handlers
    def keyActivated(self):
        shortcut = self.sender()
        key = shortcut.key().toString()
        self.model.press_key(key)
Пример #13
0
class GeneralLedgerTable(TableWithTransactions):
    COLUMNS = [
        Column('status', 25, cantTruncate=True),
        Column('date', 86, editor=DATE_EDIT, cantTruncate=True),
        Column('reconciliation_date', 110, editor=DATE_EDIT,
               cantTruncate=True),
        Column('description', 150, editor=DESCRIPTION_EDIT),
        Column('payee', 150, editor=PAYEE_EDIT),
        Column('checkno', 100),
        Column('transfer', 120, editor=ACCOUNT_EDIT),
        Column('debit', 95, alignment=Qt.AlignRight, cantTruncate=True),
        Column('credit', 95, alignment=Qt.AlignRight, cantTruncate=True),
        Column('balance', 110, alignment=Qt.AlignRight, cantTruncate=True),
    ]

    def __init__(self, model, view):
        TableWithTransactions.__init__(self, model, view)
        self.view.deletePressed.connect(self.model.delete)

    # --- Override
    def _getData(self, row, column, role):
        is_account_row = self.model.is_account_row(row)
        if role == EXTRA_ROLE:
            flags = 0
            if is_account_row:
                flags |= EXTRA_SPAN_ALL_COLUMNS
            return flags
        elif is_account_row:
            if role == Qt.DisplayRole:
                return row.account_name
            elif role == Qt.FontRole:
                font = QFont(self.view.font())
                font.setBold(True)
                return font
            elif role == Qt.BackgroundRole:
                return QBrush(QColor(Qt.lightGray))
        elif role == Qt.FontRole:
            font = QFont(self.view.font())
            is_bold = self.model.is_bold_row(row)
            font.setBold(is_bold)
            return font
        else:
            return TableWithTransactions._getData(self, row, column, role)

    def reset(self):
        TableWithTransactions.reset(self)
        self.view.clearSpans()
        for index, row in enumerate(self.model):
            if self.model.is_account_row(row):
                self.view.setSpan(index, 0, 1, len(self.COLUMNS))
Пример #14
0
class NetWorthSheet(AccountSheet):
    COLUMNS = [
        Column('name', 133),
        Column('account_number', 80),
        Column('end', 100, alignment=Qt.AlignRight),
        Column('start', 100, alignment=Qt.AlignRight),
        Column('delta', 100, alignment=Qt.AlignRight),
        Column('delta_perc', 100),
        Column('budgeted', 100, alignment=Qt.AlignRight),
    ]
    AMOUNT_ATTRS = {'end', 'start', 'delta', 'delta_perc', 'budgeted'}
    BOLD_ATTRS = {'end'}
Пример #15
0
class ExportAccountTable(Table):
    COLUMNS = [
        Column('name', 80),
        Column('export', 60),
    ]

    def __init__(self, model, view):
        Table.__init__(self, model, view)
        view.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
        view.horizontalHeader().setSectionResizeMode(1, QHeaderView.Fixed)

    # --- Data methods override
    def _getData(self, row, column, role):
        if column.name == 'export':
            if role == Qt.CheckStateRole:
                return Qt.Checked if row.export else Qt.Unchecked
            else:
                return None
        else:
            return Table._getData(self, row, column, role)

    def _getFlags(self, row, column):
        flags = Table._getFlags(self, row, column)
        if column.name == 'export':
            flags |= Qt.ItemIsUserCheckable | Qt.ItemIsEditable
        return flags

    def _setData(self, row, column, value, role):
        if column.name == 'export':
            if role == Qt.CheckStateRole:
                row.export = value
                return True
            else:
                return False
        else:
            return Table._setData(self, row, column, value, role)
Пример #16
0
class ProfitSheet(AccountSheet):
    COLUMNS = [
        Column('name', 133),
        Column('account_number', 80),
        Column('cash_flow', 100, alignment=Qt.AlignRight),
        Column('last_cash_flow', 100, alignment=Qt.AlignRight),
        Column('delta', 100, alignment=Qt.AlignRight),
        Column('delta_perc', 100),
        Column('budgeted', 100, alignment=Qt.AlignRight),
    ]
    AMOUNT_ATTRS = {
        'cash_flow', 'last_cash_flow', 'delta', 'delta_perc', 'budgeted'
    }
    BOLD_ATTRS = {
        'cash_flow',
    }
Пример #17
0
class ImportTable(Table):
    COLUMNS = [
        Column('will_import', 20, editor=NO_EDIT),
        Column('date', 80),
        Column('description', 90),
        Column('amount', 90, alignment=Qt.AlignRight),
        Column('bound', 22),
        Column('date_import', 80),
        Column('description_import', 90),
        Column('payee_import', 90),
        Column('checkno_import', 57),
        Column('transfer_import', 90),
        Column('amount_import', 90, alignment=Qt.AlignRight),
    ]

    def __init__(self, model, view):
        Table.__init__(self, model, view)
        self.view.clicked.connect(self.cellClicked)
        self.view.spacePressed.connect(self.spacePressed)

    # --- Data methods override
    def _getData(self, row, column, role):
        if column.name == 'will_import':
            if role == Qt.CheckStateRole:
                return Qt.Checked if row.will_import else Qt.Unchecked
            else:
                return None
        elif column.name == 'bound':
            if role == Qt.DecorationRole:
                return QPixmap(':/lock_12') if row.bound else None
            else:
                return None
        else:
            return Table._getData(self, row, column, role)

    def _getFlags(self, row, column):
        flags = Table._getFlags(self, row, column)
        if column.name == 'will_import':
            flags |= Qt.ItemIsUserCheckable | Qt.ItemIsEditable
            if not row.can_edit_will_import:
                flags &= ~Qt.ItemIsEnabled
        if not row.bound:
            flags |= Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled
        return flags

    def _setData(self, row, column, value, role):
        if column.name == 'will_import':
            if role == Qt.CheckStateRole:
                row.will_import = value
                return True
            else:
                return False
        else:
            return Table._setData(self, row, column, value, role)

    # --- Drag & Drop
    def dropMimeData(self, mimeData, action, row, column, parentIndex):
        if not mimeData.hasFormat(MIME_INDEXES):
            return False
        if not parentIndex.isValid():
            return False
        strMimeData = bytes(mimeData.data(MIME_INDEXES)).decode()
        indexes = list(map(int, strMimeData.split(',')))
        if len(indexes) != 1:
            return False
        index = indexes[0]
        if not self.model.can_bind(index, parentIndex.row()):
            return False
        # If we dont do the layoutChanged thing, we get a weird situation where the row below the
        # the dragged row has its will_import unchecked.
        self.layoutAboutToBeChanged.emit()
        self.model.bind(index, parentIndex.row())
        self.layoutChanged.emit()
        return True

    def mimeData(self, indexes):
        rows = set(str(index.row()) for index in indexes)
        data = ','.join(rows)
        mimeData = QMimeData()
        mimeData.setData(MIME_INDEXES, QByteArray(data.encode()))
        return mimeData

    def mimeTypes(self):
        return [MIME_INDEXES]

    def supportedDropActions(self):
        return Qt.MoveAction

    # --- Private
    def _switchToOneSidedMode(self):
        h = self.view.horizontalHeader()
        if h.isSectionHidden(1):
            return # already in one sided mode
        for i in [1, 2, 3, 4]:
            h.hideSection(i)

    def _switchToTwoSidedMode(self):
        h = self.view.horizontalHeader()
        if not h.isSectionHidden(1):
            return # already in two sided mode
        for i in [1, 2, 3, 4]:
            h.showSection(i)

    # --- Public
    def updateColumnsVisibility(self):
        if self.model.is_two_sided:
            self._switchToTwoSidedMode()
        else:
            self._switchToOneSidedMode()

    # --- Event Handling
    def cellClicked(self, index):
        column = self.model.columns.column_by_index(index.column())
        rowattr = column.name
        if rowattr == 'bound':
            self.model.unbind(index.row())

    def spacePressed(self):
        selectedIndexes = self.view.selectionModel().selectedRows()
        for index in selectedIndexes:
            row = self.model[index.row()]
            row.will_import = not row.will_import
        self.refresh()
Пример #18
0
class IgnoreListTable(Table):
    COLUMNS = [
        Column("path1", defaultWidth=230),
        Column("path2", defaultWidth=230),
    ]
Пример #19
0
class EntryTable(TableWithTransactions):
    COLUMNS = [
        Column('status', 25, cantTruncate=True),
        Column('date', 86, editor=DATE_EDIT, cantTruncate=True),
        Column('reconciliation_date', 110, editor=DATE_EDIT,
               cantTruncate=True),
        Column('description', 150, editor=DESCRIPTION_EDIT),
        Column('payee', 150, editor=PAYEE_EDIT),
        Column('checkno', 100),
        Column('transfer', 120, editor=ACCOUNT_EDIT),
        Column('increase',
               95,
               alignment=Qt.AlignRight,
               cantTruncate=True,
               painter=AMOUNT_PAINTER,
               resizeToFit=True),
        Column('decrease',
               95,
               alignment=Qt.AlignRight,
               cantTruncate=True,
               painter=AMOUNT_PAINTER,
               resizeToFit=True),
        Column('debit', 95, alignment=Qt.AlignRight, cantTruncate=True),
        Column('credit', 95, alignment=Qt.AlignRight, cantTruncate=True),
        Column('balance', 110, alignment=Qt.AlignRight, cantTruncate=True),
    ]

    def __init__(self, model, view):
        TableWithTransactions.__init__(self, model, view)
        self.tableDelegate = EntryTableDelegate(self.model)
        self.view.setItemDelegate(self.tableDelegate)
        self.view.sortByColumn(1,
                               Qt.AscendingOrder)  # sorted by date by default
        self.view.spacePressed.connect(self.model.toggle_reconciled)
        self.view.deletePressed.connect(self.model.delete)

    # --- Data methods override
    def _getStatusData(self, row, role):
        # DecorationRole is handled in TableWithTransactions
        if role == Qt.CheckStateRole:
            if row.can_reconcile():
                return Qt.Checked if row.reconciled else Qt.Unchecked
            else:
                return None
        else:
            return TableWithTransactions._getStatusData(self, row, role)

    def _getFlags(self, row, column):
        flags = TableWithTransactions._getFlags(self, row, column)
        if column.name == 'status':
            if row.can_reconcile():
                flags |= Qt.ItemIsUserCheckable
        return flags

    def _setData(self, row, column, value, role):
        if column.name == 'status':
            if role == Qt.CheckStateRole:
                row.toggle_reconciled()
                self._overrideNextSelectionUpdate()
                return True
            else:
                return False
        else:
            return TableWithTransactions._setData(self, row, column, value,
                                                  role)
Пример #20
0
class ResultsModel(ResultsModelBase):
    COLUMNS = [
        Column("marked", default_width=30),
        Column("name", default_width=200),
        Column("folder_path", default_width=180),
        Column("size", default_width=60),
        Column("duration", default_width=60),
        Column("bitrate", default_width=50),
        Column("samplerate", default_width=60),
        Column("extension", default_width=40),
        Column("mtime", default_width=120),
        Column("title", default_width=120),
        Column("artist", default_width=120),
        Column("album", default_width=120),
        Column("genre", default_width=80),
        Column("year", default_width=40),
        Column("track", default_width=40),
        Column("comment", default_width=120),
        Column("percentage", default_width=60),
        Column("words", default_width=120),
        Column("dupe_count", default_width=80),
    ]
Пример #21
0
class IgnoreListTable(Table):
    COLUMNS = [
        Column('path1', defaultWidth=230),
        Column('path2', defaultWidth=230),
    ]
Пример #22
0
class ResultsModel(ResultsModelBase):
    COLUMNS = [
        Column('marked', defaultWidth=30),
        Column('name', defaultWidth=200),
        Column('folder_path', defaultWidth=180),
        Column('size', defaultWidth=60),
        Column('duration', defaultWidth=60),
        Column('bitrate', defaultWidth=50),
        Column('samplerate', defaultWidth=60),
        Column('extension', defaultWidth=40),
        Column('mtime', defaultWidth=120),
        Column('title', defaultWidth=120),
        Column('artist', defaultWidth=120),
        Column('album', defaultWidth=120),
        Column('genre', defaultWidth=80),
        Column('year', defaultWidth=40),
        Column('track', defaultWidth=40),
        Column('comment', defaultWidth=120),
        Column('percentage', defaultWidth=60),
        Column('words', defaultWidth=120),
        Column('dupe_count', defaultWidth=80),
    ]