Folks,
Attached is patch for correct category support for task syncing in
opensync-0.4x
John.
diff --git a/opensync-plugin-0.4x/src/vbase.cc b/opensync-plugin-0.4x/src/vbase.cc
index b0824ef..c266af9 100644
--- a/opensync-plugin-0.4x/src/vbase.cc
+++ b/opensync-plugin-0.4x/src/vbase.cc
@@ -291,6 +291,38 @@ std::string vBase::GetAttr(const char *attrname, const char *block)
return ret;
}
+std::vector<std::string> vBase::GetValueVector(const char * attrname, const char * block)
+{
+ Trace trace("vBase::GetValueVector");
+ trace.logf("getting value vector for: %s", attrname);
+
+ std::vector<std::string> ret;
+ const char *value = 0;
+ bool needs_freeing = false;
+
+ b_VFormatAttribute *attr = b_vformat_find_attribute(m_format, attrname, 0, block);
+ if( attr ) {
+ if( b_vformat_attribute_is_single_valued(attr) ) {
+ value = b_vformat_attribute_get_value(attr);
+ needs_freeing = true;
+ } else {
+ // nasty, but avoids tweaking vformat.
+ int idx=0;
+ do {
+ value=b_vformat_attribute_get_nth_value(attr,idx++);
+ if(value) {
+ ret.push_back(value);
+ }
+ } while(value);
+ }
+ }
+
+ if( needs_freeing )
+ g_free((char *)value);
+
+ return ret;
+}
+
vAttr vBase::GetAttrObj(const char *attrname, int nth, const char *block)
{
Trace trace("vBase::GetAttrObj");
@@ -299,3 +331,50 @@ vAttr vBase::GetAttrObj(const char *attrname, int nth, const char *block)
return vAttr(b_vformat_find_attribute(m_format, attrname, nth, block));
}
+std::vector<std::string> vBase::Tokenize(const std::string& str, const char delim)
+{
+ std::vector<std::string> tokens;
+ std::string::size_type delimPos = 0, tokenPos = 0, pos = 0;
+
+ if(str.length()<1) {
+ return tokens;
+ }
+
+ while(1) {
+ delimPos = str.find_first_of(delim, pos);
+ tokenPos = str.find_first_not_of(delim, pos);
+
+ if(std::string::npos != delimPos) {
+ if(std::string::npos != tokenPos) {
+ if(tokenPos<delimPos) {
+ tokens.push_back(str.substr(pos,delimPos-pos));
+ } else {
+ tokens.push_back("");
+ }
+ } else {
+ tokens.push_back("");
+ }
+ pos = delimPos+1;
+ } else {
+ if(std::string::npos != tokenPos){
+ tokens.push_back(str.substr(pos));
+ } else {
+ tokens.push_back("");
+ }
+ break;
+ }
+ }
+ return tokens;
+}
+
+std::string vBase::ToStringList(const std::vector<std::string>& list, const char delim)
+{
+ std::string str;
+ for(unsigned int idx=0;idx<list.size();idx++) {
+ if(idx) {
+ str+=delim;
+ }
+ str += list[idx];
+ }
+ return str;
+}
\ No newline at end of file
diff --git a/opensync-plugin-0.4x/src/vbase.h b/opensync-plugin-0.4x/src/vbase.h
index e8cfd6c..3acf32c 100644
--- a/opensync-plugin-0.4x/src/vbase.h
+++ b/opensync-plugin-0.4x/src/vbase.h
@@ -23,6 +23,7 @@
#define __BARRY_SYNC_VBASE_H__
#include <string>
+#include <vector>
#include <stdexcept>
#include "vformat.h"
@@ -193,7 +194,12 @@ protected:
void AddParam(vAttrPtr &attr, const char *name, const char *value);
std::string GetAttr(const char *attrname, const char *block = 0);
+ std::vector<std::string> GetValueVector(const char * attrname, const char * block=0);
vAttr GetAttrObj(const char *attrname, int nth = 0, const char *block = 0);
+
+ std::vector<std::string> Tokenize(const std::string& str, const char delim=',');
+ std::string ToStringList(const std::vector<std::string>& list, const char delim=',');
+
};
#endif
diff --git a/opensync-plugin-0.4x/src/vevent.cc b/opensync-plugin-0.4x/src/vevent.cc
index dba4d0d..96dd29d 100644
--- a/opensync-plugin-0.4x/src/vevent.cc
+++ b/opensync-plugin-0.4x/src/vevent.cc
@@ -59,43 +59,6 @@ unsigned short vCalendar::GetWeekDayIndex(const char *dayname)
return 0;
}
-std::vector<std::string> vCalendar::GetDOWList(const std::string& str)
-{
- std::vector<std::string> tokens;
- std::string::size_type delimPos = 0, tokenPos = 0, pos = 0;
-
- if(str.length()<1) {
- return tokens;
- }
-
- while(1) {
- delimPos = str.find_first_of(',', pos);
- tokenPos = str.find_first_not_of(',', pos);
-
- if(std::string::npos != delimPos) {
- if(std::string::npos != tokenPos) {
- if(tokenPos<delimPos) {
- tokens.push_back(str.substr(pos,delimPos-pos));
- } else {
- tokens.push_back("");
- }
- } else {
- tokens.push_back("");
- }
- pos = delimPos+1;
- } else {
- if(std::string::npos != tokenPos){
- tokens.push_back(str.substr(pos));
- } else {
- tokens.push_back("");
- }
- break;
- }
- }
- return tokens;
-}
-
-
unsigned short vCalendar::GetMonthWeekNumFromBYDAY(const std::string& ByDay)
{
return atoi(ByDay.substr(0,ByDay.length()-2).c_str());
@@ -356,7 +319,7 @@ void vCalendar::RecurToBarryCal(vAttr& rrule, time_t starttime)
cal.RecurringType=Calendar::Week;
// we must have a dayofweek entry
if(args.find(string("BYDAY"))!=args.end()) {
- std::vector<std::string> v=GetDOWList(args["BYDAY"]);
+ std::vector<std::string> v=Tokenize(args["BYDAY"]);
// iterate along our vector and convert
for(unsigned int idx=0;idx<v.size();idx++) {
cal.WeekDays|=pmap[v[idx]];
diff --git a/opensync-plugin-0.4x/src/vevent.h b/opensync-plugin-0.4x/src/vevent.h
index 0e8423e..1ff681d 100644
--- a/opensync-plugin-0.4x/src/vevent.h
+++ b/opensync-plugin-0.4x/src/vevent.h
@@ -48,7 +48,6 @@ class vCalendar : public vBase
static const char *WeekDays[7];
- std::vector<std::string> GetDOWList(const std::string& str);
unsigned short GetMonthWeekNumFromBYDAY(const std::string& ByDay);
unsigned short GetWeekDayIndexFromBYDAY(const std::string& ByDay);
diff --git a/opensync-plugin-0.4x/src/vtodo.cc b/opensync-plugin-0.4x/src/vtodo.cc
index 1cb17a1..8261431 100644
--- a/opensync-plugin-0.4x/src/vtodo.cc
+++ b/opensync-plugin-0.4x/src/vtodo.cc
@@ -101,6 +101,7 @@ const std::string& vTodo::ToTask(const Barry::Task &task)
AddAttr(NewAttr("SEQUENCE", "0"));
AddAttr(NewAttr("SUMMARY", task.Summary.c_str()));
AddAttr(NewAttr("DESCRIPTION", task.Notes.c_str()));
+ AddAttr(NewAttr("CATEGORIES",ToStringList(task.Categories).c_str()));
// Status
if (task.StatusFlag == Barry::Task::InProgress)
@@ -190,6 +191,7 @@ const Barry::Task& vTodo::ToBarry(const char *vtodo, uint32_t RecordId)
string due = GetAttr("DUE", "/vtodo");
trace.logf("DUE attr retrieved: %s", due.c_str());
+
//
// Now, run checks and convert into Barry object
//
@@ -209,6 +211,10 @@ const Barry::Task& vTodo::ToBarry(const char *vtodo, uint32_t RecordId)
Barry::Task &rec = m_BarryTask;
rec.SetIds(Barry::Task::GetDefaultRecType(), RecordId);
+ // Categories
+
+ rec.Categories=GetValueVector("CATEGORIES","/vtodo");
+
// SUMMARY & DESCRIPTION fields
rec.Summary = summary;
rec.Notes = notes;
diff --git a/src/r_task.cc b/src/r_task.cc
index cc821ae..f2b376d 100644
--- a/src/r_task.cc
+++ b/src/r_task.cc
@@ -105,7 +105,7 @@ static FieldLink<Task> TaskFieldLinks[] = {
{ TSKFC_START_TIME, "Start Time", 0, 0, 0, 0, &Task::StartTime, 0, 0, false },
{ TSKFC_DUE_TIME, "Due Time", 0, 0, 0, 0, &Task::DueTime, 0, 0, false },
{ TSKFC_ALARM_TIME, "Alarm Time", 0, 0, 0, 0, &Task::AlarmTime, 0, 0, false },
- { TSKFC_CATEGORIES, "Categories", 0, 0, &Task::Categories, 0, 0, 0, 0, false },
+// { TSKFC_CATEGORIES, "Categories", 0, 0, &Task::Categories, 0, 0, 0, 0, false },
{ TSKFC_END, "End of List", 0, 0, 0, 0, 0, 0, 0, false },
};
@@ -202,8 +202,16 @@ const unsigned char* Task::ParseField(const unsigned char *begin,
AlarmType = AlarmProto2Rec(field->u.raw[0]);
}
return begin;
+
+ case TSKFC_CATEGORIES:
+ {
+ std::string catstring = ParseFieldString(field);
+ if( ic )
+ catstring = ic->FromBB(catstring);
+ CategoryStr2List(catstring,Categories);
+ }
+ return begin;
}
-
// base class handles recurring data
if( RecurBase::ParseField(field->type, field->u.raw, btohs(field->size), ic) )
return begin;
@@ -261,6 +269,14 @@ void Task::BuildFields(Data &data, size_t &offset, const IConverter *ic) const
if( TimeZoneValid )
BuildField(data, offset, TSKFC_TIMEZONE_CODE, TimeZoneCode);
+ // Categories
+
+ if(Categories.size()>0) {
+ string store;
+ CategoryList2Str(Categories, store);
+ BuildField(data, offset, TSKFC_CATEGORIES, ic ? ic->ToBB(store) : store);
+ }
+
// cycle through the type table
for( FieldLink<Task> *b = TaskFieldLinks;
b->type != TSKFC_END;
@@ -432,5 +448,55 @@ void Task::Dump(std::ostream &os) const
os << "\n\n";
}
+void Task::CategoryStr2List(const std::string &str,Barry::CategoryList &list)
+{
+ // start fresh
+
+ list.clear();
+
+ if( !str.size() )
+ return;
+
+ // parse the comma-delimited string to a list, stripping away
+ // any white space around each category name
+ string::size_type start = 0, end = 0, delim = str.find(',', start);
+ while( start != string::npos ) {
+ if( delim == string::npos )
+ end = str.size() - 1;
+ else
+ end = delim - 1;
+
+ // strip surrounding whitespace
+ while( str[start] == ' ' )
+ start++;
+ while( end && str[end] == ' ' )
+ end--;
+
+ if( start <= end ) {
+ string token = str.substr(start, end-start+1);
+ list.push_back(token);
+ }
+
+ // next
+ start = delim;
+ if( start != string::npos )
+ start++;
+ delim = str.find(',', start);
+ }
+}
+
+void Task::CategoryList2Str(const Barry::CategoryList &list, std::string &str)
+{
+ str.clear();
+
+ Barry::CategoryList::const_iterator i = list.begin();
+ for( ; i != list.end(); ++i ) {
+ if( str.size() )
+ str += ",";
+ str += *i;
+ }
+}
+
+
} // namespace Barry
diff --git a/src/r_task.h b/src/r_task.h
index c6b9a54..41decb1 100644
--- a/src/r_task.h
+++ b/src/r_task.h
@@ -35,6 +35,8 @@ namespace Barry {
// forward declarations
class IConverter;
+typedef std::vector<std::string> CategoryList;
+
class BXEXPORT Task : public RecurBase
{
public:
@@ -46,7 +48,7 @@ public:
uint8_t TaskType;
std::string Summary;
std::string Notes;
- std::string Categories;
+ CategoryList Categories;
std::string UID;
time_t StartTime;
@@ -95,6 +97,12 @@ protected:
static StatusFlagType StatusProto2Rec(uint8_t s);
static uint8_t StatusRec2Proto(StatusFlagType s);
+
+ // these two are common with Contact and duplicated. TODO: Should really make them
+ // functions, or hive them off up the object hierarchy. But there is no hierarchy
+
+ static void CategoryStr2List(const std::string &str, Barry::CategoryList &list);
+ static void CategoryList2Str(const Barry::CategoryList &list, std::string &str);
public:
Task();
------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
Barry-devel mailing list
Barry-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/barry-devel