User interface update
[qtmeetings] / src / IO / Communication / CommunicationManager.cpp
1 #include "CommunicationManager.h"
2 #include "Communication.h"
3 #include "ConnectionSettings.h"
4 #include "Meeting.h"
5 #include "Room.h"
6 #include <QDateTime>
7 #include <QDomDocument>
8 #include <QDebug>
9 #include "../../Domain/Configuration/Configuration.h";
10
11 static const int ERROR_BASE=100;
12
13
14 CommunicationManager::CommunicationManager()
15 {
16
17         iModifyingCommunication = NULL;
18
19         iFetchingCommunication = new Communication();
20
21         if ( iFetchingCommunication )
22         {
23                 connect( iFetchingCommunication,
24                                  SIGNAL( readProgress( int, int, int ) ),
25                                  this,
26                                  SLOT( readProgress( int, int, int ) )
27                                 );
28                 connect( iFetchingCommunication,
29                                  SIGNAL( requestFinished( int, int ) ),
30                                  this,
31                                  SLOT( requestFinished( int, int ) )
32                                 );
33         }
34
35 }
36
37 CommunicationManager::~CommunicationManager()
38 {
39         //delete iConnectionSettings;
40         delete iModifyingCommunication;
41         delete iFetchingCommunication;
42         while ( !iMeetings.isEmpty() )
43                 delete iMeetings.takeFirst();
44 }
45
46 void CommunicationManager::fetchMeetings( const int aWeek, const int aYear, const Room &aIn )
47 {
48         //prevent making multiple simultaneous user availibility requests
49         //TODO: Would be nice to queue these requests instead of just aborting 
50         const RequestData* rd = findRequest( GetUserAvailability );
51         if( rd )
52                 return;
53         
54         // Set from to beginning, 00:00 of the requested week
55         QDateTime from = QDateTime::currentDateTime();
56         from = from.addYears( aYear - from.date().year() );
57         from = from.addDays( -1*(from.date().dayOfWeek()-1) );
58         from = from.addDays( (aWeek - from.date().weekNumber())*7 );
59         QTime midnight = from.time();
60         midnight.setHMS( 0,0,0 );
61         from.setTime( midnight );
62         qDebug() << "CommunicationManager::fetchMeetings from: " << from.toString();
63         
64         QDateTime until = from.addDays(7);
65         qDebug() << "CommunicationManager::fetchMeetings until: " << until.toString();
66         
67         
68         ReqMsgGetUserAvailability msg;
69         msg.setTimeZone();
70         msg.setTimeWindow( from, until );
71         msg.addUser( aIn.address() );
72                 
73         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), msg.getMessage() );
74         qDebug() << "CommunicationManager::fetchMeetings: id: " << id;
75         if( id )
76         {
77                 addRequest( GetUserAvailability, id );
78                 iRequestInfos.first()->room = new Room( aIn );
79         }
80 }
81
82 void CommunicationManager::getSecondaryIdForMeeting( Meeting &aMeeting )
83 {
84         ReqMsgConvertMeetingId msg( aMeeting.primaryId(), aMeeting.room().address() );
85         
86         QByteArray arr = msg.getMessage();
87
88         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), arr );
89         qDebug() << "CommunicationManager::getSecondaryIdForMeeting: id: " << id;
90         if( id )
91         {
92                 addRequest( ConvertId, id );
93                 iRequestInfos.first()->meeting = &aMeeting;
94         }
95 }
96
97 void CommunicationManager::fetchMeetingDetails( Meeting& aMeeting )
98 {
99         if( aMeeting.detailsAvailable() )
100         {
101                 emit meetingDetailsFetched( aMeeting );
102                 return;
103         }
104         if( aMeeting.secondaryId().isEmpty() )
105         {
106                 getSecondaryIdForMeeting( aMeeting );
107         }
108         else
109         {
110                 getMeetingDetails( aMeeting );
111         }
112 }
113
114 void CommunicationManager::cancelFetchMeetingDetails()
115 {
116         const RequestData *rd = findRequest( GetCalendarItem );
117         if( rd != NULL ) {
118                 int id = rd->requestId;
119                 iCancelledRequests.append( id );
120         }
121 }
122
123 void CommunicationManager::getMeetingDetails( Meeting &aMeeting )
124 {
125         ReqMsgGetCalendarItem msg( aMeeting.secondaryId() );
126         
127         QByteArray arr = msg.getMessage();
128         
129         int id = iFetchingCommunication->request( msg.getContentTypeForHeader(), arr );
130         qDebug() << "CommunicationManager::getMeetingDetails: id: " << id;
131         if( id )
132         {
133                 addRequest( GetCalendarItem, id );
134                 iRequestInfos.first()->meeting = &aMeeting;
135         }
136 }
137
138 void CommunicationManager::requestFinished( int aRequestId, int aError )
139 {
140         RequestData* rd = takeRequest( aRequestId );
141         if( iCancelledRequests.contains( rd->requestId ) )
142         {
143                 iCancelledRequests.removeAll( rd->requestId );
144                 delete rd;
145                 return;
146         }
147         QByteArray* response = iFetchingCommunication->response( aRequestId );
148         qDebug() << "CommunicationManager::requestFinished: id: " << aRequestId << " error: " << aError;
149
150         if( aError != (int)(QHttp::NoError) || rd == NULL || response == NULL )
151         {
152                 int err = aError;
153                 if( rd == NULL || response == NULL )
154                         err = 10;
155                 delete rd;
156                 emit error( ERROR_BASE+(int)err, CommunicationManager::FetchingCommunication );
157                 while ( !iMeetings.isEmpty() )
158                                         delete iMeetings.takeFirst();
159                 emit meetingsFetched( iMeetings );
160                 return;
161         }
162
163         switch( rd->type )
164         {
165         case GetUserAvailability:
166                 {
167                 ResMsgGetUserAvailability msg( *response );
168         
169                 while ( !iMeetings.isEmpty() )
170                         delete iMeetings.takeFirst();
171         
172                 int err = msg.getMeetingsFromResponse( iMeetings, *(rd->room) );
173                 if( err )
174                         {
175                         emit error( ERROR_BASE+8, CommunicationManager::FetchingCommunication );
176                         while ( !iMeetings.isEmpty() )
177                                                                 delete iMeetings.takeFirst();
178                                         emit meetingsFetched( iMeetings );
179                         }
180                 else
181                         {
182                         qDebug("*** COMMUNICATIONMANAGER ::: Meetings fetched!");
183                         emit meetingsFetched( iMeetings );
184                         }
185                 break;
186                 }
187         case ConvertId:
188                 {
189                 ResponseMessage msg( *response );
190                 QString id = msg.getNodeValue( QString( "Id" ),
191                                                                            QDomNode::AttributeNode,
192                                                                            QString( "AlternateId" ) );
193                 qDebug( "ID IS: %s", id.toStdString().data() );
194                 rd->meeting->setSecondaryId( id );
195                 getMeetingDetails( *(rd->meeting) );
196                 break;
197                 }
198         case GetCalendarItem:
199                 {
200                 ResMsgGetCalendarItem msg( *response );
201                 int err = msg.getMeetingDetailsFromResponse( *(rd->meeting) );
202                 if( err )
203                         {
204                         emit error( ERROR_BASE+9, CommunicationManager::FetchingCommunication );
205                         while ( !iMeetings.isEmpty() )
206                                                                 delete iMeetings.takeFirst();
207                                         emit meetingsFetched( iMeetings );
208                         }
209
210                 else
211                         emit meetingDetailsFetched( *(rd->meeting) );
212                 break;
213                 }
214         }
215         delete response;
216         delete rd;
217 }
218
219 void CommunicationManager::readProgress( int /*aRequestId*/, int aDone, int aTotal )
220 {
221         emit readProgress( aDone, aTotal, CommunicationManager::FetchingCommunication );
222 }
223
224 void CommunicationManager::addRequest( RequestType aType, int aRequestId )
225 {
226         RequestData* rd = new RequestData( aType, aRequestId );
227         iRequestInfos.append( rd );
228 }
229
230 CommunicationManager::RequestData* CommunicationManager::takeRequest( int aRequestId )
231 {
232         if( aRequestId == 0 )
233                 return NULL;
234
235         for( int i = iRequestInfos.count() - 1; i >= 0 ; i-- )
236         {
237                 struct RequestData* rd = iRequestInfos[i];
238                 if( rd->requestId == aRequestId )
239                 {
240                         iRequestInfos.removeAt( i );
241                         return rd;
242                 }
243         }
244         return NULL;
245 }
246
247 const CommunicationManager::RequestData* CommunicationManager::findRequest( RequestType aRequestType ) const
248 {
249         for( int i = iRequestInfos.count() - 1; i >= 0 ; i-- )
250         {
251                 struct RequestData* rd = iRequestInfos[i];
252                 if( rd->type == aRequestType )
253                 {
254                         return rd;
255                 }
256         }
257         return NULL;
258 }
259