# -*- coding: utf-8 -*- # # (c) Copyright 2003-2015 HP Development Company, L.P. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Author: Don Welch # # Std Lib import sys import os import os.path # Local from base.g import * from base import utils from base.sixext import to_unicode from .ui_utils import load_pixmap try: from fax import fax except ImportError: # This can fail on Python < 2.3 due to the datetime module log.error("Fax address book disabled - Python 2.3+ required.") sys.exit(1) # Qt from qt import * from .faxaddrbookform_base import FaxAddrBookForm_base from .faxaddrbookeditform_base import FaxAddrBookEditForm_base from .faxaddrbookgroupsform_base import FaxAddrBookGroupsForm_base from .faxaddrbookgroupeditform_base import FaxAddrBookGroupEditForm_base # globals db = None # **************************************************************************** class AddressBookItem2(QListViewItem): def __init__(self, parent, entry): QListViewItem.__init__(self, parent) self.entry = entry self.setText(0, entry['name']) self.setText(1, entry['title']) self.setText(2, entry['firstname']) self.setText(3, entry['lastname']) self.setText(4, entry['fax']) self.setText(5, ', '.join(entry['groups'])) self.setText(6, entry['notes']) class GroupValidator(QValidator): def __init__(self, parent=None, name=None): QValidator.__init__(self, parent, name) def validate(self, input, pos): input = to_unicode(input) if input.find(',') > 0: return QValidator.Invalid, pos elif len(input) > 50: return QValidator.Invalid, pos else: return QValidator.Acceptable, pos class PhoneNumValidator(QValidator): def __init__(self, parent=None, name=None): QValidator.__init__(self, parent, name) def validate(self, input, pos): input = to_unicode(input) if not input: return QValidator.Acceptable, pos elif input[pos-1] not in '0123456789-(+) *#': return QValidator.Invalid, pos elif len(input) > 50: return QValidator.Invalid, pos else: return QValidator.Acceptable, pos # **************************************************************************** # class FaxAddrBookGroupEditForm(FaxAddrBookGroupEditForm_base): """ Called when clicking New... or Edit... from the Group Dialog """ def __init__(self,parent = None,name = None,modal = 0,fl = 0): FaxAddrBookGroupEditForm_base.__init__(self,parent,name,modal,fl) self.edit_mode = False self.okButton.setEnabled(True) self.all_groups = db.get_all_groups() self.groupnameEdit.setValidator(GroupValidator(self.groupnameEdit)) def setDlgData(self, group_name): self.edit_mode = True self.groupnameEdit.setText(group_name) self.groupnameEdit.setReadOnly(True) self.setEntries(group_name) def setEntries(self, group_name=''): self.entriesListView.clear() all_entries = db.get_all_records() for e, v in list(all_entries.items()): i = QCheckListItem(self.entriesListView, e, QCheckListItem.CheckBox) if group_name and group_name in v['groups']: i.setState(QCheckListItem.On) self.CheckOKButton() def getDlgData(self): group_name = to_unicode(self.groupnameEdit.text()) entries = [] i = self.entriesListView.firstChild() while i is not None: if i.isOn(): entries.append(to_unicode(i.text())) i = i.itemBelow() return group_name, entries def groupnameEdit_textChanged(self,a0): self.CheckOKButton() def entriesListView_clicked(self,a0): self.CheckOKButton() def CheckOKButton(self): group_name = to_unicode(self.groupnameEdit.text()) if not group_name or \ (not self.edit_mode and group_name in self.all_groups): self.okButton.setEnabled(False) return i = self.entriesListView.firstChild() while i is not None: if i.isOn(): break i = i.itemBelow() else: self.okButton.setEnabled(False) return self.okButton.setEnabled(True) def __tr(self,s,c = None): return qApp.translate("FaxAddrBookGroupEditForm",s,c) # **************************************************************************** # class FaxAddrBookGroupsForm(FaxAddrBookGroupsForm_base): def __init__(self,parent = None,name = None,modal = 0,fl = 0): FaxAddrBookGroupsForm_base.__init__(self,parent,name,modal,fl) self.current = None QTimer.singleShot(0, self.InitialUpdate) def InitialUpdate(self): self.UpdateList() def UpdateList(self): self.groupListView.clear() first_rec = None all_groups = db.get_all_groups() if all_groups: for group in all_groups: i = QListViewItem(self.groupListView, group, ', '.join(db.group_members(group))) if first_rec is None: first_rec = i self.groupListView.setCurrentItem(i) self.current = i self.editButton.setEnabled(True) self.deleteButton.setEnabled(True) else: self.editButton.setEnabled(False) self.deleteButton.setEnabled(False) def newButton_clicked(self): dlg = FaxAddrBookGroupEditForm(self) dlg.setEntries() if dlg.exec_loop() == QDialog.Accepted: group_name, entries = dlg.getDlgData() db.update_groups(group_name, entries) self.UpdateList() def editButton_clicked(self): dlg = FaxAddrBookGroupEditForm(self) group_name = to_unicode(self.current.text(0)) dlg.setDlgData(group_name) if dlg.exec_loop() == QDialog.Accepted: group_name, entries = dlg.getDlgData() db.update_groups(group_name, entries) self.UpdateList() def deleteButton_clicked(self): x = QMessageBox.critical(self, self.caption(), self.__tr("Annoying Confirmation: Are you sure you want to delete this group?"), QMessageBox.Yes, QMessageBox.No | QMessageBox.Default, QMessageBox.NoButton) if x == QMessageBox.Yes: db.delete_group(to_unicode(self.current.text(0))) self.UpdateList() def groupListView_currentChanged(self, a0): self.current = a0 def groupListView_doubleClicked(self, a0): self.editButton_clicked() def groupListView_rightButtonClicked(self, item, pos, a2): popup = QPopupMenu(self) popup.insertItem(self.__tr("New..."), self.newButton_clicked) if item is not None: popup.insertItem(self.__tr("Edit..."), self.editButton_clicked) popup.insertItem(self.__tr("Delete..."), self.deleteButton_clicked) popup.insertSeparator() popup.insertItem(self.__tr("Refresh List"), self.UpdateList) popup.popup(pos) def __tr(self,s,c = None): return qApp.translate("FaxAddrBookGroupsForm",s,c) # **************************************************************************** # class FaxAddrBookEditForm(FaxAddrBookEditForm_base): def __init__(self, editing=True, parent = None,name = None,modal = 0,fl = 0): FaxAddrBookEditForm_base.__init__(self,parent,name,modal,fl) self.editing = editing self.faxEdit.setValidator(PhoneNumValidator(self.faxEdit)) self.initial_nickname = '' self.OKButton.setEnabled(self.editing) def setDlgData(self, name, title, firstname, lastname, fax, group_list, notes): self.initial_nickname = name self.name = name self.titleEdit.setText(title) self.firstnameEdit.setText(firstname) self.lastnameEdit.setText(lastname) self.faxEdit.setText(fax) self.notesEdit.setText(notes) self.nicknameEdit.setText(name) self.setGroups(group_list) def setGroups(self, entry_groups=[]): self.groupListView.clear() for g in db.get_all_groups(): i = QCheckListItem(self.groupListView, g, QCheckListItem.CheckBox) if g in entry_groups: i.setState(QCheckListItem.On) def getDlgData(self): in_groups = [] i = self.groupListView.firstChild() while i is not None: if i.isOn(): in_groups.append(to_unicode(i.text())) i = i.itemBelow() return {'name': to_unicode(self.nicknameEdit.text()), 'title': to_unicode(self.titleEdit.text()), 'firstname': to_unicode(self.firstnameEdit.text()), 'lastname': to_unicode(self.lastnameEdit.text()), 'fax': to_unicode(self.faxEdit.text()), 'groups': in_groups, 'notes': to_unicode(self.notesEdit.text())} def firstnameEdit_textChanged(self,a0): pass def lastnameEdit_textChanged(self,a0): pass def nicknameEdit_textChanged(self, nickname): self.CheckOKButton(nickname, None) def faxEdit_textChanged(self, fax): self.CheckOKButton(None, fax) def CheckOKButton(self, nickname=None, fax=None): if nickname is None: nickname = to_unicode(self.nicknameEdit.text()) if fax is None: fax = to_unicode(self.faxEdit.text()) ok = bool(len(nickname) and len(fax)) if nickname: all_entries = db.get_all_records() for e, v in list(all_entries.items()): if nickname == e and nickname != self.initial_nickname: ok = False self.OKButton.setEnabled(ok) def __tr(self,s,c = None): return qApp.translate("FaxAddrBookEditForm",s,c) # **************************************************************************** # class FaxAddrBookForm(FaxAddrBookForm_base): def __init__(self,parent = None,name = None,modal = 0,fl = 0): FaxAddrBookForm_base.__init__(self,parent,name,modal,fl) self.setIcon(load_pixmap('hp_logo', '128x128')) global db db = fax.FaxAddressBook() self.init_problem = False QTimer.singleShot(0, self.InitialUpdate) def InitialUpdate(self): if self.init_problem: self.close() return self.UpdateList() def UpdateList(self): self.addressListView.clear() first_rec = None all_entries = db.get_all_records() log.debug("Number of records is: %d" % len(all_entries)) if all_entries: for e, v in list(all_entries.items()): if v['name'].startswith('__'): continue i = AddressBookItem2(self.addressListView, v) if first_rec is None: first_rec = i self.addressListView.setCurrentItem(i) self.current = i self.editButton.setEnabled(True) self.deleteButton.setEnabled(True) else: self.editButton.setEnabled(False) self.deleteButton.setEnabled(False) def groupButton_clicked(self): FaxAddrBookGroupsForm(self).exec_loop() self.sendUpdateEvent() self.UpdateList() def newButton_clicked(self): dlg = FaxAddrBookEditForm(False, self) dlg.setGroups() if dlg.exec_loop() == QDialog.Accepted: d = dlg.getDlgData() db.set(**d) self.sendUpdateEvent() self.UpdateList() def editButton_clicked(self): dlg = FaxAddrBookEditForm(True, self) c = self.current.entry dlg.setDlgData(c['name'], c['title'], c['firstname'], c['lastname'], c['fax'], c['groups'], c['notes']) prev_name = c['name'] if dlg.exec_loop() == QDialog.Accepted: d = dlg.getDlgData() if prev_name != d['name']: db.delete(prev_name) db.set(**d) self.sendUpdateEvent() self.UpdateList() def deleteButton_clicked(self): if QMessageBox.critical(self, self.caption(), self.__tr("Annoying Confirmation: Are you sure you want to delete this address book entry?"), QMessageBox.Yes, QMessageBox.No | QMessageBox.Default, QMessageBox.NoButton) == QMessageBox.Yes: db.delete(self.current.entry['name']) self.UpdateList() self.sendUpdateEvent() def addressListView_rightButtonClicked(self, item, pos, a2): popup = QPopupMenu(self) popup.insertItem(self.__tr("New..."), self.newButton_clicked) if item is not None: popup.insertItem(self.__tr("Edit..."), self.editButton_clicked) popup.insertItem(self.__tr("Delete..."), self.deleteButton_clicked) popup.insertSeparator() popup.insertItem(self.__tr("Refresh List"), self.UpdateList) popup.popup(pos) def addressListView_doubleClicked(self,a0): self.editButton_clicked() def addressListView_currentChanged(self,item): self.current = item def FailureUI(self, error_text): log.error(to_unicode(error_text).replace("", "").replace("", "").replace("

", " ")) QMessageBox.critical(self, self.caption(), QString(error_text), QMessageBox.Ok, QMessageBox.NoButton, QMessageBox.NoButton) def __tr(self,s,c = None): return qApp.translate("FaxAddrBookForm",s,c) def accept(self): self.sendUpdateEvent() FaxAddrBookForm_base.accept(self) def sendUpdateEvent(self): pass # TODO: def importPushButton_clicked(self): dlg = QFileDialog(user_conf.workingDirectory(), "LDIF (*.ldif *.ldi);;vCard (*.vcf)", None, None, True) dlg.setCaption("openfile") dlg.setMode(QFileDialog.ExistingFile) dlg.show() if dlg.exec_loop() == QDialog.Accepted: result = str(dlg.selectedFile()) working_directory = to_unicode(dlg.dir().absPath()) log.debug("result: %s" % result) user_conf.setWorkingDirectory(working_directory) if result: if result.endswith('.vcf'): ok, error_str = db.import_vcard(result) else: ok, error_str = db.import_ldif(result) if not ok: self.FailureUI(error_str) else: self.UpdateList()