00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "vtodo.h"
00024
00025 #include <stdint.h>
00026 #include <stdlib.h>
00027 #include <glib.h>
00028 #include <string.h>
00029 #include <sstream>
00030
00031 namespace Barry { namespace Sync {
00032
00033
00034
00035
00036 namespace {
00037 static void ToLower(std::string &str)
00038 {
00039 size_t i = 0;
00040 while( i < str.size() ) {
00041 str[i] = tolower(str[i]);
00042 i++;
00043 }
00044 }
00045 }
00046
00047
00048
00049
00050 vTodo::vTodo(vTimeConverter &vtc)
00051 : m_vtc(vtc)
00052 , m_gTodoData(0)
00053 {
00054 }
00055
00056 vTodo::~vTodo()
00057 {
00058 if( m_gTodoData ) {
00059 g_free(m_gTodoData);
00060 }
00061 }
00062
00063 bool vTodo::HasMultipleVTodos() const
00064 {
00065 int count = 0;
00066 b_VFormat *format = const_cast<b_VFormat*>(Format());
00067 GList *attrs = format ? b_vformat_get_attributes(format) : 0;
00068 for( ; attrs; attrs = attrs->next ) {
00069 b_VFormatAttribute *attr = (b_VFormatAttribute*) attrs->data;
00070 if( strcasecmp(b_vformat_attribute_get_name(attr), "BEGIN") == 0 &&
00071 strcasecmp(b_vformat_attribute_get_nth_value(attr, 0), "VTODO") == 0 )
00072 {
00073 count++;
00074 }
00075 }
00076 return count > 1;
00077 }
00078
00079
00080
00081
00082 const std::string& vTodo::ToTask(const Barry::Task &task)
00083 {
00084
00085 std::ostringstream oss;
00086 task.Dump(oss);
00087
00088
00089
00090 Clear();
00091 SetFormat( b_vformat_new() );
00092 if( !Format() )
00093 throw ConvertError("resource error allocating vformat");
00094
00095
00096 m_BarryTask = task;
00097
00098
00099 AddAttr(NewAttr("PRODID", "-//OpenSync//NONSGML Barry Task Record//EN"));
00100 AddAttr(NewAttr("BEGIN", "VTODO"));
00101 AddAttr(NewAttr("SEQUENCE", "0"));
00102 AddAttr(NewAttr("SUMMARY", task.Summary.c_str()));
00103 AddAttr(NewAttr("DESCRIPTION", task.Notes.c_str()));
00104 AddAttr(NewAttr("CATEGORIES", ToStringList(task.Categories).c_str()));
00105
00106
00107 if (task.StatusFlag == Barry::Task::InProgress)
00108 AddAttr(NewAttr("STATUS", "IN-PROCESS"));
00109 else if (task.StatusFlag == Barry::Task::Completed)
00110 AddAttr(NewAttr("STATUS", "COMPLETED"));
00111 else if (task.StatusFlag == Barry::Task::Deferred)
00112 AddAttr(NewAttr("STATUS", "CANCELLED"));
00113 else if (task.StatusFlag == Barry::Task::Waiting)
00114 AddAttr(NewAttr("STATUS", "NEEDS-ACTION"));
00115
00116
00117 if (task.PriorityFlag == Barry::Task::High)
00118 AddAttr(NewAttr("PRIORITY", "3"));
00119 else if (task.PriorityFlag == Barry::Task::Normal)
00120 AddAttr(NewAttr("PRIORITY", "5"));
00121 else
00122 AddAttr(NewAttr("PRIORITY", "7"));
00123
00124
00125 if( task.StartTime ) {
00126 AddAttr(NewAttr("DTSTART",
00127 m_vtc.unix2vtime(&task.StartTime).c_str()));
00128 }
00129
00130
00131 if( task.DueDateFlag ) {
00132 AddAttr(NewAttr("DUE",
00133 m_vtc.unix2vtime(&task.DueTime).c_str()));
00134 }
00135
00136
00137
00138 AddAttr(NewAttr("END", "VTODO"));
00139
00140
00141 m_gTodoData = b_vformat_to_string(Format(), VFORMAT_TODO_20);
00142 m_vTodoData = m_gTodoData;
00143
00144
00145 return m_vTodoData;
00146 }
00147
00148
00149
00150 const Barry::Task& vTodo::ToBarry(const char *vtodo, uint32_t RecordId)
00151 {
00152 using namespace std;
00153
00154
00155
00156
00157
00158 if( HasMultipleVTodos() )
00159 throw ConvertError("vCalendar data contains more than one VTODO block, unsupported");
00160
00161
00162 Clear();
00163
00164
00165 m_vTodoData = vtodo;
00166
00167
00168 SetFormat( b_vformat_new_from_string(vtodo) );
00169 if( !Format() )
00170 throw ConvertError("resource error allocating vtodo");
00171
00172 string summary = GetAttr("SUMMARY", "/vtodo");
00173
00174 if( summary.size() == 0 ) {
00175 summary = "<blank subject>";
00176
00177 }
00178
00179 string notes = GetAttr("DESCRIPTION", "/vtodo");
00180
00181
00182 string status = GetAttr("STATUS", "/vtodo");
00183
00184
00185 string priority = GetAttr("PRIORITY", "/vtodo");
00186
00187
00188 string start = GetAttr("DTSTART", "/vtodo");
00189
00190
00191 string due = GetAttr("DUE", "/vtodo");
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 Barry::Task &rec = m_BarryTask;
00209 rec.SetIds(Barry::Task::GetDefaultRecType(), RecordId);
00210
00211
00212
00213 rec.Categories = GetValueVector("CATEGORIES","/vtodo");
00214
00215
00216 rec.Summary = summary;
00217 rec.Notes = notes;
00218
00219
00220 if (status.size()) {
00221 ToLower(status);
00222
00223 const char *s = status.c_str();
00224
00225 if (strstr(s, "in-process"))
00226 rec.StatusFlag = Barry::Task::InProgress;
00227 else if (strstr(s, "completed"))
00228 rec.StatusFlag = Barry::Task::Completed;
00229 else if (strstr(s, "cancelled"))
00230 rec.StatusFlag = Barry::Task::Deferred;
00231 else if (strstr(s, "needs-action"))
00232 rec.StatusFlag = Barry::Task::Waiting;
00233 else
00234 rec.StatusFlag = Barry::Task::NotStarted;
00235 }
00236
00237
00238 if (priority.size()) {
00239 ToLower(priority);
00240
00241 const char *s = priority.c_str();
00242
00243 const int val = atoi(s);
00244
00245 if (val < 4)
00246 rec.PriorityFlag = Barry::Task::High;
00247 else if (val < 7)
00248 rec.PriorityFlag = Barry::Task::Normal;
00249 else
00250 rec.PriorityFlag = Barry::Task::Low;
00251 }
00252
00253
00254
00255 if (start.size()) {
00256 rec.StartTime = m_vtc.vtime2unix(start.c_str());
00257 }
00258
00259 if (due.size()) {
00260 rec.DueDateFlag = true;
00261 rec.DueTime = m_vtc.vtime2unix(due.c_str());
00262 }
00263
00264 std::ostringstream oss;
00265 m_BarryTask.Dump(oss);
00266
00267 return m_BarryTask;
00268 }
00269
00270
00271 char* vTodo::ExtractVTodo()
00272 {
00273 char *ret = m_gTodoData;
00274 m_gTodoData = 0;
00275 return ret;
00276 }
00277
00278 void vTodo::Clear()
00279 {
00280 vBase::Clear();
00281 m_vTodoData.clear();
00282 m_BarryTask.Clear();
00283
00284 if( m_gTodoData ) {
00285 g_free(m_gTodoData);
00286 m_gTodoData = 0;
00287 }
00288 }
00289
00290 }}
00291