📄 abtable.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_CONTACT_MRE#include <qtopia/categoryselect.h>#include <qtopia/config.h>#include <qtopia/stringutil.h>#include <qtopia/timestring.h>#ifdef QWS#include <qtopia/qcopenvelope_qws.h>#endif#ifdef QTOPIA_DESKTOP#include <qsettings.h>#endif#include <qasciidict.h>#include <qpainter.h>#include <qregexp.h>#include <qdatetime.h>#include <qfile.h>#include <qapplication.h>#include <qstyle.h>#include <qtimer.h>#include "abtable.h"#include <errno.h>#include <fcntl.h>#ifndef Q_OS_WIN32 #include <unistd.h>#endif#include <stdlib.h>#include <ctype.h> //toupper() for key hackstatic int RowHeight = 18;const int AbTable::FREQ_CONTACT_FIELD = PimContact::ContactFieldsEnd;static Qt::ButtonState bState = Qt::NoButton;static int selectionBeginRow = -1;static bool constructorDone = FALSE;static QString applicationPath;/*! \class AbTable abtable.h \brief The AbTable class is a QTable for showing a list of entries.*/AbTable::AbTable(ContactXmlIO *c, QWidget *parent, const char *name, const char *appPath ) : QTable( 0, 0, parent, name ), currFindRow( -2 ), showCat(-2), prefField(PimContact::DefaultEmail){ applicationPath = appPath; QFont f = font(); QFontMetrics fm(f); RowHeight = QMAX(18, fm.height() + 2); contacts = c; mSel = NoSelection; QTable::setSelectionMode( QTable::NoSelection ); setLeftMargin( 0 );#ifndef QTOPIA_DESKTOP setFrameStyle( NoFrame );#endif verticalHeader()->hide(); setSorting( TRUE ); connect( this, SIGNAL(clicked(int,int,int,const QPoint &)), this, SLOT(itemClicked(int,int)) ); connect( this, SIGNAL( doubleClicked( int, int, int, const QPoint & ) ), this, SLOT( slotDoubleClicked( int, int, int, const QPoint & ) ) ); connect( this, SIGNAL( currentChanged( int, int ) ), this, SLOT( slotCurrentChanged( int, int ) ) ); mAscending = FALSE; mSortColumn = -1;#ifdef QTOPIA_DESKTOP readSettings();#else QTimer::singleShot(0, this, SLOT(readSettings()) );#endif}AbTable::~AbTable(){ saveSettings();}void AbTable::setSelectionMode(SelectionMode m){ if ( m == NoSelection && mSel != m ) { mSelected.clear(); refresh(); } mSel = m;}// We clear the selection and loop through all the rows since currentChanged// will skip some rows if you move the pointing device fast enoughvoid AbTable::setSelection(int fromRow, int toRow){ // fromLow must be lower if ( toRow < fromRow ) { int t = toRow; toRow = fromRow; fromRow = t; } int row = fromRow; mSelected.clear(); while ( row <= toRow ) { mSelected.append( contacts->sortedContacts().at(row)->uid() ); row++; }}void AbTable::paintCell( QPainter *p, int row, int col, const QRect &cr, bool ){ if ( !constructorDone ) return;#if defined(Q_WS_WIN) const QColorGroup &cg = ( style().styleHint( QStyle::SH_ItemView_ChangeHighlightOnFocus ) ? palette().inactive() : colorGroup() );#else const QColorGroup &cg = colorGroup();#endif PimContact c(*(contacts->sortedContacts().at(row))); bool selected = FALSE; if ( mSel != NoSelection && mSelected.find(c.uid()) != mSelected.end() ) selected = TRUE; //PimContact c = contacts->sortedContacts()at(row); QString text; int key = headerKeyFields[ col ]; switch(key) { case PimContact::FileAs: text = findContactName(c); break; case FREQ_CONTACT_FIELD: text = findContactContact(c); break; case PimContact::Birthday: { QDate d = c.birthday(); if ( !d.isNull() ) text = TimeString::localYMD( d ); } break; case PimContact::Anniversary: { QDate d = c.anniversary(); if ( !d.isNull() ) text = TimeString::localYMD( d ); } break; case PimContact::Gender: switch( c.gender() ) { case PimContact::Male: text = tr("Male"); break; case PimContact::Female: text = tr("Female"); break; default: text = ""; break; } break; case PimContact::Notes: text = c.field( key ).simplifyWhiteSpace(); break; case PimContact::BusinessStreet: case PimContact::HomeStreet: text = c.field( key ).simplifyWhiteSpace(); break; default: text = c.field( key ); } p->save(); if ( !selected ) { p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) ); p->setPen(cg.text()); } else { p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Highlight ) ); p->setPen(cg.highlightedText() ); } p->drawLine( 0, cr.height() - 1, cr.width() - 1, cr.height() - 1 ); p->drawLine( cr.width() - 1, 0, cr.width() - 1, cr.height() - 1 ); if (row == currentRow()) { QPen op = p->pen(); p->setPen( QColor(black) ); if (col == 0) p->drawLine( 0, 1, 0, cr.height() - 2); if (col == numCols() - 1) p->drawLine( cr.width() - 2, 1, cr.width() - 2, cr.height() - 2); p->drawLine( 0, cr.height() - 2, cr.width() - 1, cr.height() - 2 ); p->drawLine( 0, 0, cr.width() - 2, 0 ); p->setPen(op); } QFont f = p->font(); QFontMetrics fm(f); p->drawText(2,2 + fm.ascent(), text); p->restore();}void AbTable::setCurrentCell( int row, int col){ int orow = currentRow(); QTable::setCurrentCell(row, col); for (int i = 0; i < numCols(); i++) { updateCell(orow, i); updateCell(row, i); }}void AbTable::columnClicked( int col ){ if ( col != mSortColumn ) { mSortColumn = col; mAscending = FALSE; } else { mAscending = !mAscending; } horizontalHeader()->setSortIndicator(mSortColumn,!mAscending); reload();}PimContact AbTable::currentEntry(){ if (contacts->sortedContacts().count() == 0) return PimContact(); if (currentRow() >= (int)contacts->sortedContacts().count()) { setCurrentCell( contacts->sortedContacts().count() - 1, currentColumn()); } else if (currentRow() < 0) { setCurrentCell(0, currentColumn()); } return *(contacts->sortedContacts().at(currentRow()));}void AbTable::setCurrentEntry(const QUuid &u){ int rows, row; rows = numRows(); for ( row = 0; row < rows; row++ ) { if ( contacts->sortedContacts().at(row)->uid() == u) { setCurrentCell(row, currentColumn()); break; } }}void AbTable::selectAll(){ if ( mSel == NoSelection || mSel == Single ) return; selectionBeginRow = -1; mSelected.clear(); for ( uint u = 0; u < contacts->sortedContacts().count(); u++ ) { mSelected.append( contacts->sortedContacts().at(u)->uid() ); } refresh();}QValueList<QUuid> AbTable::selectedContacts(){ QValueList<QUuid> list; if ( mSel == Single ) { if ( hasCurrentEntry() ) list.append( currentEntry().uid() ); } else if ( mSel == Extended ) { list = mSelected; // set current entry as selected when none is selected if ( !list.count() && hasCurrentEntry() ) list.append( currentEntry().uid() ); } return list;}QValueList<PimContact> AbTable::selected(){ QValueList<PimContact> list; if ( mSel == Single ) { if ( hasCurrentEntry() ) list.append( currentEntry() ); } else if ( mSel == Extended ) { for ( QValueList<QUuid>::Iterator it = mSelected.begin(); it != mSelected.end(); ++it) { list.append( pimForUid( *it ) ); } // set current entry as selected when none is selected if ( !list.count() && hasCurrentEntry() ) list.append( currentEntry() ); } return list;}PimContact AbTable::pimForUid(const QUuid &id){ for ( uint u = 0; u < contacts->sortedContacts().count(); u++) { if ( id == contacts->sortedContacts().at(u)->uid() ) return *contacts->sortedContacts().at(u); } return PimContact();}bool AbTable::hasCurrentEntry(){ return contacts->sortedContacts().count() != 0;}void AbTable::reload(){// qDebug("reload callled with %d contacts and sortcol %d", c.count(), mSortColumn); mSelected.clear(); if ( mSortColumn > -1 ) { contacts->setSorting( headerKeyFields[mSortColumn], mAscending);// contacts->sortedContacts()sort(); } refresh(); emit currentChanged();}void AbTable::refresh(){// qDebug("AbTable::refresh %d contacts", contacts->sortedContacts()count()); setNumRows(contacts->sortedContacts().count());}void AbTable::keyPressEvent( QKeyEvent *e ){ // next 3 lines are evil.Q /* char key = toupper( e->ascii() ); if ( key >= 'A' && key <= 'Z' ) moveTo( e->text().lower() ); */ if (e->text()[0].isLetterOrNumber()) moveTo( e->text().lower() ); switch( e->key() ) { case Qt::Key_Space: case Qt::Key_Return: case Qt::Key_Enter: emit clicked(); break; default: QTable::keyPressEvent( e ); }}void AbTable::contentsMousePressEvent( QMouseEvent *e ){ if ( mSel == Extended ) { mSelected.clear(); bState = e->button(); } QTable::contentsMousePressEvent( e );}void AbTable::contentsMouseReleaseEvent( QMouseEvent *e ){ if ( mSel == Extended ) { selectionBeginRow = -1; bState = Qt::NoButton; } QTable::contentsMouseReleaseEvent( e );}void AbTable::resizeEvent( QResizeEvent *e ){ QTable::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}void AbTable::showEvent( QShowEvent *e){ QTable::showEvent(e);#ifdef QTOPIA_DESKTOP fitHeadersToWidth();#endif}void AbTable::fitHeadersToWidth(){ // work out the avail width. May need to subtract scrollbar. int w = width() - frameWidth(); if (contentsHeight() >= (height() - horizontalHeader()->height()) ) w -= ( style().scrollBarExtent().width() ); calcFieldSizes(0, w);}void AbTable::calcFieldSizes(int oldSize, int size){ constructorDone = FALSE; //don't let QTable mess up our logic int col = headerKeyFields.count(); int max = 0; int i; for ( i = 0; i < col; i++) { max += columnWidth(i); } if ( oldSize < max ) oldSize = max; int accumulated = 0; for ( i = 0; i < col; i++) { float l = (float) columnWidth( i ) / (float) oldSize; float l2 = l * size; int newColLen = (int) l2; int min = minimumFieldSize( (PimContact::ContactFields) headerKeyFields[i] ); if ( newColLen < min ) newColLen = min; // make sure we fill out the space if there's some integer rounding leftover if ( i == col - 1 && size - accumulated - 2> min ) newColLen = size - accumulated - 2; else accumulated += newColLen; setColumnWidth( i, newColLen ); } constructorDone = TRUE;}void AbTable::moveTo( const QString &cl ){ int rows = numRows(); /////=========================== int l, u, r = 0; int comparison=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -