def __init__(self, store, aID, name, currency=0, balance=0.0, mintId=None, currNick=False): ORMObject.__init__(self) self.IsFrozen = True self.Store = store self.ID = aID self._Name = name self._Transactions = None self._RecurringTransactions = [] self._preTransactions = [] # Make sure that Currency and Balance are not None (bug #653716) self.Currency = currency or 0 self.Balance = balance or 0.0 self.MintId = mintId or None self.ShowCurrencyNick = currNick or False self.IsFrozen = False Publisher.subscribe(self.onTransactionAmountChanged, "ormobject.updated.Transaction.Amount")
def __init__(self, parent, editing=None): wx.Panel.__init__(self, parent) # Create the recurring object we will use internally. self.recurringObj = RecurringTransaction(None, None, 0, "", datetime.date.today(), RecurringTransaction.DAILY) self.Sizer = wx.GridBagSizer(0, 3) self.Sizer.SetEmptyCellSize((0,0)) self.recurringRow = RecurringRow(self, self.RECURRING_ROW) self.recurringSummaryRow = RecurringSummaryRow(self, self.SUMMARY_ROW) self.weeklyRecurringRow = WeeklyRecurringRow(self, self.WEEKLY_ROW) self.transferRow = TransferRow(self, self.TRANSFER_ROW) self.transactionRow = NewTransactionRow(self, self.TRANSACTION_ROW, editing=editing) # can not set 2nd column growable in wx3.0 if Sizer is empty self.Sizer.AddGrowableCol(1, 1) # RecurringRow needs an update once both it and the other controls exist. self.recurringRow.Update() # Hide everything up to the actual transaction row initially. if not editing: for i in range(self.TRANSACTION_ROW): self.ShowRow(i, False) ctrlId = id(self.transactionRow) Publisher.subscribe(self.onTransferToggled, "newtransaction.%i.transfertoggled"%ctrlId) Publisher.subscribe(self.onRecurringToggled, "newtransaction.%i.recurringtoggled"%ctrlId)
def __init__(self, parent, editing=None): wx.Panel.__init__(self, parent) # Create the recurring object we will use internally. self.recurringObj = RecurringTransaction(None, None, 0, "", datetime.date.today(), RecurringTransaction.DAILY) self.Sizer = wx.GridBagSizer(0, 3) self.Sizer.SetEmptyCellSize((0, 0)) self.recurringRow = RecurringRow(self, self.RECURRING_ROW) self.recurringSummaryRow = RecurringSummaryRow(self, self.SUMMARY_ROW) self.weeklyRecurringRow = WeeklyRecurringRow(self, self.WEEKLY_ROW) self.transferRow = TransferRow(self, self.TRANSFER_ROW) self.transactionRow = NewTransactionRow(self, self.TRANSACTION_ROW, editing=editing) # can not set 2nd column growable in wx3.0 if Sizer is empty self.Sizer.AddGrowableCol(1, 1) # RecurringRow needs an update once both it and the other controls exist. self.recurringRow.Update() # Hide everything up to the actual transaction row initially. if not editing: for i in range(self.TRANSACTION_ROW): self.ShowRow(i, False) ctrlId = id(self.transactionRow) Publisher.subscribe(self.onTransferToggled, "newtransaction.%i.transfertoggled" % ctrlId) Publisher.subscribe(self.onRecurringToggled, "newtransaction.%i.recurringtoggled" % ctrlId)
def __init__(self, parent, plotFactory, bankController): wx.Panel.__init__(self, parent) self.plotFactory = plotFactory self.bankController = bankController self.plotSettings = {'FitDegree': 2, 'Granularity': 100, 'Account': None, 'Months': 12} self.plotLabels = [_("Trend Degree"), _("Months")] self.currentPlotIndex = 0 self.cachedData = None self.dateRange = None self.isActive = False # create the plot panel self.plotPanel = plotFactory.createPanel(self, bankController) # create the controls at the bottom controlSizer = wx.BoxSizer() self.graphChoice = wx.Choice(self, choices=[plot.NAME for plot in plotFactory.Plots]) self.optionCtrl = wx.SpinCtrl(self, min=1, max=24, initial=self.plotSettings['FitDegree']) # the date range controls self.startDate = bankcontrols.DateCtrlFactory(self) self.endDate = bankcontrols.DateCtrlFactory(self) self.optionText = wx.StaticText(self, label=self.plotLabels[0]) self.fromText = wx.StaticText(self, label=_("From")) self.toText = wx.StaticText(self, label=_("until")) controlSizer.Add(wx.StaticText(self, label=_("Graph")), 0, wx.ALIGN_CENTER_VERTICAL) controlSizer.AddSpacer(5) controlSizer.Add(self.graphChoice, 0, wx.ALIGN_CENTER_VERTICAL) controlSizer.AddSpacer(10) controlSizer.Add(self.fromText, 0, wx.ALIGN_CENTER_VERTICAL) controlSizer.AddSpacer(5) controlSizer.Add(self.startDate, 0, wx.ALIGN_CENTER_VERTICAL) controlSizer.AddSpacer(5) controlSizer.Add(self.toText, 0, wx.ALIGN_CENTER_VERTICAL) controlSizer.AddSpacer(5) controlSizer.Add(self.endDate, 0, wx.ALIGN_CENTER_VERTICAL) controlSizer.AddSpacer(10) controlSizer.Add(self.optionText, 0, wx.ALIGN_CENTER_VERTICAL) controlSizer.AddSpacer(5) controlSizer.Add(self.optionCtrl, 0, wx.ALIGN_CENTER_VERTICAL) self.optionCtrl.SetMinSize = (20, -1) # put it all together self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.Add(self.plotPanel, 1, wx.EXPAND) self.Sizer.Add(controlSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 6) self.Layout() # bind to the spin buttons self.graphChoice.Bind(wx.EVT_CHOICE, self.onGraphChoice) self.optionCtrl.Bind(wx.EVT_SPINCTRL, self.onOptionSpin) self.Bind(wx.EVT_DATE_CHANGED, self.onDateRangeChanged) Publisher.subscribe(self.onAccountSelect, "view.account changed")
def __init__(self, path, autoSave=True): self.Subscriptions = [] self.Version = 13 self.Path = path self.AutoSave = False self.Dirty = False self.BatchDepth = 0 self.cachedModel = None # Upgrades can't enable syncing if needed from older versions. self.needsSync = False existed = True # See if the path already exists to decide what to do. if not os.path.exists(self.Path): existed = False # Initialize the connection and optimize it. connection = sqlite.connect(self.Path) self.dbconn = connection # Disable synchronous I/O, which makes everything MUCH faster, at the potential cost of durability. self.dbconn.execute("PRAGMA synchronous=OFF;") # If the db doesn't exist, initialize it. if not existed: debug.debug('Initializing', self.Path) self.initialize() else: debug.debug('Loading', self.Path) self.Meta = self.getMeta() debug.debug(self.Meta) while self.Meta['VERSION'] < self.Version: # If we are creating a new db, we don't need to backup each iteration. self.upgradeDb(self.Meta['VERSION'], backup=existed) self.Meta = self.getMeta() debug.debug(self.Meta) # We have to subscribe before syncing otherwise it won't get synced if there aren't other changes. self.Subscriptions = ( (self.onORMObjectUpdated, "ormobject.updated"), (self.onAccountBalanceChanged, "account.balance changed"), (self.onAccountRemoved, "account.removed"), (self.onBatchEvent, "batch"), (self.onExit, "exiting"), ) for callback, topic in self.Subscriptions: Publisher.subscribe(callback, topic) # If the upgrade process requires a sync, do so now. if self.needsSync: self.syncBalances() self.needsSync = False self.AutoSave = autoSave self.commitIfAppropriate()
def __init__(self, bankmodel, store): list.__init__(self, store.GetAccounts()) # Make sure all the items know their parent list. for account in self: account.Parent = self self.BankModel = bankmodel self.Store = store self.sort() Publisher.subscribe(self.onAccountRenamed, "ormobject.updated.Account.Name")
def __init__(self, parent, bankController): GroupListView.__init__(self, parent, style=wx.LC_REPORT|wx.SUNKEN_BORDER, name="TransactionOLV") self.LastSearch = None self.CurrentAccount = None self.BankController = bankController self.showGroups = False #WXTODO: figure out these (and the text color, or is that already?) from theme (LP: ???) self.evenRowsBackColor = wx.Colour(224,238,238) self.oddRowsBackColor = wx.WHITE self.cellEditMode = GroupListView.CELLEDIT_DOUBLECLICK self.SetEmptyListMsg(self.EMPTY_MSG_NORMAL) # Calculate the necessary width for the date column. dateStr = str(datetime.date.today()) dateWidth = self.GetTextExtent(dateStr)[0] + 10 # Define some constants to use throughout. self.COL_DATE = 0 self.COL_DESCRIPTION = 1 self.COL_AMOUNT = 2 self.COL_TOTAL = 3 # If you change these column names, update sizeAmounts()! self.SetColumns([ ColumnDefn(_("Date"), valueGetter=self.getDateAndIDOf, valueSetter=self.setDateOf, stringConverter=self.renderDateIDTuple, editFormatter=self.renderEditDate, width=dateWidth), ColumnDefn(_("Description"), valueGetter="Description", isSpaceFilling=True, editFormatter=self.renderEditDescription), ColumnDefn(_("Amount"), "right", valueGetter=self.getAmount, valueSetter=self.setAmount, stringConverter=self.renderFloat, editFormatter=self.renderEditFloat), ColumnDefn(_("Balance"), "right", valueGetter=self.getTotal, stringConverter=self.renderFloat, isEditable=False), ]) # Our custom hack in OLV.py:2017 will render amount floats appropriately as %.2f when editing. # By default, sort by the date column, ascending. self.SORT_COL = self.COL_DATE self.SortBy(self.SORT_COL) self.Bind(wx.EVT_RIGHT_DOWN, self.onRightDown) self.Subscriptions = ( (self.onSearch, "SEARCH.INITIATED"), (self.onSearchCancelled, "SEARCH.CANCELLED"), (self.onSearchMoreToggled, "SEARCH.MORETOGGLED"), (self.onTransactionAdded, "transaction.created"), (self.onTransactionsRemoved, "transactions.removed"), (self.onCurrencyChanged, "currency_changed"), (self.onShowCurrencyNickToggled, "controller.show_currency_nick_toggled"), (self.updateTotals, "ormobject.updated.Transaction.Amount"), (self.onTransactionDateUpdated, "ormobject.updated.Transaction.Date"), ) for callback, topic in self.Subscriptions: Publisher.subscribe(callback, topic)
def __init__(self, parent, bankController): wx.Panel.__init__(self, parent) self.ID_TIMER = wx.NewId() self.SearchTimer = wx.Timer(self, self.ID_TIMER) self.bankController = bankController self.searchCtrl = bankcontrols.UpdatableSearchCtrl(self, value="", size=(200, -1), style=wx.TE_PROCESS_ENTER) # Try to grab the GTK system icon for clearing a search, otherwise we'll get the wxPython one. iconSize = self.searchCtrl.GetClientRect().GetHeight() - 2 clearBitmap = wx.ArtProvider.GetBitmap('edit-clear', wx.ART_OTHER, [iconSize, iconSize]) if clearBitmap: self.searchCtrl.SetCancelBitmap(clearBitmap) self.searchCtrl.ShowCancelButton(True) self.searchCtrl.ShowSearchButton(False) self.searchCtrl.DescriptiveText = _("Search transactions") self.searchCtrl.SetForegroundColour('DARK GRAY') # The More/Less button. self.moreButton = bankcontrols.MultiStateButton(self, labelDict={True: _("More options"), False: _("Less options")}, state=True) self.matchChoices = [_("Amount"), _("Description"), _("Date")] self.descriptionSelection = 1 self.matchBox = bankcontrols.CompactableComboBox(self, value=self.matchChoices[1], choices=self.matchChoices, style=wx.CB_READONLY) topSizer = wx.BoxSizer() topSizer.Add(self.searchCtrl, 0, wx.ALIGN_CENTER_VERTICAL) topSizer.AddSpacer(10) topSizer.Add(self.moreButton, 0, wx.ALIGN_CENTER_VERTICAL) self.moreSizer = moreSizer = wx.BoxSizer() moreSizer.Add(wx.StaticText(self, label=_("Match: ")), 0, wx.ALIGN_CENTER_VERTICAL) moreSizer.Add(self.matchBox, 0, wx.ALIGN_CENTER_VERTICAL) self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.Add(topSizer, 0, wx.ALIGN_RIGHT|wx.TOP|wx.BOTTOM, 2) self.Sizer.Add(moreSizer, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 2) self.matchBox.Compact() self.Layout() self.searchCtrl.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.onCancel) self.searchCtrl.Bind(wx.EVT_TEXT, self.onText) #self.searchCtrl.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.onSearch) self.searchCtrl.Bind(wx.EVT_TEXT_ENTER, self.onSearch) self.moreButton.Bind(wx.EVT_BUTTON, self.onToggleMore) # Bindings to search on settings change automatically. self.matchBox.Bind(wx.EVT_COMBOBOX, self.onSearchTrigger) self.Bind(wx.EVT_TIMER, self.onSearchTimer) Publisher.subscribe(self.onExternalSearch, "SEARCH.EXTERNAL") # Initially hide the extra search options. self.onToggleMore()
def __init__(self, bankController, parent, plotSettings=None): wx.Panel.__init__(self, parent) baseplot.BasePlot.__init__(self) self.bankController = bankController self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnSize) self.data = None self.x_labels = None self.plotSettings = plotSettings # watch if there's any currency change to repaint the plot. Publisher.subscribe(self.currencyChanged, "controller.show_currency_nick_toggled") Publisher.subscribe(self.currencyChanged, "currency_changed")
def __init__(self, parent, bankController): wx.Panel.__init__(self, parent) self.bankController = bankController self.mainPanel = managetab.MainPanel(self, bankController) Publisher.subscribe(self.onRecurringTransactionAdded, "recurringtransaction.created") Publisher.subscribe(self.onRecurringTransactionUpdated, "recurringtransaction.updated") self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.Add(self.mainPanel, 1, wx.EXPAND) wx.CallLater(1000, self.CheckRecurringTransactions)
def testAnnouncedAccountHasParent(self): """ Make sure the account has a Parent when it announces itself. To do this we need to test this in a listener. """ parent = [] def listener(message): account = message.data parent.append(account.Parent) # Subscribe our listener Publisher.subscribe(listener, "account.created") # Create an account, which should trigger the listener baby = self.Model.CreateAccount("Baby") # Make sure the listener updated state appropriately self.assertTrue(parent)
def __init__(self, parent, row): bankcontrols.GBRow.__init__(self, parent, row) self.accountDict = {} self.nullChoice = ["----------"] self.fromtoBox = wx.Choice(parent, choices=[_("from"), _("to")]) self.accountSelection = wx.Choice(parent, choices=[]) hSizer = wx.BoxSizer() hSizer.Add(wx.StaticText(parent, label=_("Transfer")), flag=wx.ALIGN_CENTER_VERTICAL) hSizer.AddSpacer(3) hSizer.Add(self.fromtoBox, flag=wx.ALIGN_CENTER_VERTICAL) self.AddNext(hSizer) self.AddNext(self.accountSelection) Publisher.subscribe(self.onAccountChanged, "view.account changed")
def testDirtyExitWarns(self): """ This test is kind of hilarious. We want to make sure we are warned of exiting with a dirty model, so we create an account, register a callback which will change its name when the dirty warning goes out, then trigger a dirty exit and make sure the account name has changed. """ self.Controller.AutoSave = False a = self.Model.CreateAccount("Unwarned!") # Create and register our callback to test for the warning message. def cb(message): a.Name = "Warned" Publisher.subscribe(cb, "warning.dirty exit") # Now send the exiting message, which should cause our callback to fire if everything is well. Publisher.sendMessage("exiting") self.assertEqual(a.Name, "Warned")
def __init__(self, path=None): self._AutoSave = True self._ShowZeroBalanceAccounts = True self._ShowCurrencyNick = True self.Models = [] self.InitConfig() self.LoadPath(path, use=True) Publisher.subscribe(self.onAutoSaveToggled, "user.autosave_toggled") Publisher.subscribe(self.onShowZeroToggled, "user.showzero_toggled") Publisher.subscribe(self.onShowCurrencyNickToggled, "user.show_currency_nick_toggled") Publisher.subscribe(self.onSaveRequest, "user.saved")
def __init__(self, bankController, welcome): # Load our window settings. config = wx.Config.Get() size = config.ReadInt('SIZE_X'), config.ReadInt('SIZE_Y') pos = config.ReadInt('POS_X'), config.ReadInt('POS_Y') BrandedFrame.__init__(self, None, title="wxBanker", size=size, pos=pos) self.Panel = BankerPanel(self, bankController) Publisher.subscribe(self.onQuit, "quit") Publisher.subscribe(self.onWarning, "warning") if welcome: Publisher.subscribe(self.onFirstRun, "first run") self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_MOVE, self.OnMove) self.Bind(wx.EVT_CLOSE, self.OnClose) menuBar = BankMenuBar(bankController) self.SetMenuBar(menuBar) #self.CreateStatusBar() self.Bind(wx.EVT_MENU, menuBar.onMenuEvent)
def __init__(self, parent): wx.Panel.__init__(self, parent) self.numberClears = True sizer = wx.BoxSizer(wx.VERTICAL) self.display = wx.TextCtrl(self, -1, '0.00', style=wx.TE_RIGHT) self.display.Bind(wx.EVT_CHAR, self.onChar) sizer.Add(self.display, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 4) gs = wx.GridSizer(4, 4, 3, 3) for lbl in "C ()789/456*123-0.+=": if not lbl == ' ': btn = wx.Button(self, label=lbl) btn.Bind(wx.EVT_BUTTON, self.onButton) else: btn = wx.StaticText(self) gs.Add(btn, 1, wx.EXPAND) sizer.Add(gs, 1, wx.EXPAND) self.SetSizer(sizer) Publisher.subscribe(self.onPushChars, "CALCULATOR.PUSH_CHARS") wx.CallLater(50, self.display.SetInsertionPointEnd)
def __init__(self, parent, bankController): wx.Panel.__init__(self, parent) self.searchActive = False subpanel = wx.Panel(self) # The search control self.searchCtrl = searchctrl.SearchCtrl(self, bankController) self.transactionCtrl = transactionCtrl = TransactionCtrl(subpanel, bankController) self.newTransCtrl = newTransCtrl = transactionctrl.TransactionCtrl(self) subpanel.Sizer = wx.BoxSizer() subpanel.Sizer.Add(transactionCtrl, 1, wx.EXPAND) self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.Add(self.searchCtrl, 0, wx.ALIGN_RIGHT|wx.RIGHT, 6) self.Sizer.Add(subpanel, 1, wx.EXPAND) self.Sizer.Add(newTransCtrl, 0, wx.EXPAND|wx.LEFT, 6) self.Sizer.AddSpacer(3) for message in ["account.created", "account.removed"]: Publisher.subscribe(self.onSearchInvalidatingChange, message)
def __init__(self, parent): wx.Panel.__init__(self, parent) self.numberClears = True sizer = wx.BoxSizer(wx.VERTICAL) self.display = wx.TextCtrl(self, -1, '0.00', style=wx.TE_RIGHT) self.display.Bind(wx.EVT_CHAR, self.onChar) sizer.Add(self.display, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 4) gs = wx.GridSizer(5, 4, 3, 3) for lbl in "C ()789/456*123-0.+=": if not lbl == ' ': btn = wx.Button(self, label=lbl) btn.Bind(wx.EVT_BUTTON, self.onButton) else: btn = wx.StaticText(self) gs.Add(btn, 1, wx.EXPAND) sizer.Add(gs, 1, wx.EXPAND) self.SetSizer(sizer) Publisher.subscribe(self.onPushChars, "CALCULATOR.PUSH_CHARS") wx.CallLater(50, self.display.SetInsertionPointEnd)
def __init__(self, parent, bankController): wx.Panel.__init__(self, parent) ## Left side, the account list and calculator self.leftPanel = leftPanel = wx.Panel(self) leftPanel.Sizer = wx.BoxSizer(wx.VERTICAL) self.accountCtrl = accountCtrl = accountlistctrl.AccountListCtrl(leftPanel, bankController) calcWidget = CollapsableWidget(leftPanel, SimpleCalculator, (_("Show Calculator"), _("Hide Calculator"))) leftPanel.Sizer.Add(accountCtrl, 0, wx.EXPAND) leftPanel.Sizer.AddStretchSpacer(1) leftPanel.Sizer.Add(calcWidget, 0, wx.EXPAND) # Force the calculator widget (and parent) to take on the desired size. for widget in [calcWidget.widget, leftPanel]: widget.SetMinSize((accountCtrl.BestSize[0], -1)) ## Right side, the transaction panel: self.tabPanel = TabPanel(self, bankController) self.Sizer = topSizer = wx.BoxSizer() topSizer.Add(leftPanel, 0, wx.EXPAND|wx.ALL, 5) topSizer.Add(self.tabPanel, 1, wx.EXPAND|wx.ALL, 0) # Subscribe to messages that interest us. Publisher.subscribe(self.onChangeAccount, "view.account changed") Publisher.subscribe(self.onCalculatorToggled, "CALCULATOR.TOGGLED") # Select the last-selected account. # Windows needs a delay, to work around LP #339860. wx.CallLater(50, Publisher.sendMessage, "user.account changed", bankController.Model.GetLastAccount()) self.Layout() # Ensure the calculator is displayed as desired. calcWidget.SetExpanded(wx.Config.Get().ReadBool("SHOW_CALC"))
def __init__(self, parent, bankController, autoPopulate=True): wx.Panel.__init__(self, parent, name="AccountListCtrl") self.bankController = bankController self.Model = bankController.Model # Initialize some attributes to their default values. self.editCtrl = self.hiddenIndex = None self.currentIndex = None self.radioButtons, self.totalTexts, self.accountObjects, self.mintStatuses = [], [], [], [] # Create the staticboxsizer which is the home for everything. # This *MUST* be created first to ensure proper z-ordering (as per docs). self.staticBox = wx.StaticBox(self, label=_("Accounts")) # Create a single panel to be the "child" of the static box sizer, # to work around a wxPython regression that prevents tooltips. lp: xxxxxx self.childPanel = wx.Panel(self) self.childSizer = childSizer = wx.BoxSizer(wx.VERTICAL) ## Create and set up the buttons. # The ADD account button. BMP = self.addBMP = wx.ArtProvider.GetBitmap('wxART_add') self.addButton = addButton = bankcontrols.FlashableButton(self.childPanel, bitmap=BMP) addButton.SetToolTipString(_("Add a new account")) # The REMOVE account button. BMP = wx.ArtProvider.GetBitmap('wxART_delete') self.removeButton = removeButton = wx.BitmapButton(self.childPanel, bitmap=BMP) removeButton.SetToolTipString(_("Remove the selected account")) removeButton.Enabled = False # The EDIT account button. BMP = wx.ArtProvider.GetBitmap('wxART_textfield_rename') self.editButton = editButton = wx.BitmapButton(self.childPanel, bitmap=BMP) editButton.SetToolTipString(_("Rename the selected account")) editButton.Enabled = False # The CONFIGURE account button. BMP = wx.ArtProvider.GetBitmap('wxART_cog') self.configureButton = configureButton = wx.BitmapButton(self.childPanel, bitmap=BMP) configureButton.SetToolTipString(_("Configure the selected account")) configureButton.Enabled = False # Layout the buttons. buttonSizer = wx.BoxSizer() buttonSizer.Add(addButton) buttonSizer.AddSpacer(6) buttonSizer.Add(editButton) buttonSizer.AddSpacer(6) buttonSizer.Add(configureButton) buttonSizer.AddSpacer(6) buttonSizer.Add(removeButton) # Set up the "Total" sizer. self.totalText = wx.StaticText(self.childPanel, label=self.Model.float2str(0)) self.totalTexts.append(self.totalText) miniSizer = wx.BoxSizer() self.allAccountsRadio = wx.RadioButton(self.childPanel, label=_("All accounts")) miniSizer.Add(self.allAccountsRadio, 1, wx.ALIGN_CENTER) miniSizer.Add(self.totalText, 0, wx.ALIGN_CENTER|wx.LEFT, 10) miniSizer.AddSpacer(3) #self.staticBoxSizer = SmoothStaticBoxSizer(self.staticBox, wx.VERTICAL) self.staticBoxSizer = wx.StaticBoxSizer(self.staticBox, wx.VERTICAL) #self.staticBoxSizer.SetSmooth(False) childSizer.Add(buttonSizer, 0, wx.BOTTOM, 9) # Add just a tiny bit of padding between the accounts and the total item. childSizer.AddSpacer(3) childSizer.Add(miniSizer, 0, wx.EXPAND) self.childPanel.Sizer = childSizer self.staticBoxSizer.Add(self.childPanel, 1, wx.EXPAND) # Set up the button bindings. addButton.Bind(wx.EVT_BUTTON, self.onAddButton) removeButton.Bind(wx.EVT_BUTTON, self.onRemoveButton) editButton.Bind(wx.EVT_BUTTON, self.onRenameButton) configureButton.Bind(wx.EVT_BUTTON, self.onConfigureButton) # Set up the link binding. self.Bind(wx.EVT_RADIOBUTTON, self.onAccountClick) # Subscribe to messages we are concerned about. Publisher.subscribe(self.onAccountBalanceChanged, "ormobject.updated.Account.Balance") Publisher.subscribe(self.onAccountRenamed, "ormobject.updated.Account.Name") Publisher.subscribe(self.onTransactionDateChanged, "ormobject.updated.Transaction.Date") Publisher.subscribe(self.onAccountMintIdChanged, "ormobject.updated.Account.MintId") Publisher.subscribe(self.onAccountRemoved, "account.removed") Publisher.subscribe(self.onAccountAdded, "account.created") Publisher.subscribe(self.onCurrencyChanged, "currency_changed") Publisher.subscribe(self.onShowZeroToggled, "controller.showzero_toggled") Publisher.subscribe(self.onShowCurrencyNickToggled, "controller.show_currency_nick_toggled") Publisher.subscribe(self.onAccountChanged, "user.account changed") Publisher.subscribe(self.onSelectNextAccount, "user.next account") Publisher.subscribe(self.onSelectPreviousAccount, "user.previous account") Publisher.subscribe(self.onToggleMintIntegration, "user.mint.toggled") Publisher.subscribe(self.onMintDataUpdated, "mint.updated") # Populate ourselves initially unless explicitly told not to. if autoPopulate: for account in self.Model.Accounts: self._PutAccount(account) self.Sizer = self.staticBoxSizer # Set the minimum size to the amount it needs to display the edit box. self.Freeze() self.showEditCtrl(focus=False) minWidth = max((self.staticBoxSizer.CalcMin()[0], 250)) self.onHideEditCtrl() self.Thaw() self.staticBoxSizer.SetMinSize((minWidth, -1)) # Initially load the visibility of zero-balance accounts! # Don't refresh the selection or we'll send an account changed message which will overwrite the LastAccountId before it gets used! self.refreshVisibility(refreshSelection=False) self.staticBoxSizer.Layout() #self.staticBoxSizer.SetSmooth(True) if not self.GetCount(): self.addButton.StartFlashing()
def __init__(self, parent, bankController, autoPopulate=True): wx.Panel.__init__(self, parent, name="AccountListCtrl") self.bankController = bankController self.Model = bankController.Model # Initialize some attributes to their default values. self.editCtrl = self.hiddenIndex = None self.currentIndex = None self.radioButtons, self.totalTexts, self.accountObjects, self.mintStatuses = [], [], [], [] # Create the staticboxsizer which is the home for everything. # This *MUST* be created first to ensure proper z-ordering (as per docs). self.staticBox = wx.StaticBox(self, label=_("Accounts")) # Create a single panel to be the "child" of the static box sizer, # to work around a wxPython regression that prevents tooltips. lp: xxxxxx self.childPanel = wx.Panel(self) self.childSizer = childSizer = wx.BoxSizer(wx.VERTICAL) ## Create and set up the buttons. # The ADD account button. BMP = self.addBMP = wx.ArtProvider.GetBitmap('wxART_add') self.addButton = addButton = bankcontrols.FlashableButton( self.childPanel, bitmap=BMP) addButton.SetToolTipString(_("Add a new account")) # The REMOVE account button. BMP = wx.ArtProvider.GetBitmap('wxART_delete') self.removeButton = removeButton = wx.BitmapButton(self.childPanel, bitmap=BMP) removeButton.SetToolTipString(_("Remove the selected account")) removeButton.Enabled = False # The EDIT account button. BMP = wx.ArtProvider.GetBitmap('wxART_textfield_rename') self.editButton = editButton = wx.BitmapButton(self.childPanel, bitmap=BMP) editButton.SetToolTipString(_("Rename the selected account")) editButton.Enabled = False # The CONFIGURE account button. BMP = wx.ArtProvider.GetBitmap('wxART_cog') self.configureButton = configureButton = wx.BitmapButton( self.childPanel, bitmap=BMP) configureButton.SetToolTipString(_("Configure the selected account")) configureButton.Enabled = False # Layout the buttons. buttonSizer = wx.BoxSizer() buttonSizer.Add(addButton) buttonSizer.AddSpacer(6) buttonSizer.Add(editButton) buttonSizer.AddSpacer(6) buttonSizer.Add(configureButton) buttonSizer.AddSpacer(6) buttonSizer.Add(removeButton) # Set up the "Total" sizer. self.totalText = wx.StaticText(self.childPanel, label=self.Model.float2str(0)) self.totalTexts.append(self.totalText) miniSizer = wx.BoxSizer() self.allAccountsRadio = wx.RadioButton(self.childPanel, label=_("All accounts")) miniSizer.Add(self.allAccountsRadio, 1, wx.ALIGN_CENTER) miniSizer.Add(self.totalText, 0, wx.ALIGN_CENTER | wx.LEFT, 10) miniSizer.AddSpacer(3) #self.staticBoxSizer = SmoothStaticBoxSizer(self.staticBox, wx.VERTICAL) self.staticBoxSizer = wx.StaticBoxSizer(self.staticBox, wx.VERTICAL) #self.staticBoxSizer.SetSmooth(False) childSizer.Add(buttonSizer, 0, wx.BOTTOM, 9) # Add just a tiny bit of padding between the accounts and the total item. childSizer.AddSpacer(3) childSizer.Add(miniSizer, 0, wx.EXPAND) self.childPanel.Sizer = childSizer self.staticBoxSizer.Add(self.childPanel, 1, wx.EXPAND) # Set up the button bindings. addButton.Bind(wx.EVT_BUTTON, self.onAddButton) removeButton.Bind(wx.EVT_BUTTON, self.onRemoveButton) editButton.Bind(wx.EVT_BUTTON, self.onRenameButton) configureButton.Bind(wx.EVT_BUTTON, self.onConfigureButton) # Set up the link binding. self.Bind(wx.EVT_RADIOBUTTON, self.onAccountClick) # Subscribe to messages we are concerned about. Publisher.subscribe(self.onAccountBalanceChanged, "ormobject.updated.Account.Balance") Publisher.subscribe(self.onAccountRenamed, "ormobject.updated.Account.Name") Publisher.subscribe(self.onTransactionDateChanged, "ormobject.updated.Transaction.Date") Publisher.subscribe(self.onAccountMintIdChanged, "ormobject.updated.Account.MintId") Publisher.subscribe(self.onAccountRemoved, "account.removed") Publisher.subscribe(self.onAccountAdded, "account.created") Publisher.subscribe(self.onCurrencyChanged, "currency_changed") Publisher.subscribe(self.onShowZeroToggled, "controller.showzero_toggled") Publisher.subscribe(self.onShowCurrencyNickToggled, "controller.show_currency_nick_toggled") Publisher.subscribe(self.onAccountChanged, "user.account changed") Publisher.subscribe(self.onSelectNextAccount, "user.next account") Publisher.subscribe(self.onSelectPreviousAccount, "user.previous account") Publisher.subscribe(self.onToggleMintIntegration, "user.mint.toggled") Publisher.subscribe(self.onMintDataUpdated, "mint.updated") # Populate ourselves initially unless explicitly told not to. if autoPopulate: for account in self.Model.Accounts: self._PutAccount(account) self.Sizer = self.staticBoxSizer # Set the minimum size to the amount it needs to display the edit box. self.Freeze() self.showEditCtrl(focus=False) minWidth = max((self.staticBoxSizer.CalcMin()[0], 250)) self.onHideEditCtrl() self.Thaw() self.staticBoxSizer.SetMinSize((minWidth, -1)) # Initially load the visibility of zero-balance accounts! # Don't refresh the selection or we'll send an account changed message which will overwrite the LastAccountId before it gets used! self.refreshVisibility(refreshSelection=False) self.staticBoxSizer.Layout() #self.staticBoxSizer.SetSmooth(True) if not self.GetCount(): self.addButton.StartFlashing()
def __init__(self, bankController, *args, **kwargs): wx.MenuBar.__init__(self, *args, **kwargs) self.bankController = bankController autosave = bankController.AutoSave showZero = bankController.ShowZeroBalanceAccounts showcurrnick = bankController.ShowCurrencyNick self.currencyStrings = CurrencyStrings[:] # File menu. fileMenu = wx.Menu() self.saveMenuItem = fileMenu.Append(wx.ID_SAVE) self.autoSaveMenuItem = fileMenu.AppendCheckItem(self.ID_AUTOSAVE, _("Auto-save"), _("Automatically save changes")) fileMenu.AppendSeparator() importCsvMenu = fileMenu.Append(self.ID_IMPORT_CSV, _("Import from CSV"), _("Import transactions from a CSV file")) exportCsvMenu = fileMenu.Append(self.ID_EXPORT_CSV, _("Export to CSV"), _("Export transactions to a CSV file")) fileMenu.AppendSeparator() quitItem = fileMenu.Append(wx.ID_EXIT) # View menu. viewMenu = wx.Menu() viewMenu.Append(self.ID_VIEW_PREVACCOUNT, _("Previous account")+"\tCtrl+J") viewMenu.Append(self.ID_VIEW_NEXTACCOUNT, _("Next account")+"\tCtrl+K") viewMenu.Append(self.ID_VIEW_ALLACCOUNTS, _("All accounts")+"\tCtrl+T") viewMenu.AppendSeparator() self.showZeroMenuItem = viewMenu.AppendCheckItem(self.ID_SHOWZERO, _("Show zero-balance accounts")+"\tCtrl+B", _("When disabled, accounts with a balance of $0.00 will be hidden from the list")) # Use the initial show-zero setting. self.showZeroMenuItem.Check(showZero) # Settings menu. settingsMenu = wx.Menu() ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. currencyMenu = wx.MenuItem(settingsMenu, -1, _("Base ¤cy"), _("Select currency for the 'All Accounts' balance")) currencyMenu.SetBitmap(wx.ArtProvider.GetBitmap("wxART_money")) # Add an entry for each available currency. currencies = wx.Menu() # Place the local detected one first, then the rest sorted. currencies.Append(self.IDS_CURRENCIES[0], self.currencyStrings[0]) currencies.AppendSeparator() for i, cstr in enumerate(sorted(self.currencyStrings[1:])): idIndex = self.currencyStrings.index(cstr) item = wx.MenuItem(currencies, self.IDS_CURRENCIES[idIndex], cstr) currencies.AppendItem(item) # Add an entry to request a new currency. requestCurrencyItem = wx.MenuItem(currencies, self.ID_REQUESTCURRENCY, _("Request a Currency")) requestCurrencyItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_lightning") currencies.AppendSeparator() currencies.AppendItem(requestCurrencyItem) currencyMenu.SetSubMenu(currencies) settingsMenu.AppendItem(currencyMenu) self.showCurrencyNickItem = settingsMenu.AppendCheckItem(self.ID_SHOWCURRENCYNICK, _("Show currency names"), _("Show currency names with amounts")) self.mintEnabledItem = settingsMenu.AppendCheckItem(self.ID_MINTINTEGRATION, _("Integrate with Mint.com"), _("Sync account balances with an existing Mint.com account")) # Help menu. helpMenu = wx.Menu() ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. faqItem = wx.MenuItem(helpMenu, self.ID_FAQ, _("View &FAQs"), _("View Frequently Asked Questions online")) faqItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_comments") helpMenu.AppendItem(faqItem) ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. questionItem = wx.MenuItem(helpMenu, self.ID_QUESTION, _("Ask a &Question"), _("Ask a question online")) questionItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_user_comment") helpMenu.AppendItem(questionItem) ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. bugItem = wx.MenuItem(helpMenu, self.ID_REPORTBUG, _("&Report a Bug"), _("Report a bug to the developer online")) bugItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_bug") helpMenu.AppendItem(bugItem) ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. featureItem = wx.MenuItem(helpMenu, self.ID_REQUESTFEATURE, _("Request a Fea&ture"), _("Request a new feature to be implemented")) featureItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_lightbulb") helpMenu.AppendItem(featureItem) ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. translateItem = wx.MenuItem(helpMenu, self.ID_TRANSLATE, _("Tran&slate wxBanker"), _("Translate wxBanker to another language")) translateItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_flag_blue") helpMenu.AppendItem(translateItem) helpMenu.AppendSeparator() ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. aboutItem = helpMenu.Append(wx.ID_ABOUT, _("&About"), _("More information about wxBanker")) # Add everything to the main menu. self.Append(fileMenu, _("&File")) self.Append(viewMenu, _("&View")) self.Append(settingsMenu, _("&Settings")) self.Append(helpMenu, _("&Help")) self.toggleAutoSave(autosave) self.toggleShowCurrencyNick(showcurrnick) Publisher.subscribe(self.onAutoSaveToggled, "controller.autosave_toggled") Publisher.subscribe(self.onShowZeroToggled, "controller.showzero_toggled") Publisher.subscribe(self.onShowCurrencyNickToggled, "controller.show_currency_nick_toggled") # Subscribe to a Mint update event, which tells us the checkbox should be enabled after startup. Publisher.subscribe(self.onMintUpdate, "mint.updated")
def __init__(self, parent, row, editing=None): bankcontrols.GBRow.__init__(self, parent, row, name="NewTransactionCtrl") self.CurrentAccount = editing self.isInitialAccountSet = False self.dateCtrl = bankcontrols.DateCtrlFactory(parent) self.startText = wx.StaticText(parent, label=_("Starts:")) # The Description and Amount controls. handler = self.dateCtrl.customKeyHandler self.descCtrl = bankcontrols.HintedTextCtrl(parent, size=(140, -1), style=wx.TE_PROCESS_ENTER, hint=_("Description"), icon="wxART_page_edit", handler=handler) self.amountCtrl = bankcontrols.HintedTextCtrl( parent, size=(90, -1), style=wx.TE_PROCESS_ENTER | wx.TE_RIGHT, hint=_("Amount"), icon="wxART_money_dollar", handler=handler) # The add button. self.newButton = bankcontrols.FlashableButton( parent, bitmap=wx.ArtProvider.GetBitmap('wxART_money_add')) self.newButton.SetToolTipString(_("Enter this transaction")) checkSizer = wx.BoxSizer(wx.VERTICAL) # The transfer check. self.transferCheck = wx.CheckBox(parent, label=_("Transfer")) checkSizer.Add(self.transferCheck, 0, wx.RIGHT, 6) # The recurs check. self.recursCheck = wx.CheckBox(parent, label=_("Recurring")) checkSizer.Add(self.recursCheck, 0, wx.RIGHT, 6) # Checkboxes seem to have an overly large horizontal margin that looks bad. for check in (self.transferCheck, self.recursCheck): x, y = check.BestSize check.SetMinSize((x, y - 4)) # Set up the layout. dateSizer = wx.BoxSizer() dateSizer.Add(self.startText, flag=wx.ALIGN_CENTER) dateSizer.Add( wx.StaticBitmap(parent, bitmap=wx.ArtProvider.GetBitmap('wxART_date')), 0, wx.ALIGN_CENTER | wx.RIGHT, 2) dateSizer.Add(self.dateCtrl, flag=wx.ALIGN_CENTER | wx.EXPAND) self.startText.Hide() hSizer = wx.BoxSizer() hSizer.Add(self.amountCtrl, 0, wx.ALIGN_CENTER) hSizer.AddSpacer(5) hSizer.Add(self.newButton, 0, wx.ALIGN_CENTER) hSizer.AddSpacer(5) hSizer.Add(checkSizer, 0, wx.ALIGN_CENTER) descSizer = wx.BoxSizer() descSizer.Add(self.descCtrl, 1, flag=wx.ALIGN_CENTER) self.AddNext(dateSizer) self.AddNext(descSizer, flag=wx.EXPAND) self.AddNext(hSizer) # Initialize necessary bindings. parent.Bind( wx.EVT_TEXT_ENTER, self.onNewTransaction) # Gives us enter from description/amount. self.newButton.Bind(wx.EVT_BUTTON, self.onNewTransaction) self.recursCheck.Bind(wx.EVT_CHECKBOX, self.onRecurringCheck) self.transferCheck.Bind(wx.EVT_CHECKBOX, self.onTransferCheck) try: self.amountCtrl.Children[0].Bind(wx.EVT_CHAR, self.onAmountChar) except IndexError: # On OSX for example, a SearchCtrl is native and has no Children. pass try: dateTextCtrl = self.dateCtrl.Children[0].Children[0] except IndexError: # This will fail on MSW + wxPython < 2.8.8.0, nothing we can do. pass else: # Bind to DateCtrl Enter (LP: 252454). dateTextCtrl.WindowStyleFlag |= wx.TE_PROCESS_ENTER dateTextCtrl.Bind(wx.EVT_TEXT_ENTER, self.onDateEnter) # If we are editing, it is inherently a recurring transaction. if editing: self.recursCheck.Hide() self.newButton.Hide() else: # Only subscribe to the event and set focus if it is the permanent control (LP: #623238) Publisher.subscribe(self.onAccountChanged, "view.account changed") wx.CallLater(50, self.initialFocus)
def __init__(self, parent, bankController): wx.Panel.__init__(self, parent) self.ID_TIMER = wx.NewId() self.SearchTimer = wx.Timer(self, self.ID_TIMER) self.bankController = bankController self.searchCtrl = bankcontrols.UpdatableSearchCtrl( self, value="", size=(200, -1), style=wx.TE_PROCESS_ENTER) # Try to grab the GTK system icon for clearing a search, otherwise we'll get the wxPython one. iconSize = self.searchCtrl.GetClientRect().GetHeight() - 2 clearBitmap = wx.ArtProvider.GetBitmap('edit-clear', wx.ART_OTHER, [iconSize, iconSize]) if clearBitmap: self.searchCtrl.SetCancelBitmap(clearBitmap) self.searchCtrl.ShowCancelButton(True) self.searchCtrl.ShowSearchButton(False) self.searchCtrl.DescriptiveText = _("Search transactions") self.searchCtrl.SetForegroundColour('DARK GRAY') # The More/Less button. self.moreButton = bankcontrols.MultiStateButton(self, labelDict={ True: _("More options"), False: _("Less options") }, state=True) self.matchChoices = [_("Amount"), _("Description"), _("Date")] self.descriptionSelection = 1 self.matchBox = bankcontrols.CompactableComboBox( self, value=self.matchChoices[1], choices=self.matchChoices, style=wx.CB_READONLY) topSizer = wx.BoxSizer() topSizer.Add(self.searchCtrl, 0, wx.ALIGN_CENTER_VERTICAL) topSizer.AddSpacer(10) topSizer.Add(self.moreButton, 0, wx.ALIGN_CENTER_VERTICAL) self.moreSizer = moreSizer = wx.BoxSizer() moreSizer.Add(wx.StaticText(self, label=_("Match: ")), 0, wx.ALIGN_CENTER_VERTICAL) moreSizer.Add(self.matchBox, 0, wx.ALIGN_CENTER_VERTICAL) self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.Add(topSizer, 0, wx.ALIGN_RIGHT | wx.TOP | wx.BOTTOM, 2) self.Sizer.Add(moreSizer, 0, wx.ALIGN_RIGHT | wx.BOTTOM, 2) self.matchBox.Compact() self.Layout() self.searchCtrl.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.onCancel) self.searchCtrl.Bind(wx.EVT_TEXT, self.onText) #self.searchCtrl.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.onSearch) self.searchCtrl.Bind(wx.EVT_TEXT_ENTER, self.onSearch) self.moreButton.Bind(wx.EVT_BUTTON, self.onToggleMore) # Bindings to search on settings change automatically. self.matchBox.Bind(wx.EVT_COMBOBOX, self.onSearchTrigger) self.Bind(wx.EVT_TIMER, self.onSearchTimer) Publisher.subscribe(self.onExternalSearch, "SEARCH.EXTERNAL") # Initially hide the extra search options. self.onToggleMore()
def __init__(self, parent, row, editing=None): bankcontrols.GBRow.__init__(self, parent, row, name="NewTransactionCtrl") self.CurrentAccount = editing self.isInitialAccountSet = False self.dateCtrl = bankcontrols.DateCtrlFactory(parent) self.startText = wx.StaticText(parent, label=_("Starts:")) # The Description and Amount controls. handler = self.dateCtrl.customKeyHandler self.descCtrl = bankcontrols.HintedTextCtrl(parent, size=(140, -1), style=wx.TE_PROCESS_ENTER, hint=_("Description"), icon="wxART_page_edit", handler=handler) self.amountCtrl = bankcontrols.HintedTextCtrl(parent, size=(90, -1), style=wx.TE_PROCESS_ENTER|wx.TE_RIGHT, hint=_("Amount"), icon="wxART_money_dollar", handler=handler) # The add button. self.newButton = bankcontrols.FlashableButton(parent, bitmap=wx.ArtProvider.GetBitmap('wxART_money_add')) self.newButton.SetToolTipString(_("Enter this transaction")) checkSizer = wx.BoxSizer(wx.VERTICAL) # The transfer check. self.transferCheck = wx.CheckBox(parent, label=_("Transfer")) checkSizer.Add(self.transferCheck, 0, wx.RIGHT, 6) # The recurs check. self.recursCheck = wx.CheckBox(parent, label=_("Recurring")) checkSizer.Add(self.recursCheck, 0, wx.RIGHT, 6) # Checkboxes seem to have an overly large horizontal margin that looks bad. for check in (self.transferCheck, self.recursCheck): x, y = check.BestSize check.SetMinSize((x, y-4)) # Set up the layout. dateSizer = wx.BoxSizer() dateSizer.Add(self.startText, flag=wx.ALIGN_CENTER) dateSizer.Add(wx.StaticBitmap(parent, bitmap=wx.ArtProvider.GetBitmap('wxART_date')), 0, wx.ALIGN_CENTER|wx.RIGHT, 2) dateSizer.Add(self.dateCtrl, flag=wx.ALIGN_CENTER|wx.EXPAND) self.startText.Hide() hSizer = wx.BoxSizer() hSizer.Add(self.amountCtrl, 0, wx.ALIGN_CENTER) hSizer.AddSpacer(5) hSizer.Add(self.newButton, 0, wx.ALIGN_CENTER) hSizer.AddSpacer(5) hSizer.Add(checkSizer, 0, wx.ALIGN_CENTER) descSizer = wx.BoxSizer() descSizer.Add(self.descCtrl, 1, flag=wx.ALIGN_CENTER) self.AddNext(dateSizer) self.AddNext(descSizer, flag=wx.EXPAND) self.AddNext(hSizer) # Initialize necessary bindings. parent.Bind(wx.EVT_TEXT_ENTER, self.onNewTransaction) # Gives us enter from description/amount. self.newButton.Bind(wx.EVT_BUTTON, self.onNewTransaction) self.recursCheck.Bind(wx.EVT_CHECKBOX, self.onRecurringCheck) self.transferCheck.Bind(wx.EVT_CHECKBOX, self.onTransferCheck) try: self.amountCtrl.Children[0].Bind(wx.EVT_CHAR, self.onAmountChar) except IndexError: # On OSX for example, a SearchCtrl is native and has no Children. pass try: dateTextCtrl = self.dateCtrl.Children[0].Children[0] except IndexError: # This will fail on MSW + wxPython < 2.8.8.0, nothing we can do. pass else: # Bind to DateCtrl Enter (LP: 252454). dateTextCtrl.WindowStyleFlag |= wx.TE_PROCESS_ENTER dateTextCtrl.Bind(wx.EVT_TEXT_ENTER, self.onDateEnter) # If we are editing, it is inherently a recurring transaction. if editing: self.recursCheck.Hide() self.newButton.Hide() else: # Only subscribe to the event and set focus if it is the permanent control (LP: #623238) Publisher.subscribe(self.onAccountChanged, "view.account changed") wx.CallLater(50, self.initialFocus)
def __init__(self, bankController, *args, **kwargs): wx.MenuBar.__init__(self, *args, **kwargs) self.bankController = bankController autosave = bankController.AutoSave showZero = bankController.ShowZeroBalanceAccounts showcurrnick = bankController.ShowCurrencyNick self.currencyStrings = CurrencyStrings[:] # File menu. fileMenu = wx.Menu() self.saveMenuItem = fileMenu.Append(wx.ID_SAVE) self.autoSaveMenuItem = fileMenu.AppendCheckItem(self.ID_AUTOSAVE, _("Auto-save"), _("Automatically save changes")) fileMenu.AppendSeparator() importCsvMenu = fileMenu.Append(self.ID_IMPORT_CSV, _("Import from CSV"), _("Import transactions from a CSV file")) exportCsvMenu = fileMenu.Append(self.ID_EXPORT_CSV, _("Export to CSV"), _("Export transactions to a CSV file")) fileMenu.AppendSeparator() quitItem = fileMenu.Append(wx.ID_EXIT) # View menu. viewMenu = wx.Menu() viewMenu.Append(self.ID_VIEW_PREVACCOUNT, _("Previous account")+"\tCtrl+J") viewMenu.Append(self.ID_VIEW_NEXTACCOUNT, _("Next account")+"\tCtrl+K") viewMenu.Append(self.ID_VIEW_ALLACCOUNTS, _("All accounts")+"\tCtrl+T") viewMenu.AppendSeparator() self.showZeroMenuItem = viewMenu.AppendCheckItem(self.ID_SHOWZERO, _("Show zero-balance accounts")+"\tCtrl+B", _("When disabled, accounts with a balance of $0.00 will be hidden from the list")) # Use the initial show-zero setting. self.showZeroMenuItem.Check(showZero) # Settings menu. settingsMenu = wx.Menu() ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. currencyMenu = wx.MenuItem(settingsMenu, -1, _("Base ¤cy"), _("Select currency for the 'All Accounts' balance")) currencyMenu.SetBitmap(wx.ArtProvider.GetBitmap("wxART_money")) # Add an entry for each available currency. currencies = wx.Menu() # Place the local detected one first, then the rest sorted. currencies.Append(self.IDS_CURRENCIES[0], self.currencyStrings[0]) currencies.AppendSeparator() for i, cstr in enumerate(sorted(self.currencyStrings[1:])): idIndex = self.currencyStrings.index(cstr) item = wx.MenuItem(currencies, self.IDS_CURRENCIES[idIndex], cstr) currencies.AppendItem(item) # Add an entry to request a new currency. requestCurrencyItem = wx.MenuItem(currencies, self.ID_REQUESTCURRENCY, _("Request a Currency")) requestCurrencyItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_lightning") currencies.AppendSeparator() currencies.AppendItem(requestCurrencyItem) currencyMenu.SetSubMenu(currencies) settingsMenu.AppendItem(currencyMenu) self.showCurrencyNickItem = settingsMenu.AppendCheckItem(self.ID_SHOWCURRENCYNICK, _("Show currency names"), _("Show currency names with amounts")) self.mintEnabledItem = settingsMenu.AppendCheckItem(self.ID_MINTINTEGRATION, _("Integrate with Mint.com"), _("Sync account balances with an existing Mint.com account")) # Help menu. helpMenu = wx.Menu() ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. faqItem = wx.MenuItem(helpMenu, self.ID_FAQ, _("View &FAQs"), _("View Frequently Asked Questions online")) faqItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_comments") helpMenu.AppendItem(faqItem) ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. questionItem = wx.MenuItem(helpMenu, self.ID_QUESTION, _("Ask a &Question"), _("Ask a question online")) questionItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_user_comment") helpMenu.AppendItem(questionItem) ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. bugItem = wx.MenuItem(helpMenu, self.ID_REPORTBUG, _("&Report a Bug"), _("Report a bug to the developer online")) bugItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_bug") helpMenu.AppendItem(bugItem) ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. featureItem = wx.MenuItem(helpMenu, self.ID_REQUESTFEATURE, _("Request a Fea&ture"), _("Request a new feature to be implemented")) featureItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_lightbulb") helpMenu.AppendItem(featureItem) ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. translateItem = wx.MenuItem(helpMenu, self.ID_TRANSLATE, _("Tran&slate wxBanker"), _("Translate wxBanker to another language")) translateItem.Bitmap = wx.ArtProvider.GetBitmap("wxART_flag_blue") helpMenu.AppendItem(translateItem) helpMenu.AppendSeparator() ## TRANSLATORS: Put the ampersand (&) before the letter to use as the Alt shortcut. aboutItem = helpMenu.Append(wx.ID_ABOUT, _("&About"), _("More information about wxBanker")) # Add everything to the main menu. self.Append(fileMenu, _("&File")) self.Append(viewMenu, _("&View")) self.Append(settingsMenu, _("&Settings")) self.Append(helpMenu, _("&Help")) self.Bind(wx.EVT_MENU, self.onClickAbout) helpMenu.Bind(wx.EVT_MENU, self.onClickAbout) self.toggleAutoSave(autosave) self.toggleShowCurrencyNick(showcurrnick) Publisher.subscribe(self.onAutoSaveToggled, "controller.autosave_toggled") Publisher.subscribe(self.onShowZeroToggled, "controller.showzero_toggled") Publisher.subscribe(self.onShowCurrencyNickToggled, "controller.show_currency_nick_toggled") # Subscribe to a Mint update event, which tells us the checkbox should be enabled after startup. Publisher.subscribe(self.onMintUpdate, "mint.updated")
def __init__(self, store): ORMKeyValueObject.__init__(self, store) self.Store = store self.Accounts = AccountList(self, store) self._Tags = {} # Handle Mint integration, but send the message in the main thread, otherwise, dead. if self.MintEnabled: delayedresult.startWorker(lambda result: Publisher.sendMessage("mint.updated"), Mint.LoginFromKeyring, wkwargs={"notify": False}) Publisher.subscribe(self.onGlobalCurrencyChanged, "user.global_currency_changed") Publisher.subscribe(self.onAccountCurrencyChanged, "user.account_currency_changed") Publisher.subscribe(self.onMintToggled, "user.mint.toggled") Publisher.subscribe(self.onAccountChanged, "view.account changed") Publisher.subscribe(self.onTransactionTagged, "transaction.tagged") Publisher.subscribe(self.onTransactionUntagged, "transaction.untagged")