package SyncToDo; # Version 0.204 - 11/15/99 # SyncToDo conduit for PilotManager # v0.200 - 4/13/99, v0.202 - 4/14/99, v0.203 - 4/21/99 # Derek R. Pizzagoni, derekp@sbei.com # http://home.pacbell.net/pizz/todo_project.html # Major contributions by Mukundan Parthasarathy use Time::Local; use PilotSync; use Tk; my ($gConfigDlg); my ($VERSION) = ('0.204'); my ($ToDoFields) = (['id', 'category', 'private', 'due', 'indefinite', 'priority', 'complete', 'description', 'note']); my ($RCFILE); sub conduitInit { $RCFILE = "SyncToDo/SyncToDo.prefs"; &loadPrefs; $PREFS->{'file'} = "$ENV{HOME}/.pilotmgr/SyncToDo/.todoDB" unless (defined $PREFS->{'file'}); } sub loadPrefs { $PREFS = {}, return unless (-r "$RCFILE"); use vars qw($PREFS); do "$RCFILE"; } sub conduitQuit { &savePrefs; } sub savePrefs { $Data::Dumper::Purity = 1; $Data::Dumper::Deepcopy = 1; $Data::Dumper::Indent = 0; if (open(FD, ">$RCFILE")) { print FD Data::Dumper->Dumpxs([$PREFS], ['PREFS']), "1;\n"; close FD; } else { PilotMgr::msg("Unable to save preferences to $RCFILE!"); } } sub conduitInfo { return { 'database' => { 'name' => 'ToDoDB', 'creator' => 'ToDo', 'type' => 'Data', 'flags' => 0, 'version' => 0, }, 'version' => $VERSION, 'author' => 'Derek R. Pizzagoni', 'email' => 'derekp@sbei.com' }; } sub conduitConfigure { my ($this, $wm) = @_; my ($frame, $obj, $subfr); unless (defined $gConfigDlg and $gConfigDlg->Exists) { $gConfigDlg = $wm->Toplevel(-title => "Configuring SyncToDo"); $gConfigDlg->withdraw; $gConfigDlg->transient($wm); $frame = $gConfigDlg->Frame(-relief => 'ridge', -bd => 2); $frame->Label(-text => "SyncToDo v$VERSION\nCopyright (C) 1999\n" . &conduitInfo->{'author'} . ", " . &conduitInfo->{'email'} . "\n")->pack; $subfr = $frame->Frame; $obj = $subfr->Label(-text => "Datafile:", -width => 10); $obj->pack(-side => 'left', -anchor => 'e'); $gFileEntry = $subfr->Entry(-relief => 'sunken', -width => 40); $gFileEntry->pack(-fill => 'x', -expand => 1); $subfr->pack(-fill => 'x', -expand => 1); $frame->Label(-text => "\nPlease be careful when changing this filename.\n" . "If you have sync'd before, and you change this filename,\n" . "move your datafile to the new filename before you sync\n" . "again, or all records on the Pilot will be deleted!\n")->pack; $obj = TkUtils::Button($frame, 'Dismiss', sub{ $gConfigDlg->withdraw }); $obj->pack; $frame->pack(-fill => 'x', -expand => 1, -anchor => 'n'); PilotMgr::setColors($gConfigDlg); } $gFileEntry->configure(-textvariable => \$PREFS->{'file'}); $gConfigDlg->Popup(-popanchor => 'c', -overanchor => 'c', -popover => $wm); } sub conduitSync { my ($this, $dlp, $info) = @_; PilotSync::doSync( $dlp, &conduitInfo->{'database'}, $ToDoFields, ['categoryName', 'categoryID'], 'todo_id', "$ENV{HOME}/.pilotmgr/SyncToDo/todo.db", $PREFS->{'file'}, sub{ return $_[0]->{'description'}; }, \&readFile, \&writeFile, \&newToDoId, undef, undef, undef) } sub readFile { my ($TODOFILE) = @_; my ($db, $reclist, $rec, $i) = ({ 'NEXT_ID'=>0, '__RECORDS' => [], '__APPINFO' => { 'categoryName' => [], 'categoryID' => [] }}); my $note; $reclist = $db->{'__RECORDS'}; open(FD, "<$TODOFILE") || return $db; for ($i=0; $i < 16; $i++) { chop($rec = ); push(@{$db->{'__APPINFO'}->{'categoryName'}}, $rec); } for ($i=0; $i < 16; $i++) { chop($rec = ); push(@{$db->{'__APPINFO'}->{'categoryID'}}, $rec); } chop($db->{NEXT_ID} = ); while (!eof(FD)) { my $nextline = ""; $rec = {}; chop($rec->{todo_id} = ); chop($rec->{name} = ); chop($rec->{id} = ); chop($rec->{priority} = ); chop($rec->{category} = ); chop($rec->{private} = ); my ($pilotdate); chop($pilotdate = ); $rec->{due} = &DatePerlToPilot($pilotdate); chop($rec->{complete} = ); chop($rec->{indefinite} = ); chop($rec->{description} = ); $note = ; until ($nextline eq "-*-*-RECORD-SPLITTER-*-*-\n") { $note = $note . $nextline; $nextline = ; } chop($rec->{note} = $note); push(@$reclist, $rec); $db->{$rec->{todo_id}} = $#$reclist; } close(FD); return $db; } sub newToDoId { my ($db) = @_; return $db->{NEXT_ID}++; } sub writeFile { my ($TODOFILE, $db) = @_; my ($rec, $i); unless (open(FD, ">$TODOFILE")) { PilotMgr::msg("Unable to write to $TODOFILE. Help!"); return; } for ($i=0; $i < 16; $i++) { print FD $db->{'__APPINFO'}->{'categoryName'}->[$i], "\n"; } for ($i=0; $i < 16; $i++) { print FD $db->{'__APPINFO'}->{'categoryID'}->[$i], "\n"; } print FD $db->{NEXT_ID},"\n"; foreach $rec (@{$db->{'__RECORDS'}}) { print FD $rec->{todo_id},"\n"; if (defined($rec->{name})) { print FD "$rec->{name}\n"; } else { print FD "0\n"; } if (defined($rec->{id})) { print FD "$rec->{id}\n"; } else { print FD "0\n"; } if (defined($rec->{priority})) { print FD "$rec->{priority}\n"; } else { print FD "0\n"; } if (defined($rec->{category})) { print FD "$rec->{category}\n"; } else { print FD "0\n"; } if (defined($rec->{private})) { print FD "$rec->{private}\n"; } else { print FD "0\n"; } if (defined($rec->{due})) { my $textdate = &DatePilotToPerl($rec->{due}); print FD "$textdate\n"; } else { print FD "0\n"; } if (defined($rec->{complete})) { print FD "$rec->{complete}\n"; } else { print FD "0\n"; } if (defined($rec->{indefinite})) { print FD "$rec->{indefinite}\n"; } else { print FD "0\n"; } if (defined($rec->{description})) { print FD "$rec->{description}\n"; } else { print FD "0\n"; } if (defined($rec->{note})) { print FD "$rec->{note}\n"; print FD "-*-*-RECORD-SPLITTER-*-*-\n"; } else { print FD "0\n"; print FD "-*-*-RECORD-SPLITTER-*-*-\n"; } } close(FD); } # This grabs the pilot's date array and converts it to text version of MM/DD/YY. sub DatePilotToPerl { my ($s,$m,$h, $mday,$mon,$year) = @_; my ($date); if (ref $s eq 'ARRAY') { ($s,$m,$h, $mday,$mon,$year) = @$s; } if ($mday == 0) { $date = 0; } else { $mon++; $year = $year + 1900; $date = "$mon/$mday/$year"; } return $date; } # This grabs the text version of the date MM/DD/YY and converts to pilot array. sub DatePerlToPilot { my ($date) = @_; if (! $date) { return 0; } my ($m,$d,$y) = split(/\//, $date); $y = $y - 1900; $m--; my ($stuff1) = [0,0,0,$d,$m,$y]; $stuff1; } 1;