Merge branch 'recurrence' into 2.6.0

This commit is contained in:
Paul Beckingham 2017-01-07 12:29:11 -05:00
commit 4e7576cb79
65 changed files with 652 additions and 484 deletions

View file

@ -30,6 +30,9 @@
(thanks to Flavio Poletti).
- TW-1857 Change Task::get call to the more efficient Task::has
(thanks to Zachary Manning).
- TW1858 Change signature for dependencyGetBlocked
- TW-1859 Change signature of Task::getTags
- TW-1860 Change signature of Task::getAnnotations
- TW-1873 Specify different path to extensions/hooks directory
(thanks to Eli).
- TW-1878 uuids subcommand produces a space-delimited list, not comma-delimited

1
NEWS
View file

@ -20,6 +20,7 @@ Newly Deprecated Features in Taskwarrior 2.6.0
- The use of alternate Boolean configuration settings is deprecated. Use values
"0" for off, and "1" for on. Avoid used of "on", "off", "true", "t",
"false", "f", "yes", "y", "no", "n".
- The 'PARENT' and 'CHILD' virtual tags are replaced by 'TEMPLATE' and 'INSTANCE'.
Removed Features in 2.6.0

View file

@ -677,15 +677,16 @@ are:
ANNOTATED Matches if the task has annotations
BLOCKED Matches if the task is blocked
BLOCKING Matches if the task is blocking
CHILD Matches if the task has a parent
CHILD Matches if the task has a parent (deprecated in 2.6.0)
COMPLETED Matches if the task has completed status
DELETED Matches if the task has deleted status
DUE Matches if the task is due
INSTANCE Matches if the task is a recurrent instance
LATEST Matches if the task is the newest added task
MONTH Matches if the task is due this month
ORPHAN Matches if the task has any orphaned UDA values
OVERDUE Matches if the task is overdue
PARENT Matches if the task is a parent
PARENT Matches if the task is a parent (deprecated in 2.6.0)
PENDING Matches if the task has pending status
PRIORITY Matches if the task has a priority
PROJECT Matches if the task has a project
@ -693,6 +694,7 @@ are:
READY Matches if the task is actionable
SCHEDULED Matches if the task is scheduled
TAGGED Matches if the task has tags
TEMPLATE Matches if the task is a recurrence template
TODAY Matches if the task is due today
TOMORROW Matches if the task is due sometime tomorrow
UDA Matches if the task has any UDA values

View file

@ -300,8 +300,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
if (ref.data.size () && size == 3 && elements[0] == "annotations")
{
std::map <std::string, std::string> annos;
ref.getAnnotations (annos);
auto annos = ref.getAnnotations ();
int a = strtol (elements[1].c_str (), NULL, 10);
int count = 0;
@ -329,8 +328,7 @@ bool getDOM (const std::string& name, const Task& task, Variant& value)
if (ref.data.size () && size == 4 && elements[0] == "annotations" && elements[2] == "entry")
{
std::map <std::string, std::string> annos;
ref.getAnnotations (annos);
auto annos = ref.getAnnotations ();
int a = strtol (elements[1].c_str (), NULL, 10);
int count = 0;

View file

@ -528,10 +528,7 @@ void TF2::dependency_scan ()
{
if (left.has ("depends"))
{
std::vector <std::string> deps;
left.getDependencies (deps);
for (auto& dep : deps)
for (auto& dep : left.getDependencyUUIDs ())
{
for (auto& right : _tasks)
{

View file

@ -1081,13 +1081,14 @@ void Task::removeAnnotations ()
}
////////////////////////////////////////////////////////////////////////////////
void Task::getAnnotations (std::map <std::string, std::string>& annotations) const
std::map <std::string, std::string> Task::getAnnotations () const
{
annotations.clear ();
std::map <std::string, std::string> a;
for (auto& ann : data)
if (! ann.first.compare (0, 11, "annotation_", 11))
annotations.insert (ann);
a.insert (ann);
return a;
}
////////////////////////////////////////////////////////////////////////////////
@ -1185,35 +1186,33 @@ void Task::removeDependency (int id)
}
////////////////////////////////////////////////////////////////////////////////
void Task::getDependencies (std::vector <int>& all) const
std::vector <int> Task::getDependencyIDs () const
{
auto deps = split (get ("depends"), ',');
all.clear ();
for (auto& dep : deps)
std::vector <int> all;
for (auto& dep : split (get ("depends"), ','))
all.push_back (context.tdb2.pending.id (dep));
return all;
}
////////////////////////////////////////////////////////////////////////////////
void Task::getDependencies (std::vector <std::string>& all) const
std::vector <std::string> Task::getDependencyUUIDs () const
{
all = split (get ("depends"), ',');
return split (get ("depends"), ',');
}
////////////////////////////////////////////////////////////////////////////////
void Task::getDependencies (std::vector <Task>& all) const
std::vector <Task> Task::getDependencyTasks () const
{
std::vector <std::string> deps = split (get ("depends"), ',');
all.clear ();
for (auto& dep : deps)
std::vector <Task> all;
for (auto& dep : split (get ("depends"), ','))
{
Task task;
context.tdb2.get (dep, task);
all.push_back (task);
}
return all;
}
#endif
@ -1260,11 +1259,13 @@ bool Task::hasTag (const std::string& tag) const
#endif
if (tag == "ACTIVE") return has ("start");
if (tag == "SCHEDULED") return has ("scheduled");
if (tag == "CHILD") return has ("parent");
if (tag == "CHILD") return has ("parent"); // 2017-01-07: Deprecated in 2.6.0
if (tag == "INSTANCE") return has ("template");
if (tag == "UNTIL") return has ("until");
if (tag == "ANNOTATED") return hasAnnotations ();
if (tag == "TAGGED") return has ("tags");
if (tag == "PARENT") return has ("mask");
if (tag == "PARENT") return has ("mask"); // 2017-01-07: Deprecated in 2.6.0
if (tag == "TEMPLATE") return has ("last");
if (tag == "WAITING") return get ("status") == "waiting";
if (tag == "PENDING") return get ("status") == "pending";
if (tag == "COMPLETED") return get ("status") == "completed";
@ -1313,9 +1314,9 @@ void Task::addTags (const std::vector <std::string>& tags)
}
////////////////////////////////////////////////////////////////////////////////
void Task::getTags (std::vector<std::string>& tags) const
std::vector <std::string> Task::getTags () const
{
tags = split (get ("tags"), ',');
return split (get ("tags"), ',');
}
////////////////////////////////////////////////////////////////////////////////
@ -1336,12 +1337,15 @@ void Task::removeTag (const std::string& tag)
#ifdef PRODUCT_TASKWARRIOR
////////////////////////////////////////////////////////////////////////////////
// A UDA Orphan is an attribute that is not represented in context.columns.
void Task::getUDAOrphans (std::vector <std::string>& names) const
std::vector <std::string> Task::getUDAOrphanUUIDs () const
{
std::vector <std::string> orphans;
for (auto& it : data)
if (it.first.compare (0, 11, "annotation_", 11) != 0)
if (context.columns.find (it.first) == context.columns.end ())
names.push_back (it.first);
orphans.push_back (it.first);
return orphans;
}
////////////////////////////////////////////////////////////////////////////////
@ -1354,8 +1358,7 @@ void Task::substitute (
// Get the data to modify.
std::string description = get ("description");
std::map <std::string, std::string> annotations;
getAnnotations (annotations);
auto annotations = getAnnotations ();
// Count the changes, so we know whether to proceed to annotations, after
// modifying description.
@ -1864,19 +1867,16 @@ float Task::urgency ()
////////////////////////////////////////////////////////////////////////////////
float Task::urgency_inherit () const
{
float v = FLT_MIN;
#ifdef PRODUCT_TASKWARRIOR
// Calling dependencyGetBlocked is rather expensive.
// It is called recursively for each dependency in the chain here.
std::vector <Task> blocked;
#ifdef PRODUCT_TASKWARRIOR
dependencyGetBlocked (*this, blocked);
#endif
float v = FLT_MIN;
for (auto& task : blocked)
for (auto& task : dependencyGetBlocked (*this))
{
// Find highest urgency in all blocked tasks.
v = std::max (v, task.urgency ());
}
#endif
return v;
}

View file

@ -125,11 +125,11 @@ public:
bool hasTag (const std::string&) const;
void addTag (const std::string&);
void addTags (const std::vector <std::string>&);
void getTags (std::vector<std::string>&) const;
std::vector <std::string> getTags () const;
void removeTag (const std::string&);
bool hasAnnotations () const;
void getAnnotations (std::map <std::string, std::string>&) const;
std::map <std::string, std::string> getAnnotations () const;
void setAnnotations (const std::map <std::string, std::string>&);
void addAnnotation (const std::string&);
void removeAnnotations ();
@ -141,11 +141,11 @@ public:
#ifdef PRODUCT_TASKWARRIOR
void removeDependency (int);
void removeDependency (const std::string&);
void getDependencies (std::vector <int>&) const;
void getDependencies (std::vector <std::string>&) const;
void getDependencies (std::vector <Task>&) const;
std::vector <int> getDependencyIDs () const;
std::vector <std::string> getDependencyUUIDs () const;
std::vector <Task> getDependencyTasks () const;
void getUDAOrphans (std::vector <std::string>&) const;
std::vector <std::string> getUDAOrphanUUIDs () const;
void substitute (const std::string&, const std::string&, const std::string&);
#endif
@ -170,17 +170,17 @@ private:
const std::string decode (const std::string&) const;
public:
float urgency_project () const;
float urgency_active () const;
float urgency_scheduled () const;
float urgency_waiting () const;
float urgency_blocked () const;
float urgency_inherit () const;
float urgency_project () const;
float urgency_active () const;
float urgency_scheduled () const;
float urgency_waiting () const;
float urgency_blocked () const;
float urgency_inherit () const;
float urgency_annotations () const;
float urgency_tags () const;
float urgency_due () const;
float urgency_blocking () const;
float urgency_age () const;
float urgency_tags () const;
float urgency_due () const;
float urgency_blocking () const;
float urgency_age () const;
};
#endif

View file

@ -874,10 +874,7 @@ bool Variant::operator_match (const Variant& other, const Task& task) const
// in the annotations.
if (left.source () == "description")
{
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
for (auto& a : annotations)
for (auto& a : task.getAnnotations ())
if (r.match (a.second))
return true;
}
@ -909,10 +906,7 @@ bool Variant::operator_match (const Variant& other, const Task& task) const
// in the annotations.
if (left.source () == "description")
{
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
for (auto& a : annotations)
for (auto& a : task.getAnnotations ())
if (find (a.second, pattern, searchCaseSensitive) != std::string::npos)
return true;
}

View file

@ -14,16 +14,18 @@ set (columns_SRCS Column.cpp Column.h
ColEntry.cpp ColEntry.h
ColID.cpp ColID.h
ColIMask.cpp ColIMask.h
ColLast.cpp ColLast.h
ColMask.cpp ColMask.h
ColModified.cpp ColModified.h
ColParent.cpp ColParent.h
ColProject.cpp ColProject.h
ColRecur.cpp ColRecur.h
ColRType.cpp ColRType.h
ColScheduled.cpp ColScheduled.h
ColStart.cpp ColStart.h
ColStatus.cpp ColStatus.h
ColString.cpp ColString.h
ColTags.cpp ColTags.h
ColTemplate.cpp ColTemplate.h
ColTypeDate.cpp ColTypeDate.h
ColTypeDuration.cpp ColTypeDuration.h
ColTypeNumeric.cpp ColTypeNumeric.h

View file

@ -58,7 +58,7 @@ ColumnDepends::ColumnDepends ()
// Note that you can not determine which gets called first.
void ColumnDepends::setStyle (const std::string& value)
{
_style = value;
Column::setStyle (value);
if (_style == "indicator" && _label == STRING_COLUMN_LABEL_DEP) _label = _label.substr (0, context.config.get ("dependency.indicator").length ());
else if (_style == "count" && _label == STRING_COLUMN_LABEL_DEP) _label = STRING_COLUMN_LABEL_DEP_S;
@ -68,26 +68,25 @@ void ColumnDepends::setStyle (const std::string& value)
// Set the minimum and maximum widths for the value.
void ColumnDepends::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
std::vector <Task> blocking;
dependencyGetBlocking (task, blocking);
if (_style == "indicator")
minimum = maximum = 0;
if (task.has (_name))
{
if (task.has ("depends"))
minimum = maximum = utf8_width (context.config.get ("dependency.indicator"));
else
minimum = maximum = 0;
}
else if (_style == "count")
{
minimum = maximum = 2 + format ((int) blocking.size ()).length ();
}
else if (_style == "default" ||
_style == "list")
{
minimum = maximum = 0;
if (task.has ("depends"))
if (_style == "indicator")
{
minimum = maximum = utf8_width (context.config.get ("dependency.indicator"));
}
else if (_style == "count")
{
minimum = maximum = 2 + format ((int) dependencyGetBlocking (task).size ()).length ();
}
else if (_style == "default" ||
_style == "list")
{
minimum = maximum = 0;
auto blocking = dependencyGetBlocking (task);
std::vector <int> blocking_ids;
for (auto& i : blocking)
blocking_ids.push_back (i.id);
@ -104,8 +103,6 @@ void ColumnDepends::measure (Task& task, unsigned int& minimum, unsigned int& ma
}
}
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
////////////////////////////////////////////////////////////////////////////////
@ -118,30 +115,31 @@ void ColumnDepends::render (
if (task.has (_name))
{
if (_style == "indicator")
renderStringRight (lines, width, color, context.config.get ("dependency.indicator"));
else
{
std::vector <Task> blocking;
dependencyGetBlocking (task, blocking);
renderStringRight (lines, width, color, context.config.get ("dependency.indicator"));
}
if (_style == "count")
renderStringRight (lines, width, color, '[' + format (static_cast <int>(blocking.size ())) + ']');
else if (_style == "count")
{
renderStringRight (lines, width, color, '[' + format (static_cast <int>(dependencyGetBlocking (task).size ())) + ']');
}
else if (_style == "default" ||
_style == "list")
{
std::vector <int> blocking_ids;
for (const auto& t : blocking)
blocking_ids.push_back (t.id);
else if (_style == "default" ||
_style == "list")
{
auto blocking = dependencyGetBlocking (task);
auto combined = join (" ", blocking_ids);
std::vector <int> blocking_ids;
for (const auto& t : blocking)
blocking_ids.push_back (t.id);
std::vector <std::string> all;
wrapText (all, combined, width, _hyphenate);
auto combined = join (" ", blocking_ids);
for (const auto& i : all)
renderStringLeft (lines, width, color, i);
}
std::vector <std::string> all;
wrapText (all, combined, width, _hyphenate);
for (const auto& i : all)
renderStringLeft (lines, width, color, i);
}
}
}

View file

@ -40,16 +40,17 @@ extern Context context;
////////////////////////////////////////////////////////////////////////////////
ColumnDescription::ColumnDescription ()
{
_name = "description";
_style = "combined";
_label = STRING_COLUMN_LABEL_DESC;
_name = "description";
_style = "combined";
_label = STRING_COLUMN_LABEL_DESC;
_modifiable = true;
_styles = {"combined",
"desc",
"oneline",
"truncated",
"count",
"truncated_count"};
_styles = {"combined",
"desc",
"oneline",
"truncated",
"count",
"truncated_count"};
_dateformat = context.config.get ("dateformat.annotation");
if (_dateformat == "")
@ -101,9 +102,7 @@ void ColumnDescription::measure (Task& task, unsigned int& minimum, unsigned int
if (min_anno > minimum)
minimum = min_anno;
std::map <std::string, std::string> annos;
task.getAnnotations (annos);
for (auto& i : annos)
for (auto& i : task.getAnnotations ())
{
unsigned int len = min_anno + 1 + utf8_width (i.second);
if (len > maximum)
@ -128,9 +127,7 @@ void ColumnDescription::measure (Task& task, unsigned int& minimum, unsigned int
if (task.annotation_count)
{
auto min_anno = Datetime::length (_dateformat);
std::map <std::string, std::string> annos;
task.getAnnotations (annos);
for (auto& i : annos)
for (auto& i : task.getAnnotations ())
maximum += min_anno + 1 + utf8_width (i.second);
}
}
@ -156,9 +153,6 @@ void ColumnDescription::measure (Task& task, unsigned int& minimum, unsigned int
minimum = 4;
maximum = utf8_width (description) + 1 + 1 + format (task.annotation_count).length () + 1;
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
////////////////////////////////////////////////////////////////////////////////
@ -178,9 +172,7 @@ void ColumnDescription::render (
{
if (task.annotation_count)
{
std::map <std::string, std::string> annos;
task.getAnnotations (annos);
for (const auto& i : annos)
for (const auto& i : task.getAnnotations ())
{
Datetime dt (strtol (i.first.substr (11).c_str (), NULL, 10));
description += '\n' + std::string (_indent, ' ') + dt.toString (_dateformat) + ' ' + i.second;
@ -209,9 +201,7 @@ void ColumnDescription::render (
{
if (task.annotation_count)
{
std::map <std::string, std::string> annos;
task.getAnnotations (annos);
for (const auto& i : annos)
for (const auto& i : task.getAnnotations ())
{
Datetime dt (strtol (i.first.substr (11).c_str (), NULL, 10));
description += ' ' + dt.toString (_dateformat) + ' ' + i.second;

View file

@ -31,8 +31,9 @@
////////////////////////////////////////////////////////////////////////////////
ColumnDue::ColumnDue ()
{
_name = "due";
_label = STRING_COLUMN_LABEL_DUE;
_name = "due";
_modifiable = true;
_label = STRING_COLUMN_LABEL_DUE;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -31,8 +31,9 @@
////////////////////////////////////////////////////////////////////////////////
ColumnEntry::ColumnEntry ()
{
_name = "entry";
_label = STRING_COLUMN_LABEL_ADDED;
_name = "entry";
_modifiable = true;
_label = STRING_COLUMN_LABEL_ADDED;
}
////////////////////////////////////////////////////////////////////////////////
@ -40,7 +41,7 @@ ColumnEntry::ColumnEntry ()
// Note that you can not determine which gets called first.
void ColumnEntry::setStyle (const std::string& value)
{
_style = value;
Column::setStyle (value);
if (_style == "age" &&
_label == STRING_COLUMN_LABEL_ADDED)

View file

@ -55,10 +55,6 @@ void ColumnID::measure (Task& task, unsigned int& minimum, unsigned int& maximum
else length = 1 + (int) log10 ((double) task.id); // Slow
minimum = maximum = length;
if (_style != "default" &&
_style != "number")
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
////////////////////////////////////////////////////////////////////////////////
@ -68,6 +64,7 @@ void ColumnID::render (
int width,
Color& color)
{
// Completed and deleted tasks have no ID.
if (task.id)
renderInteger (lines, width, color, task.id);
else

View file

@ -45,15 +45,8 @@ ColumnIMask::ColumnIMask ()
void ColumnIMask::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
minimum = maximum = task.get ("imask").length ();
if (_style != "default" &&
_style != "number")
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
minimum = maximum = task.get (_name).length ();
}
////////////////////////////////////////////////////////////////////////////////
@ -64,7 +57,7 @@ void ColumnIMask::render (
Color& color)
{
if (task.has (_name))
renderStringRight (lines, width, color, task.get ("imask"));
renderStringRight (lines, width, color, task.get (_name));
}
////////////////////////////////////////////////////////////////////////////////

63
src/columns/ColLast.cpp Normal file
View file

@ -0,0 +1,63 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2016, 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
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <ColLast.h>
#include <format.h>
#include <i18n.h>
////////////////////////////////////////////////////////////////////////////////
ColumnLast::ColumnLast ()
{
_name = "last";
_style = "number";
_label = STRING_COLUMN_LABEL_LAST;
_modifiable = false;
_styles = {"number"};
_examples = {"12"};
}
////////////////////////////////////////////////////////////////////////////////
// Set the minimum and maximum widths for the value.
void ColumnLast::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
minimum = maximum = task.get (_name).length ();
}
////////////////////////////////////////////////////////////////////////////////
void ColumnLast::render (
std::vector <std::string>& lines,
Task& task,
int width,
Color& color)
{
if (task.has (_name))
renderStringRight (lines, width, color, task.get (_name));
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -24,25 +24,19 @@
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_COLSTRING
#define INCLUDED_COLSTRING
#ifndef INCLUDED_COLLAST
#define INCLUDED_COLLAST
#include <vector>
#include <string>
#include <Column.h>
#include <Color.h>
#include <Task.h>
#include <ColTypeNumeric.h>
class ColumnString : public Column
class ColumnLast : public ColumnTypeNumeric
{
public:
ColumnString ();
void setReport (const std::string&);
void measure (const std::string&, unsigned int&, unsigned int&);
void render (std::vector <std::string>&, const std::string&, int, Color&);
ColumnLast ();
void measure (Task&, unsigned int&, unsigned int&);
void render (std::vector <std::string>&, Task&, int, Color&);
private:
bool _hyphenate;
};
#endif

View file

@ -46,12 +46,7 @@ void ColumnMask::measure (Task& task, unsigned int& minimum, unsigned int& maxim
{
minimum = maximum = 0;
if (task.has (_name))
{
minimum = maximum = task.get ("mask").length ();
if (_style != "default")
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
minimum = maximum = task.get (_name).length ();
}
////////////////////////////////////////////////////////////////////////////////
@ -62,7 +57,7 @@ void ColumnMask::render (
Color& color)
{
if (task.has (_name))
renderStringLeft (lines, width, color, task.get ("mask"));
renderStringLeft (lines, width, color, task.get (_name));
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -45,13 +45,10 @@ ColumnParent::ColumnParent ()
void ColumnParent::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "default" || _style == "long") minimum = maximum = 36;
else if (_style == "short") minimum = maximum = 8;
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
}

View file

@ -59,7 +59,6 @@ ColumnProject::ColumnProject ()
void ColumnProject::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
std::string project = task.get (_name);
@ -74,10 +73,6 @@ void ColumnProject::measure (Task& task, unsigned int& minimum, unsigned int& ma
{
project = indentProject (project, " ", '.');
}
else if (_style != "default" &&
_style != "full" &&
_style != "indented")
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
minimum = longestWord (project);
maximum = utf8_width (project);

View file

@ -25,92 +25,77 @@
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <ColString.h>
#include <ColRType.h>
#include <Context.h>
#include <format.h>
#include <shared.h>
#include <util.h>
#include <format.h>
#include <i18n.h>
#include <cctype>
extern Context context;
////////////////////////////////////////////////////////////////////////////////
ColumnString::ColumnString ()
ColumnRType::ColumnRType ()
{
_name = "string";
_type = "string";
_style = "left";
_label = "";
_styles = {"left",
"right",
"left_fixed",
"right_fixed"};
_examples = {"Hello (wrapped) ",
" Hello (wrapped)",
"Hello (no-wrap) ",
" Hello (no-wrap)"};
_hyphenate = context.config.getBoolean ("hyphenate");
_name = "rtype";
_style = "default";
_label = STRING_COLUMN_LABEL_RTYPE;
_modifiable = false;
_styles = {"default", "indicator"};
_examples = {"periodic", "chained"};
}
////////////////////////////////////////////////////////////////////////////////
// ColumnString is unique - it copies the report name into the label. This is
// a kludgy reuse of an otherwise unused member.
void ColumnString::setReport (const std::string& value)
// Overriden so that style <----> label are linked.
// Note that you can not determine which gets called first.
void ColumnRType::setStyle (const std::string& value)
{
_report = _label = value;
Column::setStyle (value);
if (_style == "indicator" && _label == STRING_COLUMN_LABEL_RTYPE)
_label = _label.substr (0, context.config.get ("rtype.indicator").length ());
}
////////////////////////////////////////////////////////////////////////////////
// Set the minimum and maximum widths for the value.
//
void ColumnString::measure (const std::string& value, unsigned int& minimum, unsigned int& maximum)
void ColumnRType::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (_style == "left" ||
_style == "right" ||
_style == "default")
if (task.has (_name))
{
std::string stripped = Color::strip (value);
maximum = longestLine (stripped);
minimum = longestWord (stripped);
if (_style == "default")
minimum = maximum = task.get (_name).length ();
else if (_style == "indicator")
minimum = maximum = 1;
}
else if (_style == "left_fixed" ||
_style == "right_fixed")
minimum = maximum = strippedLength (value);
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
////////////////////////////////////////////////////////////////////////////////
void ColumnString::render (
void ColumnRType::render (
std::vector <std::string>& lines,
const std::string& value,
Task& task,
int width,
Color& color)
{
if (_style == "default" || _style == "left")
if (task.has (_name))
{
std::vector <std::string> raw;
wrapText (raw, value, width, _hyphenate);
if (_style == "default")
renderStringRight (lines, width, color, task.get (_name));
for (auto& i : raw)
renderStringLeft (lines, width, color, i);
else if (_style == "indicator")
{
std::string value {" "};
value[0] = toupper (task.get (_name)[0]);
renderStringRight (lines, width, color, value);
}
}
else if (_style == "right")
{
std::vector <std::string> raw;
wrapText (raw, value, width, _hyphenate);
for (auto& i : raw)
renderStringRight (lines, width, color, i);
}
else if (_style == "left_fixed")
renderStringLeft (lines, width, color, value);
else if (_style == "right_fixed")
renderStringRight (lines, width, color, value);
}
////////////////////////////////////////////////////////////////////////////////
bool ColumnRType::validate (const std::string& input) const
{
return input == "periodic" ||
input == "chained";
}
////////////////////////////////////////////////////////////////////////////////

45
src/columns/ColRType.h Normal file
View file

@ -0,0 +1,45 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2016, 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
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_COLRTYPE
#define INCLUDED_COLRTYPE
#include <ColTypeString.h>
class ColumnRType : public ColumnTypeString
{
public:
ColumnRType ();
void setStyle (const std::string&);
void measure (Task&, unsigned int&, unsigned int&);
void render (std::vector <std::string>&, Task&, int, Color&);
bool validate (const std::string&) const;
private:
};
#endif
////////////////////////////////////////////////////////////////////////////////

View file

@ -44,11 +44,12 @@ extern Task& contextTask;
////////////////////////////////////////////////////////////////////////////////
ColumnRecur::ColumnRecur ()
{
_name = "recur";
_style = "duration";
_label = STRING_COLUMN_LABEL_RECUR;
_styles = {"duration", "indicator"};
_examples = {"weekly", context.config.get ("recurrence.indicator")};
_name = "recur";
_style = "duration";
_label = STRING_COLUMN_LABEL_RECUR;
_modifiable = true;
_styles = {"duration", "indicator"};
_examples = {"weekly", context.config.get ("recurrence.indicator")};
}
////////////////////////////////////////////////////////////////////////////////
@ -56,7 +57,7 @@ ColumnRecur::ColumnRecur ()
// Note that you can not determine which gets called first.
void ColumnRecur::setStyle (const std::string& value)
{
_style = value;
Column::setStyle (value);
if (_style == "indicator" && _label == STRING_COLUMN_LABEL_RECUR)
_label = _label.substr (0, context.config.get ("recurrence.indicator").length ());
@ -67,23 +68,17 @@ void ColumnRecur::setStyle (const std::string& value)
void ColumnRecur::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "default" ||
_style == "duration")
{
minimum = maximum = Duration (task.get ("recur")).formatISO ().length ();
minimum = maximum = Duration (task.get (_name)).formatISO ().length ();
}
else if (_style == "indicator")
{
if (task.has ("recur"))
minimum = maximum = utf8_width (context.config.get ("recurrence.indicator"));
else
minimum = maximum = 0;
minimum = maximum = utf8_width (context.config.get ("recurrence.indicator"));
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
}
@ -98,7 +93,7 @@ void ColumnRecur::render (
{
if (_style == "default" ||
_style == "duration")
renderStringRight (lines, width, color, Duration (task.get ("recur")).formatISO ());
renderStringRight (lines, width, color, Duration (task.get (_name)).formatISO ());
else if (_style == "indicator")
renderStringRight (lines, width, color, context.config.get ("recurrence.indicator"));

View file

@ -31,8 +31,8 @@
////////////////////////////////////////////////////////////////////////////////
ColumnScheduled::ColumnScheduled ()
{
_name = "scheduled";
_label = STRING_COLUMN_LABEL_SCHED;
_name = "scheduled";
_label = STRING_COLUMN_LABEL_SCHED;
}
////////////////////////////////////////////////////////////////////////////////
@ -40,9 +40,9 @@ ColumnScheduled::ColumnScheduled ()
// Note that you can not determine which gets called first.
void ColumnScheduled::setStyle (const std::string& value)
{
_style = value;
Column::setStyle (value);
if (_style == "countdown" && _label == STRING_COLUMN_LABEL_DUE)
if (_style == "countdown" && _label == STRING_COLUMN_LABEL_SCHED)
_label = STRING_COLUMN_LABEL_COUNT;
}

View file

@ -47,7 +47,7 @@ ColumnStart::ColumnStart ()
// Note that you can not determine which gets called first.
void ColumnStart::setStyle (const std::string& value)
{
_style = value;
Column::setStyle (value);
if (_style == "active" && _label == STRING_COLUMN_LABEL_STARTED)
_label = STRING_COLUMN_LABEL_ACTIVE;
@ -58,18 +58,14 @@ void ColumnStart::setStyle (const std::string& value)
void ColumnStart::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "active")
{
if (task.has ("start"))
minimum = maximum = utf8_width (context.config.get ("active.indicator"));
else
minimum = maximum = 0;
}
minimum = maximum = utf8_width (context.config.get ("active.indicator"));
else
ColumnTypeDate::measure (task, minimum, maximum);
// TODO Throw on bad format.
}
}

View file

@ -46,7 +46,7 @@ ColumnStatus::ColumnStatus ()
// Note that you can not determine which gets called first.
void ColumnStatus::setStyle (const std::string& value)
{
_style = value;
Column::setStyle (value);
if (_style == "short" && _label == STRING_COLUMN_LABEL_STATUS)
_label = STRING_COLUMN_LABEL_STAT;
@ -74,8 +74,6 @@ void ColumnStatus::measure (Task& task, unsigned int& minimum, unsigned int& max
}
else if (_style == "short")
minimum = maximum = 1;
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -59,7 +59,7 @@ ColumnTags::ColumnTags ()
// Note that you can not determine which gets called first.
void ColumnTags::setStyle (const std::string& value)
{
_style = value;
Column::setStyle (value);
if (_style == "indicator" &&
_label == STRING_COLUMN_LABEL_TAGS)
@ -75,15 +75,11 @@ void ColumnTags::setStyle (const std::string& value)
void ColumnTags::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "indicator")
{
if (task.has ("tags"))
minimum = maximum = utf8_width (context.config.get ("tag.indicator"));
else
minimum = maximum = 0;
minimum = maximum = utf8_width (context.config.get ("tag.indicator"));
}
else if (_style == "count")
{
@ -112,8 +108,6 @@ void ColumnTags::measure (Task& task, unsigned int& minimum, unsigned int& maxim
else
minimum = maximum = utf8_width (tags);
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
}
@ -163,7 +157,7 @@ void ColumnTags::modify (Task& task, const std::string& value)
std::string label = " MODIFICATION ";
// TW-1701
task.set ("tags", "");
task.set (_name, "");
for (auto& tag : split (value, ','))
{

View file

@ -0,0 +1,75 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2016, 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
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <ColTemplate.h>
#include <format.h>
#include <i18n.h>
////////////////////////////////////////////////////////////////////////////////
ColumnTemplate::ColumnTemplate ()
{
_name = "template";
_style = "long";
_label = STRING_COLUMN_LABEL_TEMPLATE;
_modifiable = false;
_styles = {"long", "short"};
_examples = {"f30cb9c3-3fc0-483f-bfb2-3bf134f00694", "f30cb9c3"};
}
////////////////////////////////////////////////////////////////////////////////
// Set the minimum and maximum widths for the value.
void ColumnTemplate::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "default" || _style == "long") minimum = maximum = 36;
else if (_style == "short") minimum = maximum = 8;
}
}
////////////////////////////////////////////////////////////////////////////////
void ColumnTemplate::render (
std::vector <std::string>& lines,
Task& task,
int width,
Color& color)
{
if (task.has (_name))
{
// f30cb9c3-3fc0-483f-bfb2-3bf134f00694 default
// f30cb9c3 short
if (_style == "default" ||
_style == "long")
renderStringLeft (lines, width, color, task.get(_name));
else if (_style == "short")
renderStringLeft (lines, width, color, task.get (_name).substr (0, 8));
}
}
////////////////////////////////////////////////////////////////////////////////

43
src/columns/ColTemplate.h Normal file
View file

@ -0,0 +1,43 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2016, 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
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_COLTEMPLATE
#define INCLUDED_COLTEMPLATE
#include <ColTypeString.h>
class ColumnTemplate : public ColumnTypeString
{
public:
ColumnTemplate ();
void measure (Task&, unsigned int&, unsigned int&);
void render (std::vector <std::string>&, Task&, int, Color&);
private:
};
#endif
////////////////////////////////////////////////////////////////////////////////

View file

@ -72,7 +72,6 @@ ColumnTypeDate::ColumnTypeDate ()
void ColumnTypeDate::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
Datetime date (task.get_date (_name));
@ -131,8 +130,6 @@ void ColumnTypeDate::measure (Task& task, unsigned int& minimum, unsigned int& m
if (date > now)
minimum = maximum = Duration (date - now).formatVague ().length ();
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
}
@ -204,6 +201,12 @@ void ColumnTypeDate::render (
}
}
////////////////////////////////////////////////////////////////////////////////
bool ColumnTypeDate::validate (const std::string& input) const
{
return input.length () ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
void ColumnTypeDate::modify (Task& task, const std::string& value)
{

View file

@ -39,6 +39,7 @@ public:
ColumnTypeDate ();
virtual void measure (Task&, unsigned int&, unsigned int&);
virtual void render (std::vector <std::string>&, Task&, int, Color&);
virtual bool validate (const std::string&) const;
virtual void modify (Task&, const std::string&);
};

View file

@ -43,6 +43,12 @@ ColumnTypeDuration::ColumnTypeDuration ()
_type = "duration";
}
////////////////////////////////////////////////////////////////////////////////
bool ColumnTypeDuration::validate (const std::string& input) const
{
return input.length () ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
void ColumnTypeDuration::modify (Task& task, const std::string& value)
{

View file

@ -35,6 +35,7 @@ class ColumnTypeDuration : public Column
{
public:
ColumnTypeDuration ();
virtual bool validate (const std::string&) const;
virtual void modify (Task&, const std::string&);
};

View file

@ -43,6 +43,12 @@ ColumnTypeNumeric::ColumnTypeNumeric ()
_type = "numeric";
}
////////////////////////////////////////////////////////////////////////////////
bool ColumnTypeNumeric::validate (const std::string& input) const
{
return input.length () ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
void ColumnTypeNumeric::modify (Task& task, const std::string& value)
{

View file

@ -35,6 +35,7 @@ class ColumnTypeNumeric : public Column
{
public:
ColumnTypeNumeric ();
virtual bool validate (const std::string&) const;
virtual void modify (Task&, const std::string&);
};

View file

@ -43,6 +43,12 @@ ColumnTypeString::ColumnTypeString ()
_type = "string";
}
////////////////////////////////////////////////////////////////////////////////
bool ColumnTypeString::validate (const std::string& input) const
{
return input.length () ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
void ColumnTypeString::modify (Task& task, const std::string& value)
{

View file

@ -35,6 +35,7 @@ class ColumnTypeString : public Column
{
public:
ColumnTypeString ();
virtual bool validate (const std::string&) const;
virtual void modify (Task&, const std::string&);
};

View file

@ -40,12 +40,13 @@ extern Context context;
////////////////////////////////////////////////////////////////////////////////
ColumnUDAString::ColumnUDAString ()
{
_name = "<uda>";
_style = "default";
_label = "";
_uda = true;
_hyphenate = true;
_styles = {_style, "indicator"};
_name = "<uda>"; // Gets overwritten at runtime.
_style = "default";
_label = "";
_modifiable = true;
_uda = true;
_hyphenate = true;
_styles = {_style, "indicator"};
}
////////////////////////////////////////////////////////////////////////////////
@ -70,7 +71,6 @@ bool ColumnUDAString::validate (const std::string& value) const
void ColumnUDAString::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "default")
@ -78,26 +78,19 @@ void ColumnUDAString::measure (Task& task, unsigned int& minimum, unsigned int&
std::string value = task.get (_name);
if (value != "")
{
std::string stripped = Color::strip (value);
auto stripped = Color::strip (value);
maximum = longestLine (stripped);
minimum = longestWord (stripped);
}
}
else if (_style == "indicator")
{
if (task.has (_name))
{
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
minimum = maximum = utf8_width (indicator);
}
else
minimum = maximum = 0;
minimum = maximum = utf8_width (indicator);
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
}
@ -121,14 +114,11 @@ void ColumnUDAString::render (
}
else if (_style == "indicator")
{
if (task.has (_name))
{
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
renderStringRight (lines, width, color, indicator);
}
renderStringRight (lines, width, color, indicator);
}
}
}
@ -166,30 +156,22 @@ bool ColumnUDANumeric::validate (const std::string& value) const
void ColumnUDANumeric::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "default")
{
std::string value = task.get (_name);
auto value = task.get (_name);
if (value != "")
minimum = maximum = value.length ();
}
else if (_style == "indicator")
{
if (task.has (_name))
{
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
minimum = maximum = utf8_width (indicator);
}
else
minimum = maximum = 0;
minimum = maximum = utf8_width (indicator);
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
}
@ -204,19 +186,16 @@ void ColumnUDANumeric::render (
{
if (_style == "default")
{
std::string value = task.get (_name);
auto value = task.get (_name);
renderStringRight (lines, width, color, value);
}
else if (_style == "indicator")
{
if (task.has (_name))
{
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
renderStringRight (lines, width, color, indicator);
}
renderStringRight (lines, width, color, indicator);
}
}
}
@ -254,12 +233,11 @@ bool ColumnUDADate::validate (const std::string& value) const
void ColumnUDADate::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "default")
{
std::string value = task.get (_name);
auto value = task.get (_name);
if (value != "")
{
// Determine the output date format, which uses a hierarchy of definitions.
@ -267,7 +245,7 @@ void ColumnUDADate::measure (Task& task, unsigned int& minimum, unsigned int& ma
// rc.dateformat.report
// rc.dateformat
Datetime date ((time_t) strtol (value.c_str (), NULL, 10));
std::string format = context.config.get ("report." + _report + ".dateformat");
auto format = context.config.get ("report." + _report + ".dateformat");
if (format == "")
format = context.config.get ("dateformat.report");
if (format == "")
@ -278,19 +256,12 @@ void ColumnUDADate::measure (Task& task, unsigned int& minimum, unsigned int& ma
}
else if (_style == "indicator")
{
if (task.has (_name))
{
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
minimum = maximum = utf8_width (indicator);
}
else
minimum = maximum = 0;
minimum = maximum = utf8_width (indicator);
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
}
@ -305,13 +276,13 @@ void ColumnUDADate::render (
{
if (_style == "default")
{
std::string value = task.get (_name);
auto value = task.get (_name);
// Determine the output date format, which uses a hierarchy of definitions.
// rc.report.<report>.dateformat
// rc.dateformat.report
// rc.dateformat.
std::string format = context.config.get ("report." + _report + ".dateformat");
auto format = context.config.get ("report." + _report + ".dateformat");
if (format == "")
{
format = context.config.get ("dateformat.report");
@ -323,14 +294,11 @@ void ColumnUDADate::render (
}
else if (_style == "indicator")
{
if (task.has (_name))
{
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
renderStringRight (lines, width, color, indicator);
}
renderStringRight (lines, width, color, indicator);
}
}
}
@ -368,12 +336,11 @@ bool ColumnUDADuration::validate (const std::string& value) const
void ColumnUDADuration::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{
minimum = maximum = 0;
if (task.has (_name))
{
if (_style == "default")
{
std::string value = task.get (_name);
auto value = task.get (_name);
if (value != "")
minimum = maximum = Duration (value).formatISO ().length ();
}
@ -390,8 +357,6 @@ void ColumnUDADuration::measure (Task& task, unsigned int& minimum, unsigned int
else
minimum = maximum = 0;
}
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
}
@ -406,19 +371,16 @@ void ColumnUDADuration::render (
{
if (_style == "default")
{
std::string value = task.get (_name);
auto value = task.get (_name);
renderStringRight (lines, width, color, Duration (value).formatISO ());
}
else if (_style == "indicator")
{
if (task.has (_name))
{
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
auto indicator = context.config.get ("uda." + _name + ".indicator");
if (indicator == "")
indicator = "U";
renderStringRight (lines, width, color, indicator);
}
renderStringRight (lines, width, color, indicator);
}
}
}

View file

@ -26,7 +26,6 @@
#include <cmake.h>
#include <ColUUID.h>
#include <math.h>
#include <format.h>
#include <i18n.h>
@ -45,10 +44,10 @@ ColumnUUID::ColumnUUID ()
// Set the minimum and maximum widths for the value.
void ColumnUUID::measure (Task&, unsigned int& minimum, unsigned int& maximum)
{
// Mandatory attribute, no need to check the value.
if (_style == "default" || _style == "long") minimum = maximum = 36;
else if (_style == "short") minimum = maximum = 8;
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -31,8 +31,8 @@
////////////////////////////////////////////////////////////////////////////////
ColumnUntil::ColumnUntil ()
{
_name = "until";
_label = STRING_COLUMN_LABEL_UNTIL;
_name = "until";
_label = STRING_COLUMN_LABEL_UNTIL;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -32,11 +32,12 @@
////////////////////////////////////////////////////////////////////////////////
ColumnUrgency::ColumnUrgency ()
{
_name = "urgency";
_style = "real";
_label = STRING_COLUMN_LABEL_URGENCY;
_styles = {"real", "integer"};
_examples = {"4.6", "4"};
_name = "urgency";
_style = "real";
_label = STRING_COLUMN_LABEL_URGENCY;
_modifiable = false;
_styles = {"real", "integer"};
_examples = {"4.6", "4"};
}
////////////////////////////////////////////////////////////////////////////////
@ -48,9 +49,6 @@ void ColumnUrgency::measure (Task& task, unsigned int& minimum, unsigned int& ma
else if (_style == "integer")
minimum = maximum = format ((int)task.urgency ()).length ();
else
throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -31,8 +31,8 @@
////////////////////////////////////////////////////////////////////////////////
ColumnWait::ColumnWait ()
{
_name = "wait";
_label = STRING_COLUMN_LABEL_WAIT;
_name = "wait";
_label = STRING_COLUMN_LABEL_WAIT;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -36,16 +36,18 @@
#include <ColEntry.h>
#include <ColID.h>
#include <ColIMask.h>
#include <ColLast.h>
#include <ColMask.h>
#include <ColModified.h>
#include <ColParent.h>
#include <ColProject.h>
#include <ColRecur.h>
#include <ColRType.h>
#include <ColScheduled.h>
#include <ColStart.h>
#include <ColStatus.h>
#include <ColString.h>
#include <ColTags.h>
#include <ColTemplate.h>
#include <ColUntil.h>
#include <ColUrgency.h>
#include <ColUUID.h>
@ -87,23 +89,23 @@ Column* Column::factory (const std::string& name, const std::string& report)
else if (column_name == "entry") c = new ColumnEntry ();
else if (column_name == "id") c = new ColumnID ();
else if (column_name == "imask") c = new ColumnIMask ();
else if (column_name == "last") c = new ColumnLast ();
else if (column_name == "mask") c = new ColumnMask ();
else if (column_name == "modified") c = new ColumnModified ();
else if (column_name == "parent") c = new ColumnParent ();
else if (column_name == "project") c = new ColumnProject ();
else if (column_name == "recur") c = new ColumnRecur ();
else if (column_name == "rtype") c = new ColumnRType ();
else if (column_name == "scheduled") c = new ColumnScheduled ();
else if (column_name == "start") c = new ColumnStart ();
else if (column_name == "status") c = new ColumnStatus ();
else if (column_name == "tags") c = new ColumnTags ();
else if (column_name == "template") c = new ColumnTemplate ();
else if (column_name == "until") c = new ColumnUntil ();
else if (column_name == "urgency") c = new ColumnUrgency ();
else if (column_name == "uuid") c = new ColumnUUID ();
else if (column_name == "wait") c = new ColumnWait ();
// Special non-task column.
else if (column_name == "string") c = new ColumnString ();
// UDA.
else if (context.config.has ("uda." + column_name + ".type"))
c = Column::uda (column_name);
@ -129,15 +131,18 @@ void Column::factory (std::map <std::string, Column*>& all)
c = new ColumnEntry (); all[c->_name] = c;
c = new ColumnID (); all[c->_name] = c;
c = new ColumnIMask (); all[c->_name] = c;
c = new ColumnLast (); all[c->_name] = c;
c = new ColumnMask (); all[c->_name] = c;
c = new ColumnModified (); all[c->_name] = c;
c = new ColumnParent (); all[c->_name] = c;
c = new ColumnProject (); all[c->_name] = c;
c = new ColumnRecur (); all[c->_name] = c;
c = new ColumnRType (); all[c->_name] = c;
c = new ColumnScheduled (); all[c->_name] = c;
c = new ColumnStart (); all[c->_name] = c;
c = new ColumnStatus (); all[c->_name] = c;
c = new ColumnTags (); all[c->_name] = c;
c = new ColumnTemplate (); all[c->_name] = c;
c = new ColumnUntil (); all[c->_name] = c;
c = new ColumnUrgency (); all[c->_name] = c;
c = new ColumnUUID (); all[c->_name] = c;
@ -149,7 +154,7 @@ void Column::factory (std::map <std::string, Column*>& all)
////////////////////////////////////////////////////////////////////////////////
void Column::uda (std::map <std::string, Column*>& all)
{
// For each UDA, instantiate and initialize ColumnUDA().
// For each UDA, instantiate and initialize ColumnUDA.
std::set <std::string> udas;
for (const auto& i : context.config)
@ -283,12 +288,6 @@ void Column::setStyle (const std::string& style)
_style = style;
}
////////////////////////////////////////////////////////////////////////////////
bool Column::validate (const std::string& input) const
{
return input.length () ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
// All integer values are right-justified.
void Column::renderInteger (

View file

@ -57,12 +57,12 @@ public:
virtual void setLabel (const std::string& value) { _label = value; }
virtual void setReport (const std::string& value) { _report = value; }
virtual bool validate (const std::string&) const;
virtual void measure (const std::string&, unsigned int&, unsigned int&) {};
virtual void measure (Task&, unsigned int&, unsigned int&) {};
virtual void renderHeader (std::vector <std::string>&, int, Color&);
virtual void render (std::vector <std::string>&, const std::string&, int, Color&) {};
virtual void render (std::vector <std::string>&, Task&, int, Color&) {};
virtual bool validate (const std::string&) const {return false;};
virtual void modify (Task&, const std::string&) {};
protected:

View file

@ -32,7 +32,6 @@
#include <Context.h>
#include <Table.h>
#include <Command.h>
#include <ColString.h>
#include <util.h>
#include <i18n.h>

View file

@ -90,8 +90,7 @@ int CmdDenotate::execute (std::string&)
{
Task before (task);
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
auto annotations = task.getAnnotations ();
if (annotations.size () == 0)
throw std::string (STRING_CMD_DENO_NONE);

View file

@ -456,10 +456,7 @@ int CmdDiagnostics::execute (std::string& output)
for (auto& task : all)
{
// Check dependencies
std::vector <std::string> dependencies;
task.getDependencies(dependencies);
for (auto& uuid : dependencies)
for (auto& uuid : task.getDependencyUUIDs ())
{
if (! context.tdb2.has (uuid))
{

View file

@ -224,14 +224,10 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat)
<< "# iMask: " << task.get ("imask") << '\n'
<< " Project: " << task.get ("project") << '\n';
std::vector <std::string> tags;
task.getTags (tags);
auto allTags = join (" ", tags);
if (verbose)
before << "# " << STRING_EDIT_TAG_SEP << '\n';
before << " Tags: " << allTags << '\n'
before << " Tags: " << join (" ", task.getTags ()) << '\n'
<< " Description: " << task.get ("description") << '\n'
<< " Created: " << formatDate (task, "entry", dateformat) << '\n'
<< " Started: " << formatDate (task, "start", dateformat) << '\n'
@ -249,9 +245,7 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat)
<< "# " << STRING_EDIT_HEADER_14 << '\n'
<< "# " << STRING_EDIT_HEADER_15 << '\n';
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
for (auto& anno : annotations)
for (auto& anno : task.getAnnotations ())
{
Datetime dt (strtol (anno.first.substr (11).c_str (), NULL, 10));
before << " Annotation: " << dt.toString (dateformat)
@ -262,8 +256,7 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat)
before << " Annotation: " << now.toString (dateformat) << " -- \n";
// Add dependencies here.
std::vector <std::string> dependencies;
task.getDependencies (dependencies);
auto dependencies = task.getDependencyUUIDs ();
std::stringstream allDeps;
for (unsigned int i = 0; i < dependencies.size (); ++i)
{
@ -312,9 +305,7 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat)
}
// UDA orphans
std::vector <std::string> orphans;
task.getUDAOrphans (orphans);
auto orphans = task.getUDAOrphanUUIDs ();
if (orphans.size ())
{
before << "# " << STRING_EDIT_UDA_ORPHAN_SEP << '\n';
@ -355,9 +346,8 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
// tags
value = findValue (after, "\n Tags:");
auto tags = split (value, ' ');
task.remove ("tags");
task.addTags (tags);
task.addTags (split (value, ' '));
// description.
value = findMultilineValue (after, "\n Description:", "\n Created:");

View file

@ -134,9 +134,7 @@ int CmdInfo::execute (std::string& output)
std::string description = task.get ("description");
int indent = context.config.getInteger ("indent.annotation");
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
for (auto& anno : annotations)
for (auto& anno : task.getAnnotations ())
description += '\n'
+ std::string (indent, ' ')
+ Datetime (anno.first.substr (11)).toString (dateformatanno)
@ -162,8 +160,7 @@ int CmdInfo::execute (std::string& output)
// dependencies: blocked
{
std::vector <Task> blocked;
dependencyGetBlocking (task, blocked);
auto blocked = dependencyGetBlocking (task);
if (blocked.size ())
{
std::stringstream message;
@ -178,8 +175,7 @@ int CmdInfo::execute (std::string& output)
// dependencies: blocking
{
std::vector <Task> blocking;
dependencyGetBlocked (task, blocking);
auto blocking = dependencyGetBlocked (task);
if (blocking.size ())
{
std::stringstream message;
@ -201,6 +197,7 @@ int CmdInfo::execute (std::string& output)
}
// parent
// 2017-01-07: Deprecated in 2.6.0
if (task.has ("parent"))
{
row = view.addRow ();
@ -209,6 +206,7 @@ int CmdInfo::execute (std::string& output)
}
// mask
// 2017-01-07: Deprecated in 2.6.0
if (task.has ("mask"))
{
row = view.addRow ();
@ -217,6 +215,7 @@ int CmdInfo::execute (std::string& output)
}
// imask
// 2017-01-07: Deprecated in 2.6.0
if (task.has ("imask"))
{
row = view.addRow ();
@ -224,6 +223,30 @@ int CmdInfo::execute (std::string& output)
view.set (row, 1, task.get ("imask"));
}
// template
if (task.has ("template"))
{
row = view.addRow ();
view.set (row, 0, STRING_COLUMN_LABEL_TEMPLATE);
view.set (row, 1, task.get ("template"));
}
// last
if (task.has ("last"))
{
row = view.addRow ();
view.set (row, 0, STRING_COLUMN_LABEL_LAST);
view.set (row, 1, task.get ("last"));
}
// rtype
if (task.has ("rtype"))
{
row = view.addRow ();
view.set (row, 0, STRING_COLUMN_LABEL_RTYPE);
view.set (row, 1, task.get ("rtype"));
}
// entry
row = view.addRow ();
view.set (row, 0, STRING_COLUMN_LABEL_ENTERED);
@ -300,8 +323,7 @@ int CmdInfo::execute (std::string& output)
}
// tags ...
std::vector <std::string> tags;
task.getTags (tags);
auto tags = task.getTags ();
if (tags.size ())
{
auto allTags = join (" ", tags);
@ -320,19 +342,21 @@ int CmdInfo::execute (std::string& output)
if (task.hasTag ("ANNOTATED")) virtualTags += "ANNOTATED ";
if (task.hasTag ("BLOCKED")) virtualTags += "BLOCKED ";
if (task.hasTag ("BLOCKING")) virtualTags += "BLOCKING ";
if (task.hasTag ("CHILD")) virtualTags += "CHILD ";
if (task.hasTag ("CHILD")) virtualTags += "CHILD "; // 2017-01-07: Deprecated in 2.6.0
if (task.hasTag ("COMPLETED")) virtualTags += "COMPLETED ";
if (task.hasTag ("DELETED")) virtualTags += "DELETED ";
if (task.hasTag ("DUE")) virtualTags += "DUE ";
if (task.hasTag ("DUETODAY")) virtualTags += "DUETODAY ";
if (task.hasTag ("INSTANCE")) virtualTags += "INSTANCE ";
if (task.hasTag ("MONTH")) virtualTags += "MONTH ";
if (task.hasTag ("ORPHAN")) virtualTags += "ORPHAN ";
if (task.hasTag ("OVERDUE")) virtualTags += "OVERDUE ";
if (task.hasTag ("PARENT")) virtualTags += "PARENT ";
if (task.hasTag ("PARENT")) virtualTags += "PARENT "; // 2017-01-07: Deprecated in 2.6.0
if (task.hasTag ("PENDING")) virtualTags += "PENDING ";
if (task.hasTag ("READY")) virtualTags += "READY ";
if (task.hasTag ("SCHEDULED")) virtualTags += "SCHEDULED ";
if (task.hasTag ("TAGGED")) virtualTags += "TAGGED ";
if (task.hasTag ("TEMPLATE")) virtualTags += "TEMPLATE ";
if (task.hasTag ("TODAY")) virtualTags += "TODAY ";
if (task.hasTag ("TOMORROW")) virtualTags += "TOMORROW ";
if (task.hasTag ("UDA")) virtualTags += "UDA ";

View file

@ -140,13 +140,9 @@ int CmdStats::execute (std::string& output)
daysPending += (now.toEpoch () - entry) / 86400.0;
descLength += task.get ("description").length ();
annotationsT += task.getAnnotations ().size ();
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
annotationsT += annotations.size ();
std::vector <std::string> tags;
task.getTags (tags);
auto tags = task.getTags ();
if (tags.size ())
++taggedT;

View file

@ -79,10 +79,7 @@ int CmdTags::execute (std::string& output)
std::map <std::string, int> unique;
for (auto& task : filtered)
{
std::vector <std::string> tags;
task.getTags (tags);
for (auto& tag : tags)
for (auto& tag : task.getTags ())
if (unique.find (tag) != unique.end ())
unique[tag]++;
else
@ -182,13 +179,8 @@ int CmdCompletionTags::execute (std::string& output)
// names as keys.
std::map <std::string, int> unique;
for (auto& task : filtered)
{
std::vector <std::string> tags;
task.getTags (tags);
for (auto& tag : tags)
for (auto& tag : task.getTags ())
unique[tag] = 0;
}
// Add built-in tags to map.
unique["nocolor"] = 0;
@ -199,19 +191,21 @@ int CmdCompletionTags::execute (std::string& output)
unique["ANNOTATED"] = 0;
unique["BLOCKED"] = 0;
unique["BLOCKING"] = 0;
unique["CHILD"] = 0;
unique["CHILD"] = 0; // 2017-01-07: Deprecated in 2.6.0
unique["COMPLETED"] = 0;
unique["DELETED"] = 0;
unique["DUE"] = 0;
unique["DUETODAY"] = 0;
unique["INSTANCE"] = 0;
unique["MONTH"] = 0;
unique["ORPHAN"] = 0;
unique["OVERDUE"] = 0;
unique["PARENT"] = 0;
unique["PARENT"] = 0; // 2017-01-07: Deprecated in 2.6.0
unique["PENDING"] = 0;
unique["READY"] = 0;
unique["SCHEDULED"] = 0;
unique["TAGGED"] = 0;
unique["TEMPLATE"] = 0;
unique["TODAY"] = 0;
unique["TOMORROW"] = 0;
unique["UDA"] = 0;

View file

@ -142,9 +142,7 @@ int CmdTimesheet::execute (std::string& output)
std::string description = task.get ("description");
int indent = context.config.getInteger ("indent.annotation");
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
for (auto& ann : annotations)
for (auto& ann : task.getAnnotations ())
description += '\n'
+ std::string (indent, ' ')
+ Datetime (ann.first.substr (11)).toString (context.config.get ("dateformat"))
@ -198,9 +196,7 @@ int CmdTimesheet::execute (std::string& output)
std::string description = task.get ("description");
int indent = context.config.getInteger ("indent.annotation");
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
for (auto& ann : annotations)
for (auto& ann : task.getAnnotations ())
description += '\n'
+ std::string (indent, ' ')
+ Datetime (ann.first.substr (11)).toString (context.config.get ("dateformat"))

View file

@ -38,29 +38,35 @@
extern Context context;
////////////////////////////////////////////////////////////////////////////////
void dependencyGetBlocked (const Task& task, std::vector <Task>& blocked)
std::vector <Task> dependencyGetBlocked (const Task& task)
{
std::string uuid = task.get ("uuid");
auto all = context.tdb2.pending.get_tasks ();
for (auto& it : all)
std::vector <Task> blocked;
for (auto& it : context.tdb2.pending.get_tasks ())
if (it.getStatus () != Task::completed &&
it.getStatus () != Task::deleted &&
it.has ("depends") &&
it.get ("depends").find (uuid) != std::string::npos)
blocked.push_back (it);
return blocked;
}
////////////////////////////////////////////////////////////////////////////////
void dependencyGetBlocking (const Task& task, std::vector <Task>& blocking)
std::vector <Task> dependencyGetBlocking (const Task& task)
{
std::string depends = task.get ("depends");
std::vector <Task> blocking;
if (depends != "")
for (auto& it : context.tdb2.pending.get_tasks ())
if (it.getStatus () != Task::completed &&
it.getStatus () != Task::deleted &&
depends.find (it.get ("uuid")) != std::string::npos)
blocking.push_back (it);
return blocking;
}
////////////////////////////////////////////////////////////////////////////////
@ -82,8 +88,7 @@ bool dependencyIsCircular (const Task& task)
while (! s.empty ())
{
Task& current = s.top ();
std::vector <std::string> deps_current;
current.getDependencies (deps_current);
auto deps_current = current.getDependencyUUIDs ();
// This is a basic depth first search that always terminates given the
// fact that we do not visit any task twice
@ -146,14 +151,12 @@ bool dependencyIsCircular (const Task& task)
//
void dependencyChainOnComplete (Task& task)
{
std::vector <Task> blocking;
dependencyGetBlocking (task, blocking);
auto blocking = dependencyGetBlocking (task);
// If the task is anything but the tail end of a dependency chain.
if (blocking.size ())
{
std::vector <Task> blocked;
dependencyGetBlocked (task, blocked);
auto blocked = dependencyGetBlocked (task);
// Nag about broken chain.
if (context.config.getBoolean ("dependency.reminder"))
@ -206,8 +209,7 @@ void dependencyChainOnStart (Task& task)
{
if (context.config.getBoolean ("dependency.reminder"))
{
std::vector <Task> blocking;
dependencyGetBlocking (task, blocking);
auto blocking = dependencyGetBlocking (task);
// If the task is anything but the tail end of a dependency chain, nag about
// broken chain.

View file

@ -84,8 +84,7 @@ std::string taskDifferences (const Task& before, const Task& after)
{
if (name == "depends")
{
std::vector <Task> deps_after;
after.getDependencies (deps_after);
auto deps_after = after.getDependencyTasks ();
out << " - "
<< format (STRING_FEEDBACK_DEP_SET, taskIdentifiers (deps_after))
@ -110,12 +109,10 @@ std::string taskDifferences (const Task& before, const Task& after)
{
if (name == "depends")
{
std::vector <Task> deps_before;
before.getDependencies (deps_before);
auto deps_before = before.getDependencyTasks ();
std::string from = taskIdentifiers (deps_before);
std::vector <Task> deps_after;
after.getDependencies (deps_after);
auto deps_after = after.getDependencyTasks ();
std::string to = taskIdentifiers (deps_after);
out << " - "
@ -169,11 +166,7 @@ std::string taskInfoDifferences (
{
if (name == "depends")
{
std::vector <Task> deps_before;
before.getDependencies (deps_before);
std::string from = taskIdentifiers (deps_before);
out << format (STRING_FEEDBACK_DEP_DEL, from)
out << format (STRING_FEEDBACK_DEP_DEL, taskIdentifiers (before.getDependencyTasks ()))
<< "\n";
}
else if (name.substr (0, 11) == "annotation_")
@ -198,11 +191,7 @@ std::string taskInfoDifferences (
{
if (name == "depends")
{
std::vector <Task> deps_after;
after.getDependencies (deps_after);
std::string to = taskIdentifiers (deps_after);
out << format (STRING_FEEDBACK_DEP_WAS_SET, to)
out << format (STRING_FEEDBACK_DEP_WAS_SET, taskIdentifiers (after.getDependencyTasks ()))
<< "\n";
}
else if (name.substr (0, 11) == "annotation_")
@ -231,13 +220,8 @@ std::string taskInfoDifferences (
{
if (name == "depends")
{
std::vector <Task> deps_before;
before.getDependencies (deps_before);
std::string from = taskIdentifiers (deps_before);
std::vector <Task> deps_after;
after.getDependencies (deps_after);
std::string to = taskIdentifiers (deps_after);
auto from = taskIdentifiers (before.getDependencyTasks ());
auto to = taskIdentifiers (after.getDependencyTasks ());
out << format (STRING_FEEDBACK_DEP_WAS_MOD, from, to)
<< "\n";
@ -334,22 +318,24 @@ void feedback_reserved_tags (const std::string& tag)
tag == "ANNOTATED" ||
tag == "BLOCKED" ||
tag == "BLOCKING" ||
tag == "CHILD" ||
tag == "CHILD" || // Deprecated 2.6.0
tag == "COMPLETED" ||
tag == "DELETED" ||
tag == "DUE" ||
tag == "DUETODAY" ||
tag == "INSTANCE" ||
tag == "LATEST" ||
tag == "MONTH" ||
tag == "ORPHAN" ||
tag == "OVERDUE" ||
tag == "PARENT" ||
tag == "PARENT" || // Deprecated 2.6.0
tag == "PENDING" ||
tag == "PRIORITY" ||
tag == "PROJECT" ||
tag == "READY" ||
tag == "SCHEDULED" ||
tag == "TAGGED" ||
tag == "TEMPLATE" ||
tag == "TODAY" ||
tag == "TOMORROW" ||
tag == "UDA" ||
@ -397,14 +383,12 @@ void feedback_unblocked (const Task& task)
if (context.verbose ("affected"))
{
// Get a list of tasks that depended on this task.
std::vector <Task> blocked;
dependencyGetBlocked (task, blocked);
auto blocked = dependencyGetBlocked (task);
// Scan all the tasks that were blocked by this task
for (auto& i : blocked)
{
std::vector <Task> blocking;
dependencyGetBlocking (i, blocking);
auto blocking = dependencyGetBlocking (i);
if (blocking.size () == 0)
{
if (i.id)

25
src/l10n/check_translations.sh Executable file
View file

@ -0,0 +1,25 @@
#!/bin/bash
REFERENCE_LANGUAGE_FILE="eng-USA.h"
TESTED_LANGUAGE_FILES=`ls *.h | grep -v $REFERENCE_LANGUAGE_FILE`
# At the beginning, we haven't detected any invalid translation files
MISMATCHED=0
# Generate list of keys, not including defines that are commented out. Strips out the leading whitespace.
cat $REFERENCE_LANGUAGE_FILE | grep "^[[:space:]]*#define" | sed -e 's/^ *//' - | cut -f2 -d' ' | sort > identifiers
# Generate report
for LANGUAGE_FILE in $TESTED_LANGUAGE_FILES
do
echo "Comparing $REFERENCE_LANGUAGE_FILE (left) to $LANGUAGE_FILE (right)"
cat $LANGUAGE_FILE | grep "^[[:space:]]*#define" | sed -e 's/^ *//' - | cut -f2 -d' ' | sort | diff identifiers -
MISMATCHED=$(($MISMATCHED+$?))
echo ""
done
# Cleanup
rm -f identifiers
# Exit with number of not synced translations files
exit $MISMATCHED

View file

@ -210,7 +210,10 @@
#define STRING_COLUMN_LABEL_VALUE "Wert"
#define STRING_COLUMN_LABEL_MASK "Maske"
#define STRING_COLUMN_LABEL_MASK_IDX "Masken-Index"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Vorgänger-Aufgabe"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Datum"
#define STRING_COLUMN_LABEL_COLUMN "Spalten"
#define STRING_COLUMN_LABEL_STYLES "Unterstützte Formate"

View file

@ -210,7 +210,10 @@
#define STRING_COLUMN_LABEL_VALUE "Value"
#define STRING_COLUMN_LABEL_MASK "Mask"
#define STRING_COLUMN_LABEL_MASK_IDX "Mask Index"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Parent task"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Date"
#define STRING_COLUMN_LABEL_COLUMN "Columns"
#define STRING_COLUMN_LABEL_STYLES "Supported Formats"

View file

@ -210,7 +210,10 @@
#define STRING_COLUMN_LABEL_VALUE "Valoro"
#define STRING_COLUMN_LABEL_MASK "Masko"
#define STRING_COLUMN_LABEL_MASK_IDX "Mask-indico"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Patra tasko"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Dato"
#define STRING_COLUMN_LABEL_COLUMN "Kolumnoj"
#define STRING_COLUMN_LABEL_STYLES "Formaĝoj Subtenataj"

View file

@ -211,7 +211,10 @@
#define STRING_COLUMN_LABEL_VALUE "Valor"
#define STRING_COLUMN_LABEL_MASK "Máscara"
#define STRING_COLUMN_LABEL_MASK_IDX "Máscara de Índice"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Tarea madre"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Fecha"
#define STRING_COLUMN_LABEL_COLUMN "Columnas"
#define STRING_COLUMN_LABEL_STYLES "Formatos soportados"

View file

@ -210,7 +210,10 @@
#define STRING_COLUMN_LABEL_VALUE "Valeur"
#define STRING_COLUMN_LABEL_MASK "Masque"
#define STRING_COLUMN_LABEL_MASK_IDX "Indice de masque"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Tâche mère"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Date"
#define STRING_COLUMN_LABEL_COLUMN "Colonnes"
#define STRING_COLUMN_LABEL_STYLES "Formats supportés"

View file

@ -210,7 +210,10 @@
#define STRING_COLUMN_LABEL_VALUE "Valore"
#define STRING_COLUMN_LABEL_MASK "Maschera"
#define STRING_COLUMN_LABEL_MASK_IDX "Indice Maschera"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Task genitore"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Data"
#define STRING_COLUMN_LABEL_COLUMN "Colonna"
#define STRING_COLUMN_LABEL_STYLES "Formati Supportati"

View file

@ -210,7 +210,10 @@
#define STRING_COLUMN_LABEL_VALUE "Value"
#define STRING_COLUMN_LABEL_MASK "Mask"
#define STRING_COLUMN_LABEL_MASK_IDX "Mask Index"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Parent task"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Date"
#define STRING_COLUMN_LABEL_COLUMN "Columns"
#define STRING_COLUMN_LABEL_STYLES "Supported Formats"

View file

@ -210,7 +210,10 @@
#define STRING_COLUMN_LABEL_VALUE "Wartość"
#define STRING_COLUMN_LABEL_MASK "Maska"
#define STRING_COLUMN_LABEL_MASK_IDX "Indeks Maski"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Zadanie rodzic"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Data"
#define STRING_COLUMN_LABEL_COLUMN "Kolumny"
#define STRING_COLUMN_LABEL_STYLES "Formaty"

View file

@ -211,7 +211,10 @@
#define STRING_COLUMN_LABEL_VALUE "Valor"
#define STRING_COLUMN_LABEL_MASK "Máscara"
#define STRING_COLUMN_LABEL_MASK_IDX "Índice de Máscara"
#define STRING_COLUMN_LABEL_LAST "Last instance"
#define STRING_COLUMN_LABEL_RTYPE "Recurrence type"
#define STRING_COLUMN_LABEL_PARENT "Tarefa mãe"
#define STRING_COLUMN_LABEL_TEMPLATE "Template task"
#define STRING_COLUMN_LABEL_DATE "Data"
#define STRING_COLUMN_LABEL_COLUMN "Colunas"
#define STRING_COLUMN_LABEL_STYLES "Formatos Suportados"

View file

@ -52,8 +52,8 @@ std::string colorizeError (const std::string&);
std::string colorizeDebug (const std::string&);
// dependency.cpp
void dependencyGetBlocked (const Task&, std::vector <Task>&);
void dependencyGetBlocking (const Task&, std::vector <Task>&);
std::vector <Task> dependencyGetBlocked (const Task&);
std::vector <Task> dependencyGetBlocking (const Task&);
bool dependencyIsCircular (const Task&);
void dependencyChainOnComplete (Task&);
void dependencyChainOnStart (Task&);