📄 abeditor.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.************************************************************************/#include "abeditor.h"#include "addresspicker.h"#include "emaildlgimpl.h"#include <qtopia/categories.h> // needed to get correct WIN32 exports for QValueList<int>#include <qtopia/categoryselect.h>#include <qtopia/qpeapplication.h>#include <qtopia/qpedialog.h>#include <qtopia/datetimeedit.h>#include <qcombobox.h>#include <qlabel.h>#include <qstyle.h>#include <qlayout.h>#include <qlineedit.h>#include <qmultilineedit.h>#include <qscrollview.h>#include <qtoolbutton.h>#include <qpushbutton.h>#include <qmainwindow.h>#include <qvbox.h>#include <qtabwidget.h>#include <qregexp.h>#include <qwhatsthis.h>#include <qmessagebox.h>#ifdef QTOPIA_DESKTOP#include <qtextedit.h>#endif// Make QScrollView in AutoOneFit mode use the minimum horizontal size// instead of the sizeHint() so that the widgets fit horizontally.class VScrollBox : public QWidget{public: VScrollBox( QWidget *parent, const char *name=0 ) : QWidget( parent, name ) {} QSize sizeHint() const { int width = QMIN(QWidget::sizeHint().width(), qApp->desktop()->width()-style().scrollBarExtent().width() ); width = QMAX(width, QWidget::minimumSize().width()); return QSize( width, QWidget::sizeHint().height()); }};class VScrollView : public QScrollView{public: VScrollView(QWidget *parent, const char *name = 0) : QScrollView(parent, name) { setHScrollBarMode( QScrollView::AlwaysOff ); setResizePolicy( QScrollView::AutoOneFit ); setFrameStyle( QFrame::NoFrame ); w = new VScrollBox( viewport() ); addChild(w); } QWidget *widget() { return w; }private: QWidget *w;};// helper functions, convert our comma delimited list to proper// file format...void parseEmailFrom( const QString &txt, QString &strDefaultEmail, QStringList &strAll );// helper convert from file format to comma delimited...void parseEmailTo( const QString &strDefaultEmail, const QStringList &emails, QString &strBack );class FileAsCombo : public QComboBox{ Q_OBJECTpublic: FileAsCombo( AbEditor *editor, QWidget *container ); void reload(); void generateFileAsOptions(); bool userOverride; bool programaticUpdate; bool reloading;public slots: void autoUpdate(); void userChanged( const QString &);protected:private: enum ChoiceGroup { LastFirst=0, FirstLast, Business, Other }; void addOption( int index, const QString &str, ChoiceGroup group ); AbEditor *e; QStringList options; QMap<int, QStringList::Iterator > indexedOptions; QMap<QString, int> indexLookup; int curIndex; ChoiceGroup curGroup; int curNumGroupChoices; int lastNumGroupChoices; QMap<ChoiceGroup, int> bestChoiceIndex; QMap<int, ChoiceGroup> indexedGroups;};FileAsCombo::FileAsCombo( AbEditor *editor, QWidget *parent ) : QComboBox( parent, "FileAsCombo" ), userOverride( FALSE ), programaticUpdate( FALSE ), reloading( FALSE ), e( editor ), options(), indexedOptions(), curIndex( -1 ), curGroup( LastFirst ), curNumGroupChoices(-1), lastNumGroupChoices(-1), bestChoiceIndex(){ setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed) ); setInsertionPolicy( QComboBox::AtTop ); setAutoCompletion( TRUE ); setEditable( TRUE ); setDuplicatesEnabled( FALSE ); connect( this, SIGNAL( textChanged( const QString &) ), SLOT( userChanged( const QString &) ) );}void FileAsCombo::userChanged( const QString &newText ){ if ( programaticUpdate || reloading ) return; QMap<QString,int>::Iterator found = indexLookup.find( newText ); //qDebug( "FileAsCombo::userChanged newText = %s curIndex = %d found = %d", // newText.latin1(), curIndex, *found ); if ( found == indexLookup.end() && !newText.isEmpty() ) { lineEdit()->blockSignals(TRUE); lineEdit()->setText(newText); lineEdit()->blockSignals(FALSE); userOverride = TRUE; curIndex = -1; lastNumGroupChoices = -1; } else { userOverride = FALSE; if (newText.isEmpty()) curIndex = 0; else curIndex = *found; //qDebug( " userChanged indexedGroups.contains(curIndex) == %d",// indexedGroups.contains(curIndex) ); if ( curGroup != indexedGroups[curIndex] ) { curGroup = indexedGroups[curIndex]; curNumGroupChoices = 0; for ( QMap<int, ChoiceGroup>::Iterator it = indexedGroups.begin(); it != indexedGroups.end(); ++it ) { if ( *it == curGroup ) curNumGroupChoices++; } } }//qDebug( " curIndex = %d cur group = %d curNumGroupChoices = %d", curIndex, curGroup, curNumGroupChoices );}void FileAsCombo::addOption( int index, const QString &str, ChoiceGroup group ){ QStringList::Iterator it = options.append( str ); indexedOptions.insert( index, it ); indexLookup.insert( *it, index ); indexedGroups.insert( index, group ); //qDebug("addOption %s index = %d group = %d", str.latin1(), index, group ); if ( !bestChoiceIndex.contains( group ) ) bestChoiceIndex.insert( group, index ); if ( group == curGroup ) curNumGroupChoices++;}void FileAsCombo::generateFileAsOptions(){ options.clear(); indexedOptions.clear(); bestChoiceIndex.clear(); indexedGroups.clear(); indexLookup.clear(); curNumGroupChoices = 0; QString nickName = e->lineEdits[ PimContact::Nickname ]->text(); QString firstName = e->lineEdits[ PimContact::FirstName ]->text(); QString middleName = e->lineEdits[ PimContact::MiddleName ]->text(); QString lastName = e->lineEdits[PimContact::LastName ]->text(); QString suffix = e->suffixCombo->currentText(); QString company = e->lineEdits[PimContact::Company]->text(); bool bfirstName = !firstName.isEmpty(); bool bnickName = !nickName.isEmpty(); bool bmiddleName = !middleName.isEmpty(); bool blastName = !lastName.isEmpty(); bool bsuffix = !suffix.isEmpty(); int i = 0; // last, first middle ChoiceGroup g = LastFirst; if ( bfirstName && bmiddleName && blastName ) addOption( i, lastName + ", " + firstName + " " + middleName, g ); // last, first ++i; if ( bfirstName && blastName ) addOption( i, lastName + ", " + firstName, g ); // last, first suffix ++i; if ( bfirstName && blastName && bsuffix ) addOption( i, lastName + ", " + firstName + " " + suffix, g ); // last, nick ++i; if ( bnickName && blastName ) addOption( i, lastName + ", " + nickName, g ); g = FirstLast; // first middle last suffix ++i; if ( bfirstName && bmiddleName && blastName && bsuffix ) addOption( i, firstName + " " + middleName + " " + lastName + " " + suffix, g ); // first middle last ++i; if ( bfirstName && bmiddleName && blastName ) addOption( i, firstName + " " + middleName + " " + lastName, g ); // first last ++i; if ( bfirstName && blastName ) addOption( i, firstName + " " + lastName, g ); // first last suffix ++i; if ( bfirstName && blastName && bsuffix ) addOption( i, firstName + " " + lastName + " " + suffix, g ); // nick last ++i; if ( bnickName && blastName ) addOption(i, bnickName + " " + lastName, g ); g = LastFirst; ++i; if ( bfirstName ) addOption( i, firstName, g); ++i; if ( bnickName ) addOption( i, nickName, g ); ++i; if ( blastName ) addOption( i, lastName, g ); // company g = Business; ++i; if ( !company.isEmpty() ) addOption( i, company, g ); // okay, no names so starting to get desperate if ( !options.count() ) { // let's find out what fields we have that are not empty and choose the // most unique one from our uniqueness map QString mostUnique; int mostUniqueVal = 0; for ( QMap<int, QLineEdit *>::ConstIterator lit = e->lineEdits.begin(); lit != e->lineEdits.end(); ++lit ) { if ( !(*lit)->text().isEmpty() && PimContact::uniquenessMap()[ lit.key() ] > mostUniqueVal ) { mostUnique = (*lit)->text(); mostUniqueVal = PimContact::uniquenessMap()[ lit.key() ]; } } if ( !mostUnique.isEmpty() ) { ++i; addOption( i, mostUnique, Other ); } }}void FileAsCombo::autoUpdate(){ if ( programaticUpdate && !reloading ) return; //qDebug(" userOverride = %d programaticUpdate =%d reload = %d", userOverride, programaticUpdate, reloading ); // set programaticUpdate so userChanged doesn't get called; the user // isn't changing it, we are programaticUpdate = TRUE; // remember what was selected QString curText = currentText(); lastNumGroupChoices = curNumGroupChoices; // generate a new list of options generateFileAsOptions(); // make an intelligent choice of what should be shown in the // combo box //qDebug("\t before new index; last = %d current = %d", lastNumGroupChoices, curNumGroupChoices ); if ( !userOverride ) { if (options.count()) { if ( lastNumGroupChoices != curNumGroupChoices || curIndex == -1 || !indexedOptions.contains( curIndex ) ) { if ( bestChoiceIndex.contains( curGroup ) ) curIndex = bestChoiceIndex[ curGroup ]; else curIndex = indexedOptions.begin().key(); curGroup = indexedGroups[curIndex]; //qDebug("\tpicking smart choice for index; new index = %d group = %d", curIndex, curGroup); } curText = *(indexedOptions[curIndex]); } else { curText = ""; // No options available. } //qDebug( "setting curText = %s using index = %d", curText.latin1(), curIndex); } clear(); insertStringList( options ); setEditText( curText ); programaticUpdate = FALSE;}void FileAsCombo::reload(){ // inialize the file as for the first time for editing userOverride = FALSE; curGroup = LastFirst; reloading = TRUE; curIndex = -1; lastNumGroupChoices = -1; curNumGroupChoices = -1; setEditText( "" ); autoUpdate(); reloading = FALSE; userChanged( e->ent.fileAs() ); autoUpdate();}AbEditor::AbEditor( QWidget *parent, const char *name, WFlags fl) : QDialog( parent, name, TRUE, fl ){ fileAsCombo = 0; init(); resize( 400, 500 ); setCaption( tr("Edit Contact Details") );}AbEditor::~AbEditor(){}void AbEditor::setCategory(int id){ cmbCat->setCurrentCategory( id );}void AbEditor::init(){ quitExplicitly = FALSE; // setup which fields go in which tabs and in which order; this is done first since it is // most likely to change and we can calculate the QGridLayout num rows for each tab // personal tab keys QValueList<int> personalTabKeys; personalTabKeys.append( PimContact::NameTitle ); personalTabKeys.append( PimContact::FirstName ); personalTabKeys.append( PimContact::FirstNamePronunciation ); personalTabKeys.append( PimContact::MiddleName ); personalTabKeys.append( PimContact::LastName ); personalTabKeys.append( PimContact::LastNamePronunciation ); personalTabKeys.append( PimContact::Suffix ); personalTabKeys.append( PimContact::Nickname ); personalTabKeys.append( PimContact::FileAs ); personalTabKeys.append( PimContact::Categories ); personalTabKeys.append( PimContact::Emails );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -