📄 addressbook.cpp
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#define QTOPIA_INTERNAL_FD#include "abeditor.h"#include "ablabel.h"#include "abtable.h"#include "addressbook.h"#include <qtopia/qpeapplication.h>#include <qtopia/config.h>#include <qtopia/pim/contact.h>#include <qtopia/global.h>#include <qtopia/resource.h>#include <qtopia/ir.h>#include <qtopia/qpemessagebox.h>#include <qtopia/categoryselect.h>#include <qtopia/categories.h>#include <qtopia/applnk.h>#ifdef Q_WS_QWS#include <qtopia/qcopenvelope_qws.h>#endif#include <qtopia/services.h>#include <qtopia/qpemenubar.h>#include <qtopia/qpetoolbar.h>#include <qaction.h>#include <qdialog.h>#include <qdir.h>#include <qfile.h>#include <qimage.h>#include <qlayout.h>#include <qmessagebox.h>#include <qpixmap.h>#include <qpopupmenu.h>#include <qstringlist.h>#include <qtoolbutton.h>#include <qwhatsthis.h>#include <qvbox.h>#include <qlineedit.h>#include <qwhatsthis.h>#include <stdlib.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#ifndef Q_OS_WIN32# include <unistd.h>#endif#include <qdatetime.h>static bool constructorDone = FALSE;AbSettings::AbSettings(QWidget *parent, const char *name, bool modal, WFlags fl) : QDialog(parent, name, modal, fl){ setCaption(tr("Configure columns to display")); QGridLayout *grid = new QGridLayout(this); map = new FieldMap(this); grid->addWidget(map, 0, 0);}void AbSettings::setCurrentFields(const QValueList<int> &f){ QMap<int,QString> m = PimContact::trFieldsMap(); m.remove( PimRecord::Categories ); m.remove( PimContact::LastNamePronunciation ); m.remove( PimContact::FirstNamePronunciation ); m.remove( PimContact::CompanyPronunciation ); m.insert( AbTable::FREQ_CONTACT_FIELD, tr("Contact") ); map->setFields( m, f);}AddressbookWindow::AddressbookWindow( QWidget *parent, const char *name, WFlags f ) : QMainWindow( parent, name, f ), contacts( ContactIO::ReadWrite ), abEditor(0), mView(0), searchBar(0), bAbEditFirstTime(TRUE), syncing(FALSE), showingPersonal(FALSE){ setCaption( tr("Contacts") ); setIcon( Resource::loadPixmap( "AddressBook" ) ); setToolBarsMovable( FALSE ); setBackgroundMode( PaletteButton ); // Create Toolbars QPEToolBar *bar = new QPEToolBar( this ); bar->setHorizontalStretchable( TRUE ); QPEMenuBar *mbList = new QPEMenuBar( bar ); mbList->setMargin( 0 ); QPopupMenu *edit = new QPopupMenu( this ); mbList->insertItem( tr( "Contact" ), edit ); listTools = new QPEToolBar( this ); QAction *a = new QAction( tr( "New" ), Resource::loadIconSet( "new" ), QString::null, 0, this, 0 ); actionNew = a; connect( a, SIGNAL( activated() ), this, SLOT( slotListNew() ) ); a->setWhatsThis( tr("Enter a new contact.") ); a->addTo( edit ); a->addTo( listTools ); a = new QAction( tr( "Edit" ), Resource::loadIconSet( "edit" ), QString::null, 0, this, 0 ); actionEdit = a; a->setWhatsThis( tr("Edit the highlighted contact.") ); connect( a, SIGNAL( activated() ), this, SLOT( slotViewEdit() ) ); a->setEnabled(FALSE); a->addTo( edit ); a->addTo( listTools ); a = new QAction( tr( "Duplicate" ), Resource::loadIconSet( "copy" ), QString::null, 0, this, 0 ); actionDuplicate = a; a->setWhatsThis( tr("Duplicate the highlighted contact.") ); connect( a, SIGNAL( activated() ), this, SLOT( slotViewDuplicate() ) ); a->setEnabled(FALSE); a->addTo( edit ); a = new QAction( tr( "Delete" ), Resource::loadIconSet( "trash" ), QString::null, 0, this, 0 ); actionTrash = a; a->setWhatsThis( tr("Delete the selected contacts.") ); connect( a, SIGNAL( activated() ), this, SLOT( slotListDelete() ) ); a->setEnabled(FALSE); a->addTo( edit ); a->addTo( listTools ); a = new QAction( tr( "Find" ), Resource::loadIconSet( "find" ), QString::null, 0, this, 0 ); actionFind = a; a->setWhatsThis( tr("Find a contact.") ); a->setToggleAction( TRUE ); connect( a, SIGNAL(toggled(bool)), this, SLOT(slotFind(bool)) ); a->addTo( edit ); a->addTo( listTools ); a = new QAction( tr( "Write Mail To" ), Resource::loadIconSet( "qtmail/reply" ), QString::null, 0, this, 0 ); a->setEnabled( FALSE ); a->setWhatsThis( tr("Write an email to this contact.") ); actionMail = a; connect( a, SIGNAL( activated() ), this, SLOT( writeMail() ) ); a->addTo( edit ); if ( Ir::supported() ) { a = new QAction( tr ("Beam Entry" ), Resource::loadIconSet( "beam" ), QString::null, 0, this, 0 ); actionBeam = a; connect( a, SIGNAL( activated() ), this, SLOT( slotBeam() ) ); a->setWhatsThis( tr("Beam the selected contacts to another device.") ); a->addTo( edit ); }else actionBeam = 0L; edit->insertSeparator(); a = new QAction( tr("Show Business Card"), QString::null, 0, 0, 0, FALSE ); actionPersonal = a; a->setWhatsThis( tr("Show your business card entry.") ); connect( a, SIGNAL( activated() ), this, SLOT( slotPersonalView() ) ); a->addTo( edit ); a = new QAction( tr("Set as Business Card"), QString::null, 0, 0, 0, FALSE ); actionSetPersonal = a; a->setWhatsThis( tr("Set current entry as your business card.") ); connect( a, SIGNAL( activated() ), this, SLOT( markCurrentAsPersonal() ) ); a->addTo( edit ); listTools->addSeparator(); // View menu viewmenu = new QPopupMenu( this ); mbList->insertItem( tr( "View" ), viewmenu ); a = new QAction( tr( "Contact List" ), Resource::loadIconSet( "list" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( slotListView() ) ); a->setWhatsThis( tr("View list of Contacts.") ); a->setToggleAction( TRUE ); a->setOn(TRUE); a->addTo( listTools ); a->addTo( viewmenu ); actionList = a; a = new QAction( tr( "Contact Details" ), Resource::loadIconSet( "details" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( slotDetailView() ) ); a->setWhatsThis( tr("View Contact details.") ); a->setToggleAction( TRUE ); a->addTo( listTools ); a->addTo( viewmenu ); actionDetails = a; viewmenu->insertSeparator(); viewmenu->insertItem( tr("Select All"), this, SLOT( selectAll() ) ); viewmenu->insertSeparator(); viewmenu->insertItem( tr("Configure headers"), this, SLOT(configure()) ); // Create Views listView = new QVBox( this ); abList = new AbTable( &contacts, listView ); // can create this item now viewmenu->insertItem( tr("Fit to width"), abList, SLOT(fitHeadersToWidth()) ); abList->setSelectionMode( AbTable::Extended );// abList->setFrameStyle( QFrame::NoFrame ); connect( abList, SIGNAL( clicked() ), this, SLOT( slotDetailView() ) ); connect( abList, SIGNAL(currentChanged(int,int)), this, SLOT(updateIcons()) ); connect( abList, SIGNAL(findWrapAround()), this, SLOT(findWrapped()) ); connect( abList, SIGNAL(findNotFound()), this, SLOT(findNotFound()) ); connect( abList, SIGNAL(findFound()), this, SLOT(findFound()) ); QWhatsThis::add( abList, tr("List of contacts in the selected category. Click to view detailed information.") ); // Filter bar QHBox *hb = new QHBox( listView ); QComboBox *contactCombo = new QComboBox( hb ); connect( contactCombo, SIGNAL(activated(int)), this, SLOT(contactFilterSelected(int)) ); contactCombo->insertItem( PimContact::trFieldsMap()[PimContact::BusinessMobile] ); contactMap[0]=PimContact::BusinessMobile; contactCombo->insertItem( PimContact::trFieldsMap()[PimContact::HomeMobile] ); contactMap[1]=PimContact::HomeMobile; contactCombo->insertItem( PimContact::trFieldsMap()[PimContact::BusinessPhone] ); contactMap[2]=PimContact::BusinessPhone; contactCombo->insertItem( PimContact::trFieldsMap()[PimContact::HomePhone] ); contactMap[3]=PimContact::HomePhone; contactCombo->insertItem( PimContact::trFieldsMap()[PimContact::DefaultEmail] ); contactMap[4]=PimContact::DefaultEmail; contactCombo->setSizePolicy( QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred) ); contactCombo->setCurrentItem(0); contactFilterSelected( 0 ); QWhatsThis::add( contactCombo, tr("Show this contact information in the Contact column, if available.") ); cats.load(categoryFileName()); catSelect = new CategorySelect( hb ); catSelect->setRemoveCategoryEdit( TRUE ); connect( catSelect, SIGNAL(signalSelected(int)), this, SLOT(slotSetCategory(int)) ); QWhatsThis::add( catSelect, tr("Show contacts in this category.") ); QArray<int> vl( 0 ); catSelect->setCategories( vl, "Address Book", // No tr() tr("Address Book") ); catSelect->setAllCategories( TRUE ); readConfig(); setCentralWidget( listView );// slotSetCategory(-2); contacts.setFilter( catSelect->currentCategory() ); abList->reload(); setCaption( tr("Contacts") + " - " + categoryLabel( catSelect->currentCategory() ) ); constructorDone = TRUE; updateIcons(); connect(qApp, SIGNAL(categoriesChanged()), this, SLOT(catChanged()) ); // This call is to ensure that all records contains only valid categories catChanged(); connect( qApp, SIGNAL(appMessage(const QCString &, const QByteArray &)), this, SLOT(appMessage(const QCString &, const QByteArray &)) ); connect( qApp, SIGNAL(reload()), this, SLOT(reload()) ); connect( qApp, SIGNAL(flush()), this, SLOT(flush()) );}void AddressbookWindow::setDocument( const QString &filename ){ receiveFile(filename);}void AddressbookWindow::receiveFile( const QString &filename ){ QString targetFile = filename; if ( filename.right(8) == ".desktop" ) { DocLnk lnk(filename); if ( !lnk.isValid() || lnk.type().lower() != "text/x-vcard" ) return; targetFile = lnk.file(); } else if ( targetFile.right(4) != ".vcf" ) { return; } QWidget *mbParent = isVisible() ? this : 0; QValueList<PimContact> cl = PimContact::readVCard( targetFile ); if ( cl.count() == 0 ) { QMessageBox::warning(mbParent, tr("Could not read VCard document"), tr("The VCard document did not \ncontain any valid VCards") ); return; } QValueList<PimContact> newContacts, oldContacts; for( QValueList<PimContact>::Iterator it = cl.begin(); it != cl.end(); ++it ) { if ( contacts.contains(*it) ) { oldContacts.append( (*it) ); } else newContacts.append( (*it) ); } if ( newContacts.count() > 0 ) { QString list = ""; uint count = 0; for ( QValueList<PimContact>::Iterator it = newContacts.begin(); it != newContacts.end(); ++it) { if ( count < 3 ) { list += (*it).fullName() + "\n"; } else if ( count == 3 ) { list += "...\n"; } count++; } QString msg = tr("%1 new VCard(s) for \n%2\nDo you want to add them to\nyour addressbook?").arg( newContacts.count() ).arg(list); if ( QMessageBox::information(mbParent, tr("New contact(s)"), msg, QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok ) { for ( QValueList<PimContact>::Iterator it = newContacts.begin(); it != newContacts.end(); ++it) { contacts.addContact( *it ); } abList->reload(); } } else if ( oldContacts.count() > 0 ) { QString list = ""; uint count = 0; for ( QValueList<PimContact>::Iterator it = oldContacts.begin(); it != oldContacts.end(); ++it) { if ( count < 3 ) { list += (*it).fullName() + "\n"; } else if ( count == 3 ) { list += "...\n"; } count++; } QString msg = tr("%1 old VCard(s) for \n%2\nThe document only contained \nVCards already in your addressbook").arg( oldContacts.count() ).arg(list); QMessageBox::information(mbParent, tr("Contact(s) already registered"), msg, QMessageBox::Ok); }}void AddressbookWindow::flush(){ syncing = TRUE; contacts.saveData();}void AddressbookWindow::reload(){ syncing = FALSE; QArray<int> vl( 0 ); catSelect->setCategories( vl, "Address Book", // No tr() tr("Address Book") ); catSelect->setAllCategories( TRUE ); contacts.ensureDataCurrent(TRUE); abList->reload(); if ( centralWidget() == mView ) slotDetailView(); updateIcons();}void AddressbookWindow::resizeEvent( QResizeEvent *e ){ QMainWindow::resizeEvent( e ); // we receive a resize event from qtable in the middle of the constrution, since // QTable::columnwidth does qApp->processEvents. Ignore this event as it causes // all sorts of init problems for us if ( !constructorDone ) return; if ( centralWidget() == listView ) slotListView(); else if ( centralWidget() == mView ) showView();}AddressbookWindow::~AddressbookWindow(){ writeConfig(); delete abEditor;}voidAddressbookWindow::readConfig(void){ Config config("Contacts"); config.setGroup("default"); catSelect->setCurrentCategory(config.readNumEntry("Category", -2));}voidAddressbookWindow::writeConfig(void){ Config config("Contacts"); config.setGroup("default"); config.writeEntry("Category", catSelect->currentCategory());}void AddressbookWindow::updateIcons(){ if ( abList->hasCurrentEntry() ) { PimContact ce = abList->currentEntry(); actionNew->setEnabled(TRUE); actionEdit->setEnabled(TRUE); actionDuplicate->setEnabled(TRUE); actionTrash->setEnabled(TRUE); actionFind->setEnabled(TRUE); actionMail->setEnabled(!ce.defaultEmail().isEmpty()); if ( abList->selectedContacts().count() == 1 ) { actionSetPersonal->setEnabled(TRUE); actionDetails->setEnabled(TRUE); } else { actionSetPersonal->setEnabled(FALSE); actionDetails->setEnabled(FALSE); } if (actionBeam) { actionBeam->setEnabled(TRUE); } } else { actionNew->setEnabled(TRUE); actionEdit->setEnabled(FALSE); actionDuplicate->setEnabled(FALSE); actionTrash->setEnabled(FALSE); // If find is open, need to close it first. if (actionFind->isOn()) actionFind->setOn(FALSE); actionFind->setEnabled(FALSE); actionMail->setEnabled(FALSE); actionSetPersonal->setEnabled(FALSE); actionDetails->setEnabled(FALSE); if (actionBeam) { actionBeam->setEnabled(FALSE); } } actionPersonal->setEnabled( contacts.hasPersonal() );}void AddressbookWindow::setViewOptions(bool enabled){ int id; int i = 0; for (i = 2; (id = viewmenu->idAt(i)) != -1; i++) { viewmenu->setItemEnabled(id, enabled); }}void AddressbookWindow::showView(){ listView->hide(); setCentralWidget( abView() ); mView->show(); mView->setFocus(); updateIcons(); setCaption( tr("Contact Details") ); actionList->setOn( FALSE ); actionDetails->setOn( TRUE ); setViewOptions(FALSE);}bool AddressbookWindow::checkSyncing(){ if (syncing) { if ( QMessageBox::warning(this, tr("Contacts"), tr("Can not edit data, currently syncing"), QMessageBox::Ok, QMessageBox::Abort ) == QMessageBox::Abort ) { // Okay, if you say so (eg. Qtopia Desktop may have crashed).... syncing = FALSE; } else return TRUE; } return FALSE;}void AddressbookWindow::slotListNew(){ PimContact cnt; QArray<int> cats(1); cats[0] = catSelect->currentCategory(); cnt.setCategories( cats ); if( !checkSyncing() ) { if ( abEditor ) abEditor->setEntry( cnt ); abView()->init( cnt ); editEntry( NewEntry ); }}void AddressbookWindow::slotDetailView(){ if ( abList->hasCurrentEntry() ) { if (actionFind->isOn()) actionFind->setOn(FALSE); abView()->init( abList->currentEntry() ); mView->sync(); showView(); }}void AddressbookWindow::slotListView(){ actionList->setOn( TRUE ); actionDetails->setOn( FALSE ); if ( !abList->isVisible() ) { abView()->hide(); setCentralWidget( listView ); listView->show(); abList->setFocus();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -