Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

abview.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (c) 2002 Stefan Eilers (eilers.stefan@epost.de)
00003 **
00004 ** This file is part of Qt Palmtop Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 **
00015 **********************************************************************/
00016 
00017 #include "abview.h"
00018 
00019 #include <opie2/ocontactaccessbackend_vcard.h>
00020 #include <opie2/odebug.h>
00021 
00022 #include <qpe/global.h>
00023 
00024 #include <qlayout.h>
00025 
00026 #include <assert.h>
00027 
00028 
00029 // Is defined in LibQPE
00030 extern QString categoryFileName();
00031 
00032 QString addressbookPersonalVCardName()
00033 {
00034         QString filename = Global::applicationFileName("addressbook",
00035                                                        "businesscard.vcf");
00036         return filename;
00037 }
00038 
00039 
00040 AbView::AbView ( QWidget* parent, const QValueList<int>& ordered ):
00041         QWidget(parent),
00042         mCat(0),
00043         m_inSearch( false ),
00044         m_inPersonal( false ),
00045         m_sortOrder( true ),
00046         m_curr_category( 0 ),
00047         m_curr_View( TableView ),
00048         m_prev_View( TableView ),
00049         m_curr_Contact ( 0 ),
00050         m_contactdb ( 0l ),
00051         m_storedDB ( 0l ),
00052         m_viewStack( 0l ),
00053         m_abTable( 0l ),
00054         m_orderedFields( ordered )
00055 {
00056         odebug << "AbView::c'tor" << oendl;
00057         // Load default database and handle syncing myself.. !
00058         m_contactdb = new Opie::OPimContactAccess ( "addressbook", 0l, 0l, false );
00059         m_contactdb -> setReadAhead( 16 ); // Use ReadAhead-Cache if available
00060         mCat.load( categoryFileName() );
00061 
00062         // Create Layout and put WidgetStack into it.
00063         QVBoxLayout *vb = new QVBoxLayout( this );
00064         m_viewStack = new QWidgetStack( this );
00065         vb->addWidget( m_viewStack );
00066 
00067         // Creat TableView
00068         QVBox* tableBox = new QVBox( m_viewStack );
00069         m_abTable = new AbTable( m_orderedFields, tableBox, "table" );
00070         m_abTable->setCurrentCell( 0, 0 );
00071         m_abTable->setFocus();
00072 
00073         // Add TableView to WidgetStack and raise it
00074         m_viewStack -> addWidget( tableBox , TableView );
00075 
00076         // Create CardView and add it to WidgetStack
00077         QVBox* cardBox = new QVBox( m_viewStack );
00078         m_ablabel = new AbLabel( cardBox, "CardView");
00079         m_viewStack -> addWidget( cardBox , CardView );
00080 
00081         // Connect views to me
00082         connect ( m_abTable, SIGNAL( signalSwitch(void) ),
00083                   this, SLOT( slotSwitch(void) ) );
00084         connect ( m_abTable, SIGNAL( signalSortOrderChanged( bool ) ),
00085                   this, SLOT( slotSetSortOrder( bool ) ) );
00086         connect ( m_ablabel, SIGNAL( signalOkPressed(void) ),
00087                   this, SLOT( slotSwitch(void) ) );
00088 
00089         load();
00090 }
00091 
00092 AbView::~AbView()
00093 {
00094         m_contactdb -> save();
00095         delete m_contactdb;
00096 
00097         if ( m_storedDB ){
00098                 m_storedDB -> save();
00099                 delete m_storedDB;
00100         }
00101 }
00102 
00103 
00104 void AbView::setView( Views view )
00105 {
00106         odebug << "AbView::setView( Views view )" << oendl;
00107         m_curr_View = view;
00108         load();
00109 }
00110 
00111 void AbView::addEntry( const Opie::OPimContact &newContact )
00112 {
00113         odebug << "AbView::AddContact" << oendl;
00114         m_contactdb->add ( newContact );
00115         load();
00116 
00117 }
00118 void AbView::removeEntry( const int UID )
00119 {
00120         odebug << "AbView;:RemoveContact" << oendl;
00121         m_contactdb->remove( UID );
00122         load();
00123 }
00124 
00125 void AbView::replaceEntry( const Opie::OPimContact &contact )
00126 {
00127         odebug << "AbView::ReplaceContact" << oendl;
00128         m_contactdb->replace( contact );
00129         load();
00130 
00131 }
00132 
00133 Opie::OPimContact AbView::currentEntry()
00134 {
00135         Opie::OPimContact currentContact;
00136 
00137         switch ( (int) m_curr_View ) {
00138         case TableView:
00139                 currentContact = m_abTable -> currentEntry();
00140                 break;
00141         case CardView:
00142                 currentContact = m_ablabel -> currentEntry();
00143                 break;
00144         }
00145         m_curr_Contact = currentContact.uid();
00146         return currentContact;
00147 }
00148 
00149 bool AbView::save()
00150 {
00151         //      odebug << "AbView::Save data" << oendl;
00152 
00153         return m_contactdb->save();
00154 }
00155 
00156 void AbView::load()
00157 {
00158         odebug << "AbView::Load data" << oendl;
00159 
00160         // Letter Search is stopped at this place
00161         emit signalClearLetterPicker();
00162 
00163         odebug << "selected Category: " << m_curr_category << oendl;
00164         
00165         if ( m_curr_category == -1 ) {
00166                 // Show just unfiled contacts
00167                 m_list = m_contactdb->sorted( m_sortOrder, Opie::OPimContactAccess::SortFileAsName, 
00168                                               Opie::OPimContactAccess::DoNotShowWithCategory, 0 );
00169         } else  if ( m_curr_category == 0 ){
00170                 // Just show all contacts
00171                 m_list = m_contactdb->sorted( m_sortOrder, Opie::OPimContactAccess::SortFileAsName, 
00172                                               Opie::OPimBase::FilterOff, 0 );
00173         } else {
00174                 // Show contacts with given categories
00175                 m_list = m_contactdb->sorted( m_sortOrder, Opie::OPimContactAccess::SortFileAsName, 
00176                                               Opie::OPimBase::FilterCategory, m_curr_category );
00177         }
00178 
00179         odebug << "Number of contacts: " << m_list.count() << oendl;
00180 
00181         updateView( true );
00182 
00183 }
00184 
00185 void AbView::reload()
00186 {
00187         odebug << "AbView::::reload()" << oendl;
00188 
00189         m_contactdb->reload();
00190         load();
00191 }
00192 
00193 void AbView::clear()
00194 {
00195         // :SX
00196 }
00197 
00198 void AbView::setShowByCategory( const QString& cat )
00199 {
00200         odebug << "AbView::setShowCategory( const QString& cat )" << oendl;
00201 
00202         int intCat = 0;
00203 
00204         // Unfiled will be stored as -1
00205     if ( cat == tr( "Unfiled" ) )
00206         intCat = -1;
00207     else if ( cat.isNull() )
00208         intCat = 0;
00209         else
00210                 intCat = mCat.id("Contacts", cat );
00211 
00212         // Just do anything if we really change the category
00213         if ( intCat != m_curr_category ){
00214                 //              odebug << "Categories: Selected " << cat << ".. Number: "
00215                 //                                              << m_curr_category << oendl;
00216 
00217                 m_curr_category = intCat;
00218                 emit signalClearLetterPicker();
00219                 load();
00220         }
00221         m_curr_category = intCat;
00222 
00223 }
00224 
00225 void AbView::setShowToView( Views view )
00226 {
00227         odebug << "void AbView::setShowToView( View " << view << " )" << oendl;
00228 
00229         if ( m_curr_View != view ){
00230                 odebug << "Change the View (Category is: " << m_curr_category << ")" << oendl;
00231                 m_prev_View = m_curr_View;
00232                 m_curr_View = view;
00233 
00234                 updateView();
00235         }
00236 
00237 }
00238 
00239 void AbView::setShowByLetter( char c, AbConfig::LPSearchMode mode )
00240 {
00241         odebug << "void AbView::setShowByLetter( " << c << ", " << mode << " )" << oendl;
00242 
00243         assert( mode < AbConfig::LASTELEMENT );
00244 
00245         Opie::OPimContact query;
00246         if ( c == 0 ){
00247                 load();
00248                 return;
00249         }else{
00250                 // If the current Backend is unable to solve the query, we will
00251                 // ignore the request ..
00252                 if ( ! m_contactdb->hasQuerySettings( Opie::OPimContactAccess::WildCards |
00253                                                       Opie::OPimContactAccess::IgnoreCase ) ){
00254                         owarn << "Tried to access queryByExample which is not supported by the current backend!!" << oendl;
00255                         owarn << "I have to ignore this access!" << oendl;
00256                         return;
00257                 }
00258 
00259                 switch( mode ){
00260                 case AbConfig::LastName:
00261                         query.setLastName( QString("%1*").arg(c) );
00262                         break;
00263                 case AbConfig::FileAs:
00264                         query.setFileAs( QString("%1*").arg(c) );
00265                         break;
00266                 default:
00267                         owarn << "Unknown Searchmode for AbView::setShowByLetter ! -> " << mode << oendl
00268                                                         << "I will ignore it.." << oendl;
00269                         return;
00270                 }
00271                 m_list = m_contactdb->queryByExample( query, Opie::OPimContactAccess::WildCards | Opie::OPimContactAccess::IgnoreCase );
00272 
00273         if ( m_curr_category != 0 )
00274                         clearForCategory();
00275 
00276         // Sort filtered results
00277         m_list = m_contactdb->sorted( m_list, true, Opie::OPimContactAccess::SortFileAsName,
00278                           Opie::OPimContactAccess::FilterCategory, m_curr_category );
00279                 m_curr_Contact = 0;
00280         }
00281         updateView( true );
00282 }
00283 
00284 void AbView::setListOrder( const QValueList<int>& ordered )
00285 {
00286         m_orderedFields = ordered;
00287         if ( m_abTable ){
00288                 m_abTable->setOrderedList( ordered );
00289                 m_abTable->refresh();
00290         }
00291         updateView();
00292 }
00293 
00294 
00295 QString AbView::showCategory() const
00296 {
00297         return mCat.label( "Contacts", m_curr_category );
00298 }
00299 
00300 void AbView::showPersonal( bool personal )
00301 {
00302         odebug << "void AbView::showPersonal( " << personal << " )" << oendl;
00303 
00304         if ( personal ){
00305 
00306                 if ( m_inPersonal )
00307                         return;
00308 
00309                 // Now switch to vCard Backend and load data.
00310                 // The current default backend will be stored
00311                 // to avoid unneeded load/stores.
00312                 m_storedDB = m_contactdb;
00313 
00314                 Opie::OPimContactAccessBackend* vcard_backend = new Opie::OPimContactAccessBackend_VCard( QString::null,
00315                                                                           addressbookPersonalVCardName() );
00316                 m_contactdb = new Opie::OPimContactAccess ( "addressbook", QString::null , vcard_backend, true );
00317 
00318                 m_inPersonal = true;
00319                 m_curr_View = CardView;
00320 
00321         }else{
00322 
00323                 if ( !m_inPersonal )
00324                         return;
00325 
00326                 // Remove vCard Backend and restore default
00327                 m_contactdb->save();
00328                 delete m_contactdb;
00329 
00330                 m_contactdb = m_storedDB;
00331                 m_storedDB = 0l;
00332 
00333                 m_curr_View = TableView;
00334                 m_inPersonal = false;
00335 
00336         }
00337         load();
00338 }
00339 
00340 void AbView::setCurrentUid( int uid ){
00341 
00342         m_curr_Contact = uid;
00343         updateView( true ); //true: Don't modificate the UID !
00344 }
00345 
00346 
00347 QStringList AbView::categories()
00348 {
00349         mCat.load( categoryFileName() );
00350         QStringList categoryList = mCat.labels( "Contacts" );
00351         return categoryList;
00352 }
00353 
00354 // BEGIN: Slots
00355 void AbView::slotDoFind( const QString &str, bool caseSensitive, bool useRegExp,
00356                          bool , QString cat )
00357 {
00358         //      owarn << "void AbView::slotDoFind" << oendl;
00359 
00360         // We reloading the data: Deselect Letterpicker
00361         emit signalClearLetterPicker();
00362 
00363         // Use the current Category if nothing else selected
00364         int category = 0;
00365 
00366         if ( cat.isEmpty() )
00367                 category = m_curr_category;
00368         else{
00369                 category = mCat.id("Contacts", cat );
00370         }
00371 
00372         //      odebug << "Find in Category " << category << oendl;
00373 
00374         QRegExp r( str );
00375         r.setCaseSensitive( caseSensitive );
00376         r.setWildcard( !useRegExp );
00377 
00378         // Get all matching entries out of the database
00379         m_list = m_contactdb->matchRegexp( r );
00380 
00381         //      odebug << "Found: " << m_list.count() << oendl;
00382         if ( m_list.count() == 0 ){
00383                 emit signalNotFound();
00384                 return;
00385         }
00386 
00387         // Now remove all contacts with wrong category (if any selected)
00388         // This algorithm is a litte bit ineffective, but
00389         // we will not have a lot of matching entries..
00390         if ( m_curr_category != 0 )
00391                 clearForCategory();
00392 
00393         // Now show all found entries
00394         updateView( true );
00395 }
00396 
00397 void AbView::offSearch()
00398 {
00399         m_inSearch = false;
00400 
00401         load();
00402 }
00403 
00404 void AbView::slotSwitch(){
00405         //      odebug << "AbView::slotSwitch()" << oendl;
00406 
00407         m_prev_View = m_curr_View;
00408         switch ( (int) m_curr_View ){
00409         case TableView:
00410                 odebug << "Switching to CardView" << oendl;
00411                 m_curr_View = CardView;
00412                 break;
00413         case CardView:
00414                 odebug << "Switching to TableView" << oendl;
00415                 m_curr_View = TableView;
00416                 break;
00417         }
00418         updateView();
00419 
00420 }
00421 
00422 void AbView::slotSetSortOrder( bool order ){
00423         m_sortOrder = order;
00424         reload();
00425 }
00426 
00427 // END: Slots
00428 
00429 void AbView::clearForCategory()
00430 {
00431         Opie::OPimContactAccess::List::Iterator it;
00432         // Now remove all contacts with wrong category if any category selected
00433 
00434         Opie::OPimContactAccess::List allList = m_list;
00435         if ( m_curr_category != 0 ){
00436                 for ( it = allList.begin(); it != allList.end(); ++it ){
00437                         if ( !contactCompare( *it, m_curr_category ) ){
00438                                 //odebug << "Removing " << (*it).uid() << oendl;
00439                                 m_list.remove( (*it).uid() );
00440                         }
00441                 }
00442         }
00443 
00444 }
00445 
00446 bool AbView::contactCompare( const Opie::OPimContact &cnt, int category )
00447 {
00448         //      odebug << "bool AbView::contactCompare( const Opie::OPimContact &cnt, "
00449         //                                      << category << " )" << oendl;
00450 
00451         bool returnMe;
00452         QArray<int> cats;
00453         cats = cnt.categories();
00454 
00455         //      odebug << "Number of categories: " << cats.count() << oendl;
00456 
00457         returnMe = false;
00458         if ( cats.count() == 0 && category == -1 )
00459                 // Contacts with no category will just shown on "All" and "Unfiled"
00460                 returnMe = true;
00461         else {
00462                 int i;
00463                 for ( i = 0; i < int(cats.count()); i++ ) {
00464                         //odebug << "Comparing " << cats[i] << " with " << category << oendl;
00465                         if ( cats[i] == category ) {
00466                                 returnMe = true;
00467                                 break;
00468                         }
00469                 }
00470         }
00471         //      odebug << "Return: " << returnMe << oendl;
00472         return returnMe;
00473 }
00474 
00475 // In Some rare cases we have to update all lists..
00476 void AbView::updateListinViews()
00477 {
00478                 m_abTable -> setContacts( m_list );
00479                 m_ablabel -> setContacts( m_list );
00480 }
00481 
00482 void  AbView::updateView( bool newdata )
00483 {
00484         //      odebug << "AbView::updateView()" << oendl;
00485 
00486         if ( m_viewStack -> visibleWidget() ){
00487                 m_viewStack -> visibleWidget() -> clearFocus();
00488         }
00489 
00490         // If we switching the view, we have to store some information
00491         if ( !newdata ){
00492                 if ( m_list.count() ){
00493                         switch ( (int) m_prev_View ) {
00494                         case TableView:
00495                                 m_curr_Contact = m_abTable -> currentEntry_UID();
00496                                 break;
00497                         case CardView:
00498                                 m_curr_Contact = m_ablabel -> currentEntry_UID();
00499                                 break;
00500                         }
00501                 }else
00502                         m_curr_Contact = 0;
00503         }
00504 
00505         // Feed all views with new lists
00506         if ( newdata )
00507                 updateListinViews();
00508 
00509         // Tell the world that the view is changed
00510         if ( m_curr_View != m_prev_View )
00511                 emit signalViewSwitched ( (int) m_curr_View );
00512 
00513         m_prev_View = m_curr_View;
00514 
00515         // Switch to new View
00516         switch ( (int) m_curr_View ) {
00517         case TableView:
00518                 m_abTable -> setChoiceSelection( m_orderedFields );
00519                 if ( m_curr_Contact != 0 )
00520                         m_abTable -> selectContact ( m_curr_Contact );
00521                 m_abTable -> setFocus();
00522                 break;
00523         case CardView:
00524                 if ( m_curr_Contact != 0 )
00525                         m_ablabel -> selectContact( m_curr_Contact );
00526                 m_ablabel -> setFocus();
00527                 break;
00528         }
00529 
00530         // Raise the current View
00531         m_viewStack -> raiseWidget( m_curr_View );
00532 }
00533 
00534 

Generated on Sat Nov 5 16:15:46 2005 for OPIE by  doxygen 1.4.2