class PhoneBook(gtk.Window): 'the contact widget holding all contacts' def __init__(self, contact = None): super(PhoneBook, self).__init__() self.set_size_request(444, 300) self.set_border_width(10) self.set_title('Contact Information') self.set_icon_from_file(ICON_PATH + '/contact.png') self.set_decorated(True) self.set_modal(True) self.set_position(gtk.WIN_POS_MOUSE) self.entry_list = [] label = gtk.Label() label.set_markup('<span font_desc="belgrano 11">Name : </span>') label.set_justify(gtk.JUSTIFY_LEFT) self.entry_list.append(gtk.Entry()) def left_strip_name(entry): entry.set_text(entry.get_text().lstrip()) self.entry_list[0].connect("changed", left_strip_name) self.entry_list[0].modify_font(pango.FontDescription('belgrano')) h_box = gtk.HBox() h_box.pack_start(label) h_box.pack_start(self.entry_list[-1]) alignment = gtk.Alignment(0.5, 0, 0, 0) alignment.add(h_box) v_box = gtk.VBox(False, 4) v_box.pack_start(alignment) self.__add_button = Button(ICON_PATH + '/add.png', 'add contact', 20, 20) self.__remove_button = Button(ICON_PATH + '/remove.png', 'remove contact', 20, 20) self.__default_button = Button(ICON_PATH + '/default.png', 'set default', 20, 20) h_box = gtk.HBox(False, 10) label = gtk.Label() label.set_markup('<span font_desc="belgrano 10" foreground="#ffffff">\ <b>Default No</b> :</span>') h_box.pack_start(label) self.entry_list.append(gtk.Entry()) self.entry_list[-1].connect("changed", self.__check_num) self.entry_list[-1].modify_font(pango.FontDescription('CrashNumberingGothic')) self.entry_list[-1].set_max_length(10) h_box.pack_start(self.entry_list[-1]) h_box.pack_start(self.__add_button) alignment = gtk.Alignment(0, 0, 0, 0) alignment.add(h_box) vbox = gtk.VBox(True, 4) vbox.pack_start(alignment) alignment = gtk.Alignment(0, 0, 0, 0) alignment.add(vbox) alignment.set_border_width(8) scroll = gtk.ScrolledWindow() scroll.set_size_request(420, 180) scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) scroll.add_with_viewport(alignment) scroll.set_border_width(8) self.__add_button.connect("clicked", self.__add_entry, vbox) self.__remove_button.connect("clicked", self.__remove_entry, vbox) self.__default_button.connect("clicked", self.__change_default) frame = gtk.Frame('Contact Numbers') frame.get_label_widget().modify_font(pango.FontDescription('belgrano')) frame.set_label_align(0.5, 0.5) frame.set_shadow_type(gtk.SHADOW_IN) self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#ffffff')) frame.get_label_widget().set_sensitive(False) frame.add(scroll) scroll.get_child().modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse( '#000000')) v_box.pack_start(frame) save = Button(ICON_PATH + '/save.png', 'Save') cancel = Button(ICON_PATH + '/cancel.png', 'Cancel') save.connect("clicked", self.__save) cancel.connect("clicked", self.__cancel) h_box = gtk.HBox(True, 8) h_box.pack_start(cancel) h_box.pack_start(save) alignment = gtk.Alignment(1, 0.5, 0, 1) alignment.add(h_box) v_box.pack_start(alignment) self.__count = 1 self.add(v_box) self.connect('destroy', gtk.main_quit) self.set_resizable(False) if contact: for text in contact[2:]: if text: self.__add_button.emit('clicked') for index in range(len(contact)): if contact[index]: self.entry_list[index].set_text(contact[index]) self.show_all() def __save(self, unused): 'saves the contact details' def show_message(msg_type, msg_format, text, button = gtk.BUTTONS_CLOSE): ''' shows warning/error messages if anything goes wrong in contact info ''' def set_flag(unused_button): ''' sets the flag to overwrite same contact name with newer details ''' self.__over_write = True return False self.__over_write = False message = gtk.MessageDialog(type = msg_type, message_format = msg_format, buttons = button) message.format_secondary_markup(text) message.set_icon_from_file(ICON_PATH + '/contact.png') if button == gtk.BUTTONS_YES_NO: message.get_child().get_children()[-1].get_children()[0].\ connect('clicked', set_flag) message.run() message.destroy() if not self.entry_list[0].get_text(): show_message(gtk.MESSAGE_ERROR, 'ERROR', '<span font_desc=\ "belgrano 12">Name can not be empty</span>') return False elif not self.entry_list[1].get_text(): show_message(gtk.MESSAGE_ERROR, 'ERROR', '<span font_desc="primitiv\ e 12"><span foreground="#3EA9DC"><b>' + self.entry_list[0].get_text() + \ '</b></span> must have a default number</span>') return False else: faulty = [] for entry in range(1, len(self.entry_list)): if len(self.entry_list[entry].get_text()) < 10: faulty.append(entry) if faulty: text = '<span font_desc="belgrano 12">The following contact(s)\ has(have) less than 10 digits :\n' for index in faulty: if index == 1: text += '<b>default</b>\n' else: text += '#<b>' + str(index) + '</b>\n' text += '</span>' show_message(gtk.MESSAGE_ERROR, 'ERROR', text) return False values = [self.entry_list[1].get_text(), self.entry_list[0].get_text()] for entry in self.entry_list[2:]: values.append(entry.get_text()) values = tuple(values) from database import DataBase database = DataBase() if database.row_count('contacts', self.entry_list[1].get_text()): show_message(gtk.MESSAGE_WARNING, 'WARNING', '<span font_desc="belgrano 12">Number <span foreground="#0000FF"><b>' + \ self.entry_list[1].get_text() + '</b></span> is already in use for <span foreground="#FF0000"><b>%s</b></span>\n\nOverwrite the \ details for <span foreground="#077E11"><b>%s</b></span> ?</span>' % (database.select('contacts', self.entry_list[1].get_text())[0][0], self.entry_list[0].get_text()), gtk.BUTTONS_YES_NO) if self.__over_write: database.update('contacts', values) database.close() self.destroy() else: database.update('contacts', values) database.close() self.destroy() def __cancel(self, unused_button): 'cancels all the informations for a contact' self.destroy() def __check_num(self, entry): 'forces the characters in the entry field to be digits only' text = entry.get_text().strip() entry.set_text(''.join([i for i in text if i in '0123456789'])) def __remove_entry(self, unused, vbox): 'removes a contact number field' self.__count -= 1 hbox = self.__remove_button.parent alignment = hbox.parent remove_list = self.__remove_button.parent.get_children() for item in remove_list: item.hide() hbox.remove(item) remove_list[0].destroy() remove_list[1].destroy() self.entry_list.pop() alignment.remove(hbox) hbox.destroy() alignment.destroy() hbox = vbox.get_children()[-1].get_children()[0] hbox.pack_start(self.__add_button) if self.__count > 1: hbox.pack_start(self.__remove_button) hbox.show_all() def __add_entry(self, unused, vbox): 'adds a new field for a new contact number' def cursor_enter(unused_entry, unused_event, hbox): 'places the default button next to the field whenever cursor enters the field' if self.__default_button.parent: self.__default_button.parent.remove(self.__default_button) hbox.pack_start(self.__default_button) self.__default_button.show() if self.__count > 1: self.__remove_button.hide() self.__remove_button.parent.remove(self.__remove_button) h_box = gtk.HBox(False, 10) self.entry_list.append(gtk.Entry()) self.entry_list[-1].connect("changed", self.__check_num) self.entry_list[-1].modify_font(pango.FontDescription('CrashNumberingGothic')) self.entry_list[-1].connect("enter-notify-event", cursor_enter, h_box) self.entry_list[-1].set_max_length(10) self.__add_button.hide() self.__add_button.parent.remove(self.__add_button) label = gtk.Label() label.set_markup('<span font_desc="belgrano 11"foreground = "#ffffff">\ Contact #%02d :</span>' % (self.__count + 1)) h_box.pack_start(label) h_box.pack_start(self.entry_list[-1]) h_box.pack_start(self.__add_button) h_box.pack_start(self.__remove_button) alignment = gtk.Alignment(0, 0, 0, 0) alignment.add(h_box) vbox.pack_start(alignment) alignment.show_all() self.__count += 1 def __change_default(self, unused): 'swaps the focused contact number with the default number' entry = self.__default_button.parent.get_children()[1] temp = entry.get_text() entry.set_text(self.entry_list[1].get_text()) self.entry_list[1].set_text(temp) return False