206 lines
6.1 KiB
C++
206 lines
6.1 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// taskwarrior - a command line task list manager.
|
|
//
|
|
// Copyright 2006-2012, Paul Beckingham, Federico Hernandez.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included
|
|
// in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
// SOFTWARE.
|
|
//
|
|
// http://www.opensource.org/licenses/mit-license.php
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define L10N // Localization complete.
|
|
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <algorithm>
|
|
#include <sys/types.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <pwd.h>
|
|
#include <time.h>
|
|
|
|
#include <Context.h>
|
|
#include <Directory.h>
|
|
#include <File.h>
|
|
#include <Date.h>
|
|
#include <Duration.h>
|
|
#include <ViewText.h>
|
|
#include <text.h>
|
|
#include <util.h>
|
|
#include <i18n.h>
|
|
#include <main.h>
|
|
|
|
static void countTasks (const std::vector <Task>&, const std::string&, int&, int&);
|
|
|
|
extern Context context;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
std::string getFullDescription (Task& task, const std::string& report)
|
|
{
|
|
std::string desc = task.get ("description");
|
|
std::string annotationDetails;
|
|
|
|
std::map <std::string, std::string> annotations;
|
|
task.getAnnotations (annotations);
|
|
|
|
if (annotations.size () != 0)
|
|
{
|
|
std::string annotationDetails = context.config.get ("report." + report + ".annotations");
|
|
if (annotationDetails == "")
|
|
annotationDetails = context.config.get ("annotations");
|
|
if (report == "info")
|
|
annotationDetails = "full";
|
|
|
|
if (annotationDetails == "none")
|
|
{
|
|
desc = "+" + desc;
|
|
}
|
|
else if (annotationDetails == "sparse")
|
|
{
|
|
if (annotations.size () > 1)
|
|
desc = "+" + desc;
|
|
|
|
std::map <std::string, std::string>::iterator i = annotations.begin ();
|
|
|
|
Date dt (strtol (i->first.substr (11).c_str (), NULL, 10));
|
|
std::string format = context.config.get ("dateformat.annotation");
|
|
if (format == "")
|
|
format = context.config.get ("dateformat");
|
|
std::string when = dt.toString (format);
|
|
desc += "\n" + when + " " + i->second;
|
|
}
|
|
else
|
|
{
|
|
std::map <std::string, std::string>::iterator anno;
|
|
for (anno = annotations.begin (); anno != annotations.end (); ++anno)
|
|
{
|
|
Date dt (strtol (anno->first.substr (11).c_str (), NULL, 10));
|
|
std::string format = context.config.get ("dateformat.annotation");
|
|
if (format == "")
|
|
format = context.config.get ("dateformat");
|
|
std::string when = dt.toString (format);
|
|
desc += "\n" + when + " " + anno->second;
|
|
}
|
|
}
|
|
}
|
|
|
|
return desc;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
std::string getDueDate (Task& task, const std::string& format)
|
|
{
|
|
std::string due = task.get ("due");
|
|
if (due.length ())
|
|
{
|
|
Date d (atoi (due.c_str ()));
|
|
due = d.toString (format);
|
|
}
|
|
|
|
return due;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
std::string onProjectChange (Task& task, bool scope /* = true */)
|
|
{
|
|
std::stringstream msg;
|
|
std::string project = task.get ("project");
|
|
|
|
if (project != "")
|
|
{
|
|
if (scope)
|
|
msg << format (STRING_HELPER_PROJECT_CHANGE, project)
|
|
<< " ";
|
|
|
|
// Count pending and done tasks, for this project.
|
|
int count_pending = 0;
|
|
int count_done = 0;
|
|
std::vector <Task> all = context.tdb2.all_tasks ();
|
|
countTasks (all, project, count_pending, count_done);
|
|
|
|
// count_done count_pending percentage
|
|
// ---------- ------------- ----------
|
|
// 0 0 0%
|
|
// >0 0 100%
|
|
// 0 >0 0%
|
|
// >0 >0 calculated
|
|
int percentage = 0;
|
|
if (count_done == 0)
|
|
percentage = 0;
|
|
else if (count_pending == 0)
|
|
percentage = 100;
|
|
else
|
|
percentage = (count_done * 100 / (count_done + count_pending));
|
|
|
|
msg << format (STRING_HELPER_PROJECT_COMPL, project, percentage)
|
|
<< " "
|
|
<< format (STRING_HELPER_PROJECT_REM, count_pending, count_pending + count_done)
|
|
<< "\n";
|
|
}
|
|
|
|
return msg.str ();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
std::string onProjectChange (Task& task1, Task& task2)
|
|
{
|
|
std::string messages = onProjectChange (task1);
|
|
messages += onProjectChange (task2);
|
|
|
|
return messages;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
static void countTasks (
|
|
const std::vector <Task>& all,
|
|
const std::string& project,
|
|
int& count_pending,
|
|
int& count_done)
|
|
{
|
|
std::vector <Task>::const_iterator it;
|
|
for (it = all.begin (); it != all.end (); ++it)
|
|
{
|
|
if (it->get ("project") == project)
|
|
{
|
|
switch (it->getStatus ())
|
|
{
|
|
case Task::pending:
|
|
case Task::waiting:
|
|
++count_pending;
|
|
break;
|
|
|
|
case Task::completed:
|
|
++count_done;
|
|
break;
|
|
|
|
case Task::deleted:
|
|
case Task::recurring:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|