예제 #1
0
class GUI(wx.Frame):
    title = "Jello Puddin' Pals"
    def __init__(self):
        wx.Frame.__init__(self, None, -1, self.title, wx.Point(30,30))
        self.addressBook = AddressBook()
        self.saveName = ""
        self.create_menu()
        self.create_main_panel()
        self.validation = Validator()


    def create_menu(self):
        ##### Menu Bar
        self.Bind(wx.EVT_CLOSE, self.on_exit, self)
        self.menubar = wx.MenuBar()

        menu_file = wx.Menu()
        m_open = menu_file.Append(-1, "&New", "New Address Book")
        self.Bind(wx.EVT_MENU, self.on_new, m_open)
        m_open = menu_file.Append(-1, "&Open", "Open Address Book")
        self.Bind(wx.EVT_MENU, self.on_open, m_open)
        m_save = menu_file.Append(-1, "&Save", "Save Address Book")
        self.Bind(wx.EVT_MENU, self.on_save, m_save)
        m_save_as = menu_file.Append(-1, "&Save as...", "Save Address Book as...")
        self.Bind(wx.EVT_MENU, self.on_save_as, m_save_as)
        m_import = menu_file.Append(-1, "&Import", "Import Address Book")
        self.Bind(wx.EVT_MENU, self.on_import, m_import)
        m_export = menu_file.Append(-1, "&Export", "Export Address Book")
        self.Bind(wx.EVT_MENU, self.on_export, m_export)
        m_exit = menu_file.Append(-1, "&Exit", "Exit Program")
        self.Bind(wx.EVT_MENU, self.on_exit, m_exit)

        menu_contact = wx.Menu()
        m_add = menu_contact.Append(-1, "&Add New Contact", "Add New Contact to Address Book")
        self.Bind(wx.EVT_MENU, self.on_add, m_add)
        m_edit = menu_contact.Append(-1, "&Edit Selected", "Edit Selected Contact")
        self.Bind(wx.EVT_MENU, self.on_edit, m_edit)
        m_remove = menu_contact.Append(-1, "&Remove Selected", "Remove Selected Contact from Address Book")
        self.Bind(wx.EVT_MENU, self.on_remove, m_remove)
        m_print = menu_contact.Append(-1, "Get Mailing Label", "Get Mailing Label for Selected Contact")
        self.Bind(wx.EVT_MENU, self.on_print, m_print)

        menu_help = wx.Menu()
        m_about = menu_help.Append(-1, "&About", "About this application")
        self.Bind(wx.EVT_MENU, self.on_about, m_about)
        self.menubar.Append(menu_file, "&File")
        self.menubar.Append(menu_contact, "&Contact")
        self.menubar.Append(menu_help, "&Help")
        self.SetMenuBar(self.menubar)
        self.statusbar = self.CreateStatusBar()


    def create_main_panel(self):
        self.panel = wx.Panel(self)

        ##### List of Contacts
        self.list = wx.ListCtrl(self.panel, -1, size=wx.Size(775,500), style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
        self.list.InsertColumn(0, 'Name', width=150)
        self.list.InsertColumn(1, 'Phone', width=125)
        self.list.InsertColumn(2, 'Address', width=150)
        self.list.InsertColumn(3, 'Address, cont.', width=100)
        self.list.InsertColumn(4, 'City', width=125)
        self.list.InsertColumn(5, 'State', width=50)
        self.list.InsertColumn(6, 'Zip', width=75)
        self.display()

        ##### User Controls
        self.addButton = wx.Button(self.panel, -1, "+ Add", size=wx.Size(80,20))
        self.Bind(wx.EVT_BUTTON, self.on_add, self.addButton)
        self.removeButton = wx.Button(self.panel, -1, "- Remove", size=wx.Size(80,20))
        self.Bind(wx.EVT_BUTTON, self.on_remove, self.removeButton)
        self.editButton = wx.Button(self.panel, -1, "Edit", size=wx.Size(80,20))
        self.Bind(wx.EVT_BUTTON, self.on_edit, self.editButton)
        self.printButton = wx.Button(self.panel, -1, "Mail Label", size=wx.Size(80,20))
        self.Bind(wx.EVT_BUTTON, self.on_print, self.printButton)
        self.sortName = wx.Button(self.panel, -1, u"Sort by Name \u25B2", size=wx.Size(120,20))
        self.Bind(wx.EVT_BUTTON, self.on_sort_name, self.sortName)
        self.sortZip = wx.Button(self.panel, -1, u"Sort by Zip", size=wx.Size(120,20))
        self.Bind(wx.EVT_BUTTON, self.on_sort_zip, self.sortZip)

        ##### Layout
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.hbox = wx.BoxSizer(wx.HORIZONTAL)
        flags = wx.ALIGN_LEFT | wx.ALL | wx.ALIGN_CENTER_VERTICAL
        self.hbox.Add(self.addButton, 0, border=5, flag=flags)
        self.hbox.Add(self.editButton, 0, border=5, flag=flags)
        self.hbox.Add(self.removeButton, 0, border=5, flag=flags)
        self.hbox.Add(self.printButton, 0, border=5, flag=flags)
        self.hbox.AddStretchSpacer()
        self.hbox.Add(self.sortName, 0, border=5, flag=wx.ALIGN_RIGHT | wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        self.hbox.Add(self.sortZip, 0, border=5, flag=wx.ALIGN_RIGHT | wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        self.vbox.Add(self.hbox, 0, flag = wx.ALIGN_LEFT | wx.TOP | wx.EXPAND)
        self.vbox.Add(self.list, 1, border=5, flag = wx.ALL | wx.GROW)
        self.panel.SetSizer(self.vbox)
        self.vbox.Fit(self)


    ##### Functionality
    def display(self):
        self.list.DeleteAllItems()
        for contact in self.addressBook.contacts:
            self.show_contact(contact)
        if self.saveName != "":
            file = self.saveName.split('/')
            self.SetTitle("Jello Puddin' Pals - {}".format(file[len(file)-1]))


    def show_contact(self, contact):
        index = self.list.InsertStringItem(sys.maxint, contact.getAttr('name'))
        self.list.SetStringItem(index, 1, contact.getAttr('phone'))
        self.list.SetStringItem(index, 2, contact.getAttr('address'))
        self.list.SetStringItem(index, 3, contact.getAttr('address2'))
        self.list.SetStringItem(index, 4, contact.getAttr('city'))
        self.list.SetStringItem(index, 5, contact.getAttr('state'))
        self.list.SetStringItem(index, 6, contact.getAttr('zipcode'))


    def on_add(self, event):
        cb = ContactBox(self, "add")
        cb.Show()


    def on_edit(self, event):
        if len(self.addressBook.contacts)>0:
            i = self.list.GetFirstSelected()
            name = self.addressBook.contacts[i].getAttr('name')
            phone = self.addressBook.contacts[i].getAttr('phone')
            address = self.addressBook.contacts[i].getAttr('address')
            address2 = self.addressBook.contacts[i].getAttr('address2')
            city = self.addressBook.contacts[i].getAttr('city')
            state = self.addressBook.contacts[i].getAttr('state')
            zipcode = self.addressBook.contacts[i].getAttr('zipcode')
            cb = ContactBox(self, "edit", name, phone, address, address2, city, state, zipcode, index=i)
            cb.Show()
        else:
            self.flash_status_message("Address book is empty")


    def on_remove(self, event):
        if len(self.addressBook.contacts)>0:
            i = self.list.GetFirstSelected()
            name = self.addressBook.contacts[i].getAttr('name')
            dlg = wx.MessageDialog(self, "Are you sure you want to remove {}?".format(name), "Confirm Delete", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
            result = dlg.ShowModal()
            dlg.Destroy()
            if result == wx.ID_OK:
                del self.addressBook.contacts[i]
                self.addressBook.sort(self.addressBook.sortMethod[0],self.addressBook.sortMethod[1])
                self.display()
                self.addressBook.changed = True
                self.flash_status_message("Removed {}".format(name))
        else:
            self.flash_status_message("Address book is empty")


    def on_sort_name(self, event):
        if self.addressBook.sortMethod == ('name', False):
            self.addressBook.sortMethod = ('name',True)
            self.addressBook.sort('name',True)
            self.sortName.SetLabel(u"Sort by Name \u25BC")
            self.sortZip.SetLabel(u"Sort by Zip")
            self.flash_status_message("Sorted address book by last name, Z-A")
        else:
            self.addressBook.sortMethod = ('name',False)
            self.addressBook.sort('name',False)
            self.sortName.SetLabel(u"Sort by Name \u25B2")
            self.sortZip.SetLabel(u"Sort by Zip")
            self.flash_status_message("Sorted address book by last name, A-Z")
        self.display()


    def on_sort_zip(self, event):
        if self.addressBook.sortMethod == ('zipcode', False):
            self.addressBook.sortMethod = ('zipcode',True)
            self.addressBook.sort('zipcode',True)
            self.sortZip.SetLabel(u"Sort by Zip \u25BC")
            self.sortName.SetLabel(u"Sort by Name")
            self.flash_status_message("Sorted address book by zip code, 9-0")
        else:
            self.addressBook.sortMethod = ('zipcode',False)
            self.addressBook.sort('zipcode',False)
            self.sortZip.SetLabel(u"Sort by Zip \u25B2")
            self.sortName.SetLabel(u"Sort by Name")
            self.flash_status_message("Sorted address book by zip code, 0-9")
        self.display()


    ##### Menu functions
    def on_new(self, event):
        if self.addressBook.changed:
            if wx.MessageBox("This address book contains unsaved changes! Continue anyway?", "Are you sure?", wx.ICON_QUESTION | wx.YES_NO, self) == wx.NO:
                return
        newGui = GUI()
        newGui.display()
        newGui.Show()
        self.Destroy()


    def on_open(self, event):
        if self.addressBook.changed:
            if wx.MessageBox("This address book contains unsaved changes! Continue anyway?", "Are you sure?", wx.ICON_QUESTION | wx.YES_NO, self) == wx.NO:
                return
        openFileDialog = wx.FileDialog(self, "Open .tsv file", "", "", ".tsv files (*.tsv)|*.tsv", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        if openFileDialog.ShowModal() == wx.ID_CANCEL:
            return
        inFilePath = openFileDialog.GetPath()
        if self.validation.isValidUSPS(inFilePath):
            newGui = GUI()
            newGui.addressBook.loadTSV(inFilePath)
            newGui.saveName = inFilePath
            newGui.addressBook.sort('name',False)
            newGui.display()
            newGui.Show()
            newGui.flash_status_message("Opened address book {}".format(newGui.saveName))
            self.Destroy()
        else:
            dlg = wx.MessageDialog(self, "Unable to open {}".format(inFilePath.split('/')[len(inFilePath.split('/'))-1]), "Invalid File", wx.OK)
            dlg.ShowModal()
            dlg.Destroy()


    def on_save_as(self, mode):
        defaultName = ""
        if mode != 1:
            default = self.saveName.split('/')
            if len(default) > 0:
                defaultName = default[len(default)-1]
        saveFileDialog = wx.FileDialog(self, "Save .tsv file", "", defaultName, ".tsv files (*.tsv)|*.tsv", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if saveFileDialog.ShowModal() == wx.ID_CANCEL:
            return
        self.saveName = saveFileDialog.GetPath()
        self.addressBook.writeTSV(self.saveName)
        if (mode != 2):
            self.display()
            self.addressBook.changed = False
        self.flash_status_message("Saved address book as {}".format(self.saveName))


    def on_import(self, event):
        openFileDialog = wx.FileDialog(self, "Import .tsv file", "", "", ".tsv files (*.tsv)|*.tsv", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        if openFileDialog.ShowModal() == wx.ID_CANCEL:
            return
        inFilePath = openFileDialog.GetPath()
        if self.validation.isValidUSPS(inFilePath):
            temp = AddressBook()
            temp.loadTSV(inFilePath)
            for contact in temp.contacts:
                self.addressBook.contacts.append(contact)
            self.addressBook.sort(self.addressBook.sortMethod[0],self.addressBook.sortMethod[1])
            self.display()
            self.flash_status_message("Imported address book {}".format(inFilePath))
            self.addressBook.changed = True
        else:
            dlg = wx.MessageDialog(self, "Unable to import {}".format(inFilePath.split('/')[len(inFilePath.split('/'))-1]), "Invalid File", wx.OK)
            dlg.ShowModal()
            dlg.Destroy()


    def on_export(self, event):
        self.on_save_as(mode=2)


    def on_save(self, event):
        if self.saveName == "":
            self.on_save_as(mode=0)
        else:
            self.addressBook.writeTSV(self.saveName)
            self.addressBook.changed = False
            self.flash_status_message("Saved address book {}".format(self.saveName))


    def on_print(self, event):
        if len(self.addressBook.contacts)>0:
            i = self.list.GetFirstSelected()
            mail = self.addressBook.contacts[i].getLabel()
            dlg = MessageBox(self, mail)
            dlg.ShowModal()
            dlg.Destroy()
        else:
            self.flash_status_message("Address book is empty")


    def on_exit(self, event):
        if self.addressBook.changed:
            if wx.MessageBox("This address book contains unsaved changes! Exit anyway?", "Are you sure?", wx.ICON_QUESTION | wx.YES_NO, self) == wx.NO:
                return
        self.Destroy()


    def on_about(self, event):
        msg = "Bill Cosby's Eligible Bachelors of Science"
        dlg = wx.MessageDialog(self, msg, "About", wx.OK)
        dlg.ShowModal()
        dlg.Destroy()


    def flash_status_message(self, msg, flash_len_ms=3000):
        self.statusbar.SetStatusText(msg)
        self.timeroff = wx.Timer(self)
        self.Bind(
            wx.EVT_TIMER,
            self.on_flash_status_off,
            self.timeroff)
        self.timeroff.Start(flash_len_ms, oneShot=True)
    def on_flash_status_off(self, event):
        self.statusbar.SetStatusText('')
예제 #2
0
 def testNonTSV(self):
     v = Validator()
     filein = 'testTSV/test.csv'
     self.assertFalse(v.isValidUSPS(filein))
예제 #3
0
 def testGoodTSV(self):
     v = Validator()
     filein = 'testTSV/twoWord.tsv'
     self.assertTrue(v.isValidUSPS(filein))
예제 #4
0
 def  testDNETSV(self):
     v = Validator()
     """tests if v rejects files that don't exist"""
     filein = 'blah.tsv'
     self.assertFalse(v.isValidUSPS(filein))