libkpimexchange Library API Documentation

dateset.cpp

00001 /* 00002 This file is part of libkpimexchange. 00003 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org> 00004 00005 This library is free software; you can redistribute it and/or modify it 00006 under the terms of the GNU Library General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or (at your 00008 option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, but WITHOUT 00011 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to the 00017 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00018 02111-1307, USA. 00019 */ 00020 00021 // $Id: dateset.cpp,v 1.1 2002/12/11 11:25:13 janpascal Exp $ 00022 00023 #include <qptrlist.h> 00024 #include <qdatetime.h> 00025 #include <qpair.h> 00026 00027 #include <kdebug.h> 00028 00029 #include "dateset.h" 00030 00031 DateSet::DateSet() 00032 { 00033 kdDebug() << "Creating DateSet" << endl; 00034 // mOldestDate = 00035 mDates = new RangeList(); 00036 mDates->setAutoDelete( true ); 00037 } 00038 00039 DateSet::~DateSet() 00040 { 00041 kdDebug() << "Deleting DateSet" << endl; 00042 delete mDates; 00043 } 00044 00045 void DateSet::add( QDate const& date ) 00046 { 00047 if (mDates->isEmpty()) { 00048 mDates->insert( 0, new QPair<QDate,QDate>( date, date ) ); 00049 return; 00050 } 00051 int i = find( date ); 00052 mDates->insert( i, new QPair<QDate,QDate>( date, date ) ); 00053 tryMerge( i ); 00054 tryMerge( i-1 ); 00055 } 00056 00057 void DateSet::add( QDate const& from, QDate const& to ) 00058 { 00059 if (mDates->isEmpty()) { 00060 mDates->insert( 0, new QPair<QDate,QDate>( from, to ) ); 00061 return; 00062 } 00063 uint i = find( from ); 00064 kdDebug() << "Adding range at position " << i << endl; 00065 mDates->insert( i, new QPair<QDate,QDate>( from, to ) ); 00066 00067 do { 00068 } while ( tryMerge( i ) ); 00069 do { 00070 } while ( tryMerge( i-1 ) ); 00071 /* 00072 QPair<QDate,QDate>* item = mDates->at( i ); 00073 00074 if (to >= item->first) 00075 return; 00076 00077 if (to.daysTo( item->first ) == 1 ) 00078 item->first = from; 00079 else 00080 mDates->insert( i, new QPair<QDate,QDate>( from, to ) ); 00081 */ 00082 } 00083 00084 void DateSet::remove( QDate const& date ) 00085 { 00086 if (mDates->isEmpty()) { 00087 return; 00088 } 00089 00090 uint i = find( date ); 00091 if ( i == mDates->count() ) 00092 return; 00093 00094 QPair<QDate,QDate>* item = mDates->at( i ); 00095 if ( date < item->first ) 00096 return; 00097 if ( date == item->first ) { 00098 if ( date == item->second ) { 00099 mDates->remove( i ); 00100 } else { 00101 item->first = item->first.addDays( 1 ); 00102 } 00103 return; 00104 } 00105 00106 if ( date == item->second ) { 00107 item->second = item->second.addDays( -1 ); 00108 } else { 00109 mDates->insert( i, new QPair<QDate,QDate>(item->first, date.addDays( -1 ) ) ); 00110 item->first = date.addDays( 1 ); 00111 } 00112 } 00113 00114 void DateSet::remove( QDate const& from, QDate const& to ) 00115 { 00116 if (mDates->isEmpty()) { 00117 return; 00118 } 00119 00120 uint i = find( from ); 00121 if ( i == mDates->count() ) 00122 return; 00123 00124 while( i < mDates->count() ) { 00125 QPair<QDate,QDate>* item = mDates->at( i ); 00126 // Check if we're done: next item is later dan removal period 00127 if ( to < item->first ) 00128 break; 00129 00130 // Check if entire item should be removed 00131 if ( from <= item->first && to >= item->second ) { 00132 mDates->remove( i ); 00133 // Don't skip the next range 00134 continue; 00135 } 00136 00137 // Check if we should take a slice out of the middle of the item 00138 if ( from > item->first && to < item->second ) { 00139 mDates->insert( i, new QPair<QDate,QDate>( item->first, from.addDays( -1 ) ) ); 00140 item->first = to.addDays( 1 ); 00141 break; // We're done 00142 } 00143 00144 // Now check if we should take off the beginning of the item 00145 if ( from <= item->first ) { 00146 item->first = to.addDays( 1 ); 00147 // Finished 00148 break; 00149 } 00150 00151 // Only one possibility left: we should take off the end 00152 // of the current range 00153 item->second = from.addDays( -1 ); 00154 i++; 00155 } 00156 } 00157 00158 bool DateSet::contains( QDate const& date ) 00159 { 00160 if (mDates->isEmpty()) { 00161 return false; 00162 } 00163 00164 uint i = find( date ); 00165 // kdDebug() << "contains looking for " << date.toString() << " at range " << i << endl; 00166 if ( i == mDates->count() ) 00167 return false; 00168 00169 QPair<QDate,QDate>* item = mDates->at( i ); 00170 // kdDebug() << "contains looking at range " << item->first.toString() << " -- " << item->second.toString() << endl; 00171 return ( item->first <= date ); 00172 } 00173 00174 // returns true if and only if the whole range is in the set 00175 bool DateSet::contains( QDate const& from, QDate const& to ) 00176 { 00177 if (mDates->isEmpty()) { 00178 return false; 00179 } 00180 00181 uint i = find( from ); 00182 if ( i == mDates->count() ) 00183 return false; 00184 00185 QPair<QDate,QDate>* item = mDates->at( i ); 00186 00187 return ( from >= item->first && to <= item->second ); 00188 } 00189 00190 // Finds the index in mDates of the range containing date, if it 00191 // exists. Else, return the index of the range following the date. 00192 // If mDates is empty, return 0. 00193 // If date is later than the last item in mDates, return mDates->count() 00194 00195 int DateSet::find( QDate const& date ) 00196 { 00197 if ( mDates->isEmpty() ) 00198 return 0; 00199 00200 int start = 0; 00201 int end = mDates->count(); 00202 while ( start < end ) { 00203 int i = start + (end-start) / 2; 00204 // kdDebug() << start << ", " << i << ", " << end << endl; 00205 QPair<QDate,QDate> *item = mDates->at( i ); 00206 if ( item->first <= date && date <= item->second ) 00207 return i; 00208 if ( date > item->second ) { 00209 start = i+1; 00210 } else { // this means date < item->first 00211 end = i; 00212 } 00213 } 00214 00215 // kdDebug() << "Found for date " << date.toString() << " range " << end << endl; 00216 return end; 00217 /* 00218 // Now either start==end or start+1 == end 00219 if ( mDates->at( end )->second < date ) 00220 return end+1; 00221 else if (mDates->at( start )->first > date ) 00222 return start; 00223 else 00224 return end; 00225 */ 00226 } 00227 00228 void DateSet::print() 00229 { 00230 for( uint i=0; i<mDates->count(); i++ ) 00231 { 00232 QDate start = mDates->at( i )->first; 00233 QDate end = mDates->at( i )->second; 00234 if (start == end) 00235 kdDebug() << start.toString() << endl; 00236 else 00237 kdDebug() << "(" << start.toString() << " , " << end.toString() << ")" << endl; 00238 } 00239 } 00240 00241 // Try and merge range i with range i+1 00242 // NOT TRUE preconditions: range i starts before range i+1, but MAY end later! 00243 // preconditions: range i starts before or in range i+1 00244 bool DateSet::tryMerge( int i ) 00245 { 00246 if ( i < 0 || i+1 >= mDates->count() ) 00247 return false; 00248 00249 QPair<QDate,QDate>* item1 = mDates->at( i ); 00250 QPair<QDate,QDate>* item2 = mDates->at( i+1 ); 00251 00252 // First case: item1 starts before or on the same date as item2 00253 if ( item1->first <= item2->first ) { 00254 // Check for overlap 00255 if ( item1->second >= item2->first || 00256 item1->second.daysTo( item2->first ) == 1 ) { 00257 kdDebug() << "Merging items " << i << " and " << (i+1) << endl; 00258 if (item1->second < item2->second) item1->second = item2->second; 00259 mDates->remove( i+1 ); 00260 return true; 00261 } 00262 return false; 00263 } 00264 00265 // Second case: item1 starts later than item2 (but at the latest on 00266 // the last day of item2, see preconditions!) 00267 00268 // Check for overlap 00269 if ( item1->second >= item2->first || 00270 item1->second.daysTo( item2->first ) == 1 ) { 00271 kdDebug() << "Merging items " << i << " and " << (i+1) << endl; 00272 if (item1->second < item2->second) item1->second = item2->second; 00273 item1->first = item2->first; 00274 mDates->remove( i+1 ); 00275 return true; 00276 } 00277 return false; 00278 } 00279 00280
KDE Logo
This file is part of the documentation for libkpimexchange Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:58:09 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003