taskjuggler 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +44 -0
- data/bin/tj3webd +4 -0
- data/data/css/tjreport.css +14 -5
- data/data/tjp.vim +22 -7
- data/examples/Fedora-20/reports.tji +2 -4
- data/examples/Scrum/Product Burndown.csv +26 -0
- data/examples/Scrum/Sprint 1 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 2 Burndown.csv +26 -0
- data/examples/Scrum/Sprint 3 Burndown.csv +26 -0
- data/examples/Scrum/scrum.tjp +141 -0
- data/examples/Tutorial/tutorial.tjp +13 -7
- data/lib/taskjuggler/Attributes.rb +2 -3
- data/lib/taskjuggler/HTMLDocument.rb +25 -18
- data/lib/taskjuggler/Journal.rb +85 -65
- data/lib/taskjuggler/KeywordDocumentation.rb +25 -13
- data/lib/taskjuggler/LeaveList.rb +1 -1
- data/lib/taskjuggler/Limits.rb +3 -5
- data/lib/taskjuggler/MessageHandler.rb +173 -19
- data/lib/taskjuggler/Painter.rb +75 -0
- data/lib/taskjuggler/Painter/BasicShapes.rb +76 -0
- data/lib/taskjuggler/Painter/Color.rb +273 -0
- data/lib/taskjuggler/Painter/Element.rb +56 -0
- data/lib/taskjuggler/Painter/FontData.rb +221 -0
- data/lib/taskjuggler/Painter/FontMetrics.rb +125 -0
- data/lib/taskjuggler/Painter/FontMetricsData.rb +151 -0
- data/lib/taskjuggler/Painter/Group.rb +77 -0
- data/lib/taskjuggler/Painter/Points.rb +47 -0
- data/lib/taskjuggler/Painter/Primitives.rb +100 -0
- data/lib/taskjuggler/Painter/SVGSupport.rb +36 -0
- data/lib/taskjuggler/Painter/Text.rb +36 -0
- data/lib/taskjuggler/Project.rb +46 -29
- data/lib/taskjuggler/ProjectFileParser.rb +24 -22
- data/lib/taskjuggler/ProjectFileScanner.rb +2 -2
- data/lib/taskjuggler/PropertyTreeNode.rb +26 -34
- data/lib/taskjuggler/Query.rb +8 -5
- data/lib/taskjuggler/RealFormat.rb +3 -0
- data/lib/taskjuggler/Resource.rb +3 -5
- data/lib/taskjuggler/ResourceScenario.rb +19 -7
- data/lib/taskjuggler/RichText.rb +4 -6
- data/lib/taskjuggler/RichText/FunctionExample.rb +1 -1
- data/lib/taskjuggler/RichText/FunctionHandler.rb +5 -6
- data/lib/taskjuggler/RichText/Parser.rb +4 -6
- data/lib/taskjuggler/RichText/RTFNavigator.rb +1 -1
- data/lib/taskjuggler/RichText/RTFQuery.rb +2 -3
- data/lib/taskjuggler/RichText/RTFReport.rb +1 -1
- data/lib/taskjuggler/RichText/RTFReportLink.rb +1 -2
- data/lib/taskjuggler/RichText/RTFWithQuerySupport.rb +1 -1
- data/lib/taskjuggler/RichText/Scanner.rb +6 -6
- data/lib/taskjuggler/RichText/Snip.rb +1 -2
- data/lib/taskjuggler/RuntimeConfig.rb +9 -6
- data/lib/taskjuggler/ScenarioData.rb +4 -3
- data/lib/taskjuggler/Scoreboard.rb +6 -0
- data/lib/taskjuggler/SheetHandlerBase.rb +25 -8
- data/lib/taskjuggler/SimpleQueryExpander.rb +14 -5
- data/lib/taskjuggler/SyntaxReference.rb +1 -2
- data/lib/taskjuggler/TableColumnSorter.rb +84 -0
- data/lib/taskjuggler/Task.rb +3 -5
- data/lib/taskjuggler/TaskJuggler.rb +36 -29
- data/lib/taskjuggler/TaskScenario.rb +154 -66
- data/lib/taskjuggler/TextParser.rb +24 -17
- data/lib/taskjuggler/TextParser/Scanner.rb +16 -11
- data/lib/taskjuggler/TextParser/SourceFileInfo.rb +20 -15
- data/lib/taskjuggler/TimeSheets.rb +6 -12
- data/lib/taskjuggler/Tj3AppBase.rb +35 -16
- data/lib/taskjuggler/Tj3Config.rb +1 -1
- data/lib/taskjuggler/TjpSyntaxRules.rb +239 -49
- data/lib/taskjuggler/XMLElement.rb +9 -2
- data/lib/taskjuggler/apps/Tj3.rb +43 -37
- data/lib/taskjuggler/apps/Tj3Client.rb +62 -112
- data/lib/taskjuggler/apps/Tj3Daemon.rb +66 -29
- data/lib/taskjuggler/apps/Tj3Man.rb +5 -5
- data/lib/taskjuggler/apps/Tj3SsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3SsSender.rb +13 -16
- data/lib/taskjuggler/apps/Tj3TsReceiver.rb +10 -13
- data/lib/taskjuggler/apps/Tj3TsSender.rb +12 -15
- data/lib/taskjuggler/apps/Tj3TsSummary.rb +12 -15
- data/lib/taskjuggler/apps/Tj3WebD.rb +99 -0
- data/lib/taskjuggler/daemon/Daemon.rb +50 -10
- data/lib/taskjuggler/daemon/DaemonConnector.rb +127 -0
- data/lib/taskjuggler/daemon/ProcessIntercom.rb +36 -21
- data/lib/taskjuggler/daemon/ProjectBroker.rb +122 -112
- data/lib/taskjuggler/daemon/ProjectServer.rb +78 -46
- data/lib/taskjuggler/daemon/ReportServer.rb +52 -28
- data/lib/taskjuggler/daemon/ReportServlet.rb +92 -21
- data/lib/taskjuggler/daemon/WebServer.rb +75 -22
- data/lib/taskjuggler/daemon/WelcomePage.rb +1 -0
- data/lib/taskjuggler/reports/AccountListRE.rb +3 -3
- data/lib/taskjuggler/reports/CSVFile.rb +9 -2
- data/lib/taskjuggler/reports/ChartPlotter.rb +453 -0
- data/lib/taskjuggler/reports/Navigator.rb +1 -0
- data/lib/taskjuggler/reports/NikuReport.rb +4 -4
- data/lib/taskjuggler/reports/Report.rb +6 -18
- data/lib/taskjuggler/reports/ReportBase.rb +9 -9
- data/lib/taskjuggler/reports/ReportContext.rb +2 -2
- data/lib/taskjuggler/reports/StatusSheetReport.rb +6 -6
- data/lib/taskjuggler/reports/TableReport.rb +24 -15
- data/lib/taskjuggler/reports/TimeSheetReport.rb +5 -5
- data/lib/taskjuggler/reports/TraceReport.rb +251 -0
- data/lib/tj3webd.rb +17 -0
- data/manual/Day_To_Day_Juggling +10 -3
- data/manual/Installation +38 -19
- data/manual/Software +25 -19
- data/manual/Tutorial +119 -110
- data/manual/html/Day_To_Day_Juggling.html +7 -5
- data/manual/html/Getting_Started.html +4 -4
- data/manual/html/How_To_Contribute.html +4 -4
- data/manual/html/Installation.html +19 -11
- data/manual/html/Intro.html +4 -4
- data/manual/html/Reporting_Bugs.html +4 -4
- data/manual/html/Rich_Text_Attributes.html +4 -4
- data/manual/html/Software.html +15 -11
- data/manual/html/TaskJuggler_2x_Migration.html +4 -4
- data/manual/html/TaskJuggler_Internals.html +4 -4
- data/manual/html/The_TaskJuggler_Syntax.html +4 -4
- data/manual/html/Tutorial.html +41 -32
- data/manual/html/account.html +4 -4
- data/manual/html/account.task.html +4 -4
- data/manual/html/accountprefix.html +4 -4
- data/manual/html/accountreport.html +27 -9
- data/manual/html/accountroot.html +5 -5
- data/manual/html/active.html +4 -4
- data/manual/html/adopt.task.html +4 -4
- data/manual/html/aggregate.html +4 -4
- data/manual/html/alert.html +4 -4
- data/manual/html/alertlevels.html +4 -4
- data/manual/html/allocate.html +5 -5
- data/manual/html/alphabet.html +4 -4
- data/manual/html/alternative.html +4 -4
- data/manual/html/author.html +4 -4
- data/manual/html/balance.html +5 -5
- data/manual/html/booking.resource.html +4 -4
- data/manual/html/booking.task.html +4 -4
- data/manual/html/caption.html +5 -5
- data/manual/html/cellcolor.column.html +43 -8
- data/manual/html/celltext.column.html +4 -4
- data/manual/html/center.html +5 -5
- data/manual/html/charge.html +4 -4
- data/manual/html/chargeset.html +4 -4
- data/manual/html/columnid.html +27 -15
- data/manual/html/columns.html +5 -5
- data/manual/html/complete.html +4 -4
- data/manual/html/copyright.html +4 -4
- data/manual/html/credits.html +4 -4
- data/manual/html/css/tjreport.css +14 -5
- data/manual/html/currency.html +4 -4
- data/manual/html/currencyformat.html +5 -5
- data/manual/html/dailymax.html +5 -5
- data/manual/html/dailymin.html +5 -5
- data/manual/html/dailyworkinghours.html +4 -4
- data/manual/html/date.extend.html +4 -4
- data/manual/html/date.html +5 -5
- data/manual/html/definitions.html +4 -4
- data/manual/html/depends.html +4 -4
- data/manual/html/details.html +4 -4
- data/manual/html/disabled.html +4 -4
- data/manual/html/duration.html +4 -4
- data/manual/html/efficiency.html +4 -4
- data/manual/html/effort.html +4 -4
- data/manual/html/email.html +4 -4
- data/manual/html/enabled.html +4 -4
- data/manual/html/end.column.html +4 -4
- data/manual/html/end.html +4 -4
- data/manual/html/end.limit.html +4 -4
- data/manual/html/end.report.html +5 -5
- data/manual/html/end.timesheet.html +4 -4
- data/manual/html/endcredit.html +4 -4
- data/manual/html/epilog.html +5 -5
- data/manual/html/export.html +4 -4
- data/manual/html/extend.html +4 -4
- data/manual/html/fail.html +43 -8
- data/manual/html/fdl.html +4 -4
- data/manual/html/flags.account.html +4 -4
- data/manual/html/flags.html +4 -4
- data/manual/html/flags.journalentry.html +4 -4
- data/manual/html/flags.report.html +5 -5
- data/manual/html/flags.resource.html +4 -4
- data/manual/html/flags.statussheet.html +4 -4
- data/manual/html/flags.task.html +4 -4
- data/manual/html/flags.timesheet.html +4 -4
- data/manual/html/fontcolor.column.html +43 -8
- data/manual/html/footer.html +5 -5
- data/manual/html/formats.html +5 -5
- data/manual/html/functions.html +4 -4
- data/manual/html/gapduration.html +4 -4
- data/manual/html/gaplength.html +4 -4
- data/manual/html/halign.center.html +4 -4
- data/manual/html/halign.column.html +43 -8
- data/manual/html/halign.left.html +4 -4
- data/manual/html/halign.right.html +4 -4
- data/manual/html/hasalert.html +4 -4
- data/manual/html/header.html +5 -5
- data/manual/html/headline.html +7 -7
- data/manual/html/height.html +72 -0
- data/manual/html/hideaccount.html +46 -11
- data/manual/html/hidejournalentry.html +5 -5
- data/manual/html/hidereport.html +43 -8
- data/manual/html/hideresource.html +44 -9
- data/manual/html/hidetask.html +44 -9
- data/manual/html/icalreport.html +4 -4
- data/manual/html/include.macro.html +4 -4
- data/manual/html/include.project.html +4 -4
- data/manual/html/include.properties.html +4 -4
- data/manual/html/index.html +2 -1
- data/manual/html/inherit.extend.html +4 -4
- data/manual/html/interval1.html +4 -4
- data/manual/html/interval2.html +4 -4
- data/manual/html/interval3.html +4 -4
- data/manual/html/interval4.html +4 -4
- data/manual/html/isactive.html +4 -4
- data/manual/html/ischildof.html +4 -4
- data/manual/html/isdependencyof.html +4 -4
- data/manual/html/isdutyof.html +4 -4
- data/manual/html/isfeatureof.html +4 -4
- data/manual/html/isleaf.html +4 -4
- data/manual/html/ismilestone.html +4 -4
- data/manual/html/isongoing.html +4 -4
- data/manual/html/isresource.html +4 -4
- data/manual/html/isresponsibilityof.html +4 -4
- data/manual/html/istask.html +4 -4
- data/manual/html/journalattributes.html +11 -7
- data/manual/html/journalentry.html +4 -4
- data/manual/html/journalmode.html +5 -5
- data/manual/html/leaveallowance.html +5 -5
- data/manual/html/leaves.html +5 -6
- data/manual/html/left.html +5 -5
- data/manual/html/length.html +4 -4
- data/manual/html/limits.allocate.html +4 -4
- data/manual/html/limits.html +4 -4
- data/manual/html/limits.resource.html +4 -4
- data/manual/html/limits.task.html +4 -4
- data/manual/html/listitem.column.html +4 -4
- data/manual/html/listtype.column.html +4 -4
- data/manual/html/loadunit.html +5 -5
- data/manual/html/logicalexpression.html +8 -44
- data/manual/html/logicalflagexpression.html +4 -4
- data/manual/html/macro.html +4 -4
- data/manual/html/managers.html +4 -4
- data/manual/html/mandatory.html +4 -4
- data/manual/html/maxend.html +4 -4
- data/manual/html/maximum.html +5 -5
- data/manual/html/maxstart.html +4 -4
- data/manual/html/milestone.html +4 -4
- data/manual/html/minend.html +4 -4
- data/manual/html/minimum.html +5 -5
- data/manual/html/minstart.html +4 -4
- data/manual/html/monthlymax.html +5 -5
- data/manual/html/monthlymin.html +5 -5
- data/manual/html/navbar.html +10 -4
- data/manual/html/navigator.html +4 -4
- data/manual/html/newtask.html +4 -4
- data/manual/html/nikureport.html +4 -4
- data/manual/html/note.task.html +4 -4
- data/manual/html/now.html +4 -4
- data/manual/html/numberformat.html +5 -5
- data/manual/html/onend.html +4 -4
- data/manual/html/onstart.html +4 -4
- data/manual/html/opennodes.html +5 -5
- data/manual/html/overtime.booking.html +4 -4
- data/manual/html/period.column.html +4 -4
- data/manual/html/period.limit.html +4 -4
- data/manual/html/period.report.html +5 -5
- data/manual/html/period.task.html +4 -4
- data/manual/html/persistent.html +4 -4
- data/manual/html/precedes.html +4 -4
- data/manual/html/priority.html +4 -4
- data/manual/html/priority.timesheet.html +4 -4
- data/manual/html/project.html +4 -4
- data/manual/html/projectid.html +4 -4
- data/manual/html/projectid.task.html +4 -4
- data/manual/html/projectids.html +4 -4
- data/manual/html/projection.html +5 -7
- data/manual/html/prolog.html +5 -5
- data/manual/html/properties.html +11 -5
- data/manual/html/purge.html +5 -5
- data/manual/html/rate.html +4 -4
- data/manual/html/rate.resource.html +4 -4
- data/manual/html/reference.extend.html +4 -4
- data/manual/html/remaining.html +4 -4
- data/manual/html/replace.html +4 -4
- data/manual/html/reportprefix.html +4 -4
- data/manual/html/resource.html +4 -10
- data/manual/html/resourceattributes.html +4 -4
- data/manual/html/resourceprefix.html +4 -4
- data/manual/html/resourcereport.html +28 -10
- data/manual/html/resourceroot.html +5 -5
- data/manual/html/resources.limit.html +4 -4
- data/manual/html/responsible.html +4 -4
- data/manual/html/richtext.extend.html +4 -4
- data/manual/html/right.html +5 -5
- data/manual/html/rollupaccount.html +44 -9
- data/manual/html/rollupresource.html +44 -9
- data/manual/html/rolluptask.html +44 -9
- data/manual/html/scale.column.html +4 -4
- data/manual/html/scenario.html +4 -22
- data/manual/html/scenario.ical.html +4 -4
- data/manual/html/scenarios.export.html +4 -4
- data/manual/html/scenarios.html +5 -5
- data/manual/html/scenariospecific.extend.html +4 -4
- data/manual/html/scheduled.html +4 -4
- data/manual/html/scheduling.html +4 -4
- data/manual/html/select.html +4 -4
- data/manual/html/selfcontained.html +5 -5
- data/manual/html/shift.allocate.html +4 -4
- data/manual/html/shift.html +4 -4
- data/manual/html/shift.resource.html +5 -5
- data/manual/html/shift.task.html +4 -4
- data/manual/html/shift.timesheet.html +4 -4
- data/manual/html/shifts.allocate.html +4 -4
- data/manual/html/shifts.resource.html +4 -4
- data/manual/html/shifts.task.html +4 -4
- data/manual/html/shorttimeformat.html +4 -4
- data/manual/html/sloppy.booking.html +4 -4
- data/manual/html/sloppy.projection.html +5 -5
- data/manual/html/sortaccounts.html +5 -5
- data/manual/html/sortjournalentries.html +5 -5
- data/manual/html/sortresources.html +5 -5
- data/manual/html/sorttasks.html +5 -5
- data/manual/html/start.column.html +4 -4
- data/manual/html/start.html +4 -4
- data/manual/html/start.limit.html +4 -4
- data/manual/html/start.report.html +5 -5
- data/manual/html/startcredit.html +4 -4
- data/manual/html/status.statussheet.html +4 -4
- data/manual/html/status.timesheet.html +4 -4
- data/manual/html/statussheet.html +4 -4
- data/manual/html/statussheetreport.html +4 -4
- data/manual/html/strict.projection.html +5 -5
- data/manual/html/summary.html +4 -4
- data/manual/html/supplement.html +4 -4
- data/manual/html/supplement.resource.html +4 -10
- data/manual/html/supplement.task.html +4 -28
- data/manual/html/tagfile.html +4 -4
- data/manual/html/task.html +4 -28
- data/manual/html/task.statussheet.html +4 -4
- data/manual/html/task.timesheet.html +4 -4
- data/manual/html/taskattributes.html +4 -4
- data/manual/html/taskprefix.html +4 -4
- data/manual/html/taskreport.html +28 -10
- data/manual/html/taskroot.html +5 -5
- data/manual/html/text.extend.html +4 -4
- data/manual/html/textreport.html +27 -9
- data/manual/html/timeformat.html +5 -5
- data/manual/html/timeoff.nikureport.html +4 -4
- data/manual/html/timesheet.html +4 -4
- data/manual/html/timesheetreport.html +23 -5
- data/manual/html/timezone.export.html +4 -4
- data/manual/html/timezone.html +4 -4
- data/manual/html/timezone.report.html +5 -5
- data/manual/html/timezone.shift.html +4 -4
- data/manual/html/timingresolution.html +4 -4
- data/manual/html/title.column.html +4 -4
- data/manual/html/title.html +5 -5
- data/manual/html/toc.html +207 -179
- data/manual/html/tooltip.column.html +45 -10
- data/manual/html/tracereport.html +405 -0
- data/manual/html/trackingscenario.html +6 -6
- data/manual/html/treelevel.html +4 -4
- data/manual/html/vacation.html +4 -4
- data/manual/html/vacation.resource.html +4 -4
- data/manual/html/vacation.shift.html +4 -4
- data/manual/html/warn.html +43 -8
- data/manual/html/weeklymax.html +5 -5
- data/manual/html/weeklymin.html +5 -5
- data/manual/html/weekstartsmonday.html +4 -4
- data/manual/html/weekstartssunday.html +6 -6
- data/manual/html/width.column.html +6 -6
- data/manual/html/width.html +72 -0
- data/manual/html/work.html +4 -4
- data/manual/html/workinghours.project.html +4 -4
- data/manual/html/workinghours.resource.html +4 -4
- data/manual/html/workinghours.shift.html +4 -4
- data/manual/html/yearlyworkingdays.html +4 -4
- data/spec/Color_spec.rb +60 -0
- data/spec/ProjectBroker_spec.rb +3 -2
- data/spec/StatusSheets_spec.rb +5 -4
- data/spec/TableColumnSorter_spec.rb +78 -0
- data/spec/TimeSheets_spec.rb +6 -2
- data/spec/Tj3Daemon_spec.rb +2 -2
- data/spec/TraceReport_spec.rb +117 -0
- data/taskjuggler.gemspec +1 -1
- data/test/MessageChecker.rb +3 -1
- data/test/ReferenceGenerator.rb +1 -1
- data/test/TestSuite/CSV-Reports/Leave.tjp +1 -1
- data/test/TestSuite/CSV-Reports/refs/resourcereport_with_tasks.csv +3 -0
- data/test/TestSuite/CSV-Reports/refs/taskcounter.csv +9 -0
- data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +19 -16
- data/test/TestSuite/CSV-Reports/refs/weekly.csv +1 -0
- data/test/TestSuite/Export-Reports/refs/LogicalExpression.tjp +14 -2
- data/test/TestSuite/Export-Reports/refs/tutorial.tjp +98 -86
- data/test/TestSuite/Scheduler/Correct/Leaves.tjp +25 -0
- data/test/TestSuite/Syntax/Correct/Leave.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/LogicalExpression.tjp +9 -1
- data/test/TestSuite/Syntax/Correct/TraceReport.tjp +10 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +10 -4
- data/test/test_CSV-Reports.rb +3 -3
- data/test/test_Export-Reports.rb +91 -86
- data/test/test_Journal.rb +15 -12
- data/test/test_Limits.rb +3 -3
- data/test/test_Project.rb +1 -2
- data/test/test_ProjectFileScanner.rb +1 -1
- data/test/test_PropertySet.rb +1 -1
- data/test/test_Query.rb +5 -6
- data/test/test_ReportGenerator.rb +15 -7
- data/test/test_RichText.rb +4 -3
- data/test/test_Scheduler.rb +19 -7
- data/test/test_ShiftAssignments.rb +2 -2
- data/test/test_SimpleQueryExpander.rb +29 -2
- data/test/test_Syntax.rb +14 -5
- metadata +49 -10
- data/lib/taskjuggler/LogFile.rb +0 -73
data/lib/taskjuggler/Limits.rb
CHANGED
@@ -94,9 +94,7 @@ class TaskJuggler
|
|
94
94
|
def ok?(index, upper, resource)
|
95
95
|
# if @upper does not match or the provided resource does not match,
|
96
96
|
# we can ignore this limit.
|
97
|
-
return true if @upper != upper ||
|
98
|
-
(!@resource.nil? ^ !resource.nil?) ||
|
99
|
-
(@resource && resource && @resource != resource)
|
97
|
+
return true if @upper != upper || (@resource && @resource != resource)
|
100
98
|
|
101
99
|
if index.nil?
|
102
100
|
# No index given. We need to check all counters.
|
@@ -109,8 +107,8 @@ class TaskJuggler
|
|
109
107
|
# anything. Everything is ok.
|
110
108
|
return true if !@interval.contains?(index)
|
111
109
|
|
112
|
-
|
113
|
-
|
110
|
+
sbVal = @scoreboard[idxToSbIdx(index)]
|
111
|
+
return @upper ? (sbVal < @value) : (sbVal >= @value)
|
114
112
|
end
|
115
113
|
end
|
116
114
|
|
@@ -15,18 +15,23 @@ if RUBY_VERSION < "1.9.0"
|
|
15
15
|
require 'rubygems'
|
16
16
|
end
|
17
17
|
|
18
|
+
require 'singleton'
|
18
19
|
require 'term/ansicolor'
|
19
20
|
require 'taskjuggler/TextParser/SourceFileInfo'
|
20
21
|
|
21
22
|
class TaskJuggler
|
22
23
|
|
24
|
+
class TjRuntimeError < RuntimeError
|
25
|
+
end
|
26
|
+
|
23
27
|
# The Message object can store several classes of messages that the
|
24
28
|
# application can send out.
|
25
29
|
class Message
|
26
30
|
|
27
31
|
include Term::ANSIColor
|
28
32
|
|
29
|
-
attr_reader :type, :id, :message, :
|
33
|
+
attr_reader :type, :id, :message, :line
|
34
|
+
attr_accessor :sourceFileInfo
|
30
35
|
|
31
36
|
# Create a new Message object. The _type_ specifies what tpye of message
|
32
37
|
# this is. The following types are supported: fatal, error, warning, info
|
@@ -68,7 +73,7 @@ class TaskJuggler
|
|
68
73
|
@scenario = scenario
|
69
74
|
end
|
70
75
|
|
71
|
-
# Convert the Message into a String.
|
76
|
+
# Convert the Message into a String that can be printed to the console.
|
72
77
|
def to_s
|
73
78
|
str = ""
|
74
79
|
# The SourceFileInfo is printed as <fileName>:line:
|
@@ -87,26 +92,81 @@ class TaskJuggler
|
|
87
92
|
str
|
88
93
|
end
|
89
94
|
|
95
|
+
# Convert the Message into a String that can be stored in a log file.
|
96
|
+
def to_log
|
97
|
+
str = ""
|
98
|
+
# The SourceFileInfo is printed as <fileName>:line:
|
99
|
+
if @sourceFileInfo
|
100
|
+
str += "#{@sourceFileInfo.fileName}:#{sourceFileInfo.lineNo}: "
|
101
|
+
end
|
102
|
+
str += "Scenario #{@scenario.id}: " if @scenario
|
103
|
+
str += @message
|
104
|
+
str
|
105
|
+
end
|
106
|
+
|
90
107
|
end
|
91
108
|
|
92
109
|
# The MessageHandler can display and store application messages. Depending
|
93
110
|
# on the type of the message, a TjExeption can be raised (:error), or the
|
94
111
|
# program can be immedidately aborted (:fatal). Other types will just
|
95
112
|
# continue the program flow.
|
96
|
-
class
|
113
|
+
class MessageHandlerInstance
|
114
|
+
|
115
|
+
include Singleton
|
97
116
|
|
98
117
|
attr_reader :messages, :errors
|
99
|
-
attr_accessor :
|
118
|
+
attr_accessor :logFile, :appName, :abortOnWarning, :trapSetup, :baselineSFI
|
100
119
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
120
|
+
LogLevels = { :none => 0, :fatal => 1, :error => 2, :critical => 2,
|
121
|
+
:warning => 3, :info => 4, :debug => 5 }
|
122
|
+
|
123
|
+
# Initialize the MessageHandler.
|
124
|
+
def initialize
|
125
|
+
reset
|
126
|
+
end
|
127
|
+
|
128
|
+
# Reset the MessageHandler to the initial state. All messages will be
|
129
|
+
# purged and the error counter set to 0.
|
130
|
+
def reset
|
131
|
+
# This setting controls what type of messages will be written to the
|
132
|
+
# console.
|
133
|
+
@outputLevel = 4
|
134
|
+
# This setting controls what type of messages will be written to the log
|
135
|
+
# file.
|
136
|
+
@logLevel = 3
|
137
|
+
# The full file name of the log file.
|
138
|
+
@logFile = nil
|
139
|
+
# The name of the current application
|
140
|
+
@appName = 'unknown'
|
108
141
|
# Set to true if program should be exited on warnings.
|
109
142
|
@abortOnWarning = false
|
143
|
+
# A SourceFileInfo object that will be used to baseline the provided
|
144
|
+
# source file infos of the messages.
|
145
|
+
@baselineSFI = nil
|
146
|
+
# If this is set the true, we only throw a TjRuntimeError instead of
|
147
|
+
# using exit().
|
148
|
+
@trapSetup = false
|
149
|
+
|
150
|
+
clear
|
151
|
+
end
|
152
|
+
|
153
|
+
# Clear the error log.
|
154
|
+
def clear
|
155
|
+
# A counter for messages of type error.
|
156
|
+
@errors = 0
|
157
|
+
# A list of all generated messages.
|
158
|
+
@messages = []
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
# Set the console output level.
|
163
|
+
def outputLevel=(level)
|
164
|
+
@outputLevel = checkLevel(level)
|
165
|
+
end
|
166
|
+
|
167
|
+
# Set the log output level.
|
168
|
+
def logLevel=(level)
|
169
|
+
@logLevel = checkLevel(level)
|
110
170
|
end
|
111
171
|
|
112
172
|
# Generate a fatal message that will abort the application.
|
@@ -142,19 +202,70 @@ class TaskJuggler
|
|
142
202
|
# Generate a debug message.
|
143
203
|
def debug(id, message, sourceFileInfo = nil, line = nil, data = nil,
|
144
204
|
scenario = nil)
|
145
|
-
addMessage(:
|
205
|
+
addMessage(:debug, id, message, sourceFileInfo, line, data, scenario)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Convert all messages into a single String.
|
209
|
+
def to_s
|
210
|
+
text = ''
|
211
|
+
@messages.each { |msg| text += msg.to_s }
|
212
|
+
text
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
def checkLevel(level)
|
218
|
+
if level.is_a?(Fixnum)
|
219
|
+
if level < 0 || level > 5
|
220
|
+
raise ArgumentError, "Unsupported level #{level}"
|
221
|
+
end
|
222
|
+
else
|
223
|
+
unless (level = LogLevels[level])
|
224
|
+
raise ArgumentError, "Unsupported level #{level}"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
level
|
229
|
+
end
|
230
|
+
|
231
|
+
def log(type, message)
|
232
|
+
return unless @logFile
|
233
|
+
|
234
|
+
timeStamp = Time.new.strftime("%Y-%m-%d %H:%M:%S")
|
235
|
+
begin
|
236
|
+
@logFile.untaint
|
237
|
+
File.open(@logFile, 'a') do |f|
|
238
|
+
f.write("#{timeStamp} #{type} #{@appName}[#{Process.pid}]: " +
|
239
|
+
"#{message}\n")
|
240
|
+
end
|
241
|
+
rescue
|
242
|
+
$stderr.puts "Cannot write to log file #{@logFile}: #{$!}"
|
243
|
+
end
|
146
244
|
end
|
147
245
|
|
148
246
|
# Generate a message by specifying the _type_.
|
149
247
|
def addMessage(type, id, message, sourceFileInfo = nil, line = nil,
|
150
248
|
data = nil, scenario = nil)
|
249
|
+
# If we have a SourceFileInfo and a baseline SFI, we correct the
|
250
|
+
# sourceFileInfo accordingly.
|
251
|
+
if sourceFileInfo && @baselineSFI
|
252
|
+
sourceFileInfo = TextParser::SourceFileInfo.new(
|
253
|
+
@baselineSFI.fileName,
|
254
|
+
sourceFileInfo.lineNo + @baselineSFI.lineNo - 1,
|
255
|
+
sourceFileInfo.columnNo)
|
256
|
+
end
|
257
|
+
|
151
258
|
# Treat criticals like errors but without generating another
|
152
259
|
# exception.
|
153
260
|
msg = Message.new(type == :critical ? :error : type, id, message,
|
154
261
|
sourceFileInfo, line, data, scenario)
|
155
262
|
@messages << msg
|
263
|
+
|
264
|
+
# Append the message to the log file if requested by the user.
|
265
|
+
log(type, msg.to_log) if @logLevel >= LogLevels[type]
|
266
|
+
|
156
267
|
# Print the message to $stderr if requested by the user.
|
157
|
-
$stderr.puts msg.to_s if @
|
268
|
+
$stderr.puts msg.to_s if @outputLevel >= LogLevels[type]
|
158
269
|
|
159
270
|
case type
|
160
271
|
when :warning
|
@@ -165,17 +276,60 @@ class TaskJuggler
|
|
165
276
|
when :error
|
166
277
|
# Increase the error counter.
|
167
278
|
@errors += 1
|
168
|
-
|
279
|
+
if @trapSetup
|
280
|
+
raise TjRuntimeError
|
281
|
+
else
|
282
|
+
exit 1
|
283
|
+
end
|
169
284
|
when :fatal
|
170
285
|
raise RuntimeError
|
171
286
|
end
|
172
287
|
end
|
173
288
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
289
|
+
end
|
290
|
+
|
291
|
+
module MessageHandler
|
292
|
+
|
293
|
+
# Generate a fatal message that will abort the application.
|
294
|
+
def fatal(id, message, sourceFileInfo = nil, line = nil, data = nil,
|
295
|
+
scenario = nil)
|
296
|
+
MessageHandlerInstance.instance.fatal(id, message, sourceFileInfo, line,
|
297
|
+
data, scenario)
|
298
|
+
end
|
299
|
+
|
300
|
+
# Generate an error message.
|
301
|
+
def error(id, message, sourceFileInfo = nil, line = nil, data = nil,
|
302
|
+
scenario = nil)
|
303
|
+
MessageHandlerInstance.instance.error(id, message, sourceFileInfo, line,
|
304
|
+
data, scenario)
|
305
|
+
end
|
306
|
+
|
307
|
+
# Generate an critical message.
|
308
|
+
def critical(id, message, sourceFileInfo = nil, line = nil, data = nil,
|
309
|
+
scenario = nil)
|
310
|
+
MessageHandlerInstance.instance.critical(id, message, sourceFileInfo,
|
311
|
+
line, data, scenario)
|
312
|
+
end
|
313
|
+
|
314
|
+
# Generate a warning.
|
315
|
+
def warning(id, message, sourceFileInfo = nil, line = nil, data = nil,
|
316
|
+
scenario = nil)
|
317
|
+
MessageHandlerInstance.instance.warning(id, message, sourceFileInfo,
|
318
|
+
line, data, scenario)
|
319
|
+
end
|
320
|
+
|
321
|
+
# Generate an info message.
|
322
|
+
def info(id, message, sourceFileInfo = nil, line = nil, data = nil,
|
323
|
+
scenario = nil)
|
324
|
+
MessageHandlerInstance.instance.info(id, message, sourceFileInfo, line,
|
325
|
+
data, scenario)
|
326
|
+
end
|
327
|
+
|
328
|
+
# Generate a debug message.
|
329
|
+
def debug(id, message, sourceFileInfo = nil, line = nil, data = nil,
|
330
|
+
scenario = nil)
|
331
|
+
MessageHandlerInstance.instance.debug(id, message, sourceFileInfo, line,
|
332
|
+
data, scenario)
|
179
333
|
end
|
180
334
|
|
181
335
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = Painter.rb -- The TaskJuggler III Project Management Software
|
5
|
+
#
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
|
+
# by Chris Schlaeger <chris@linux.com>
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify
|
10
|
+
# it under the terms of version 2 of the GNU General Public License as
|
11
|
+
# published by the Free Software Foundation.
|
12
|
+
#
|
13
|
+
|
14
|
+
require 'taskjuggler/XMLElement'
|
15
|
+
require 'taskjuggler/Painter/Primitives'
|
16
|
+
require 'taskjuggler/Painter/Group'
|
17
|
+
require 'taskjuggler/Painter/BasicShapes'
|
18
|
+
require 'taskjuggler/Painter/Text'
|
19
|
+
require 'taskjuggler/Painter/FontMetrics'
|
20
|
+
|
21
|
+
class TaskJuggler
|
22
|
+
|
23
|
+
# This is a vector drawing class. It can describe a canvas with lines,
|
24
|
+
# rectangles, circles, ellipses and text elements on it. The elements can be
|
25
|
+
# grouped. It currently only supports rendering as an SVG output.
|
26
|
+
class Painter
|
27
|
+
|
28
|
+
include Primitives
|
29
|
+
|
30
|
+
# Create a canvas of dimension _width_ times _height_. The block can be
|
31
|
+
# used to add elements to the drawing. If the block has an argument, the
|
32
|
+
# block content is evaluated within the current context. If no argument is
|
33
|
+
# provided, the newly created object will be the evaluation context of the
|
34
|
+
# block. This will make instance variables of the caller inaccessible.
|
35
|
+
# Methods of the caller will still be available.
|
36
|
+
def initialize(width, height, &block)
|
37
|
+
@width = width
|
38
|
+
@height = height
|
39
|
+
|
40
|
+
@elements = []
|
41
|
+
if block
|
42
|
+
if block.arity == 1
|
43
|
+
# This is the traditional case where self is passed to the block.
|
44
|
+
# All Primitives methods now must be prefixed with the block
|
45
|
+
# variable to call them.
|
46
|
+
yield self
|
47
|
+
else
|
48
|
+
# In order to have the primitives easily available in the block, we
|
49
|
+
# use instance_eval to switch self to this object. But this makes the
|
50
|
+
# methods of the original self no longer accessible. We work around
|
51
|
+
# this by saving the original self and using method_missing to
|
52
|
+
# delegate the method call to the original self.
|
53
|
+
@originalSelf = eval('self', block.binding)
|
54
|
+
instance_eval(&block)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Delegator to @originalSelf.
|
60
|
+
def method_missing(method, *args, &block)
|
61
|
+
@originalSelf.send(method, *args, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Render the canvas as SVG output (tree of XMLElement objects).
|
65
|
+
def to_svg
|
66
|
+
XMLElement.new('svg', 'width' => "#{@width}px",
|
67
|
+
'height' => "#{@height}px") do
|
68
|
+
@elements.map { |el| el.to_svg }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = BasicShapes.rb -- The TaskJuggler III Project Management Software
|
5
|
+
#
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
|
+
# by Chris Schlaeger <chris@linux.com>
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify
|
10
|
+
# it under the terms of version 2 of the GNU General Public License as
|
11
|
+
# published by the Free Software Foundation.
|
12
|
+
#
|
13
|
+
|
14
|
+
require 'taskjuggler/XMLElement'
|
15
|
+
require 'taskjuggler/Painter/Element'
|
16
|
+
|
17
|
+
class TaskJuggler
|
18
|
+
|
19
|
+
class Painter
|
20
|
+
|
21
|
+
# A circle element.
|
22
|
+
class Circle < Element
|
23
|
+
|
24
|
+
# Create a circle with center at cx, cy and radius r.
|
25
|
+
def initialize(attrs)
|
26
|
+
super('circle', [ :cx, :cy, :r ] + FillAndStrokeAttrs, attrs)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
# An ellipse element.
|
32
|
+
class Ellipse < Element
|
33
|
+
|
34
|
+
# Create an ellipse with center at cx, cy and radiuses rx and ry.
|
35
|
+
def initialize(attrs)
|
36
|
+
super('ellipse', [ :cx, :cy, :rx, :ry ] + FillAndStrokeAttrs, attrs)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# A line element.
|
42
|
+
class Line < Element
|
43
|
+
|
44
|
+
# Create a line from x1, y1, to x2, y2.
|
45
|
+
def initialize(attrs)
|
46
|
+
super('line', [ :x1, :y1, :x2, :y2 ] + StrokeAttrs, attrs)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
# A Rectangle element.
|
52
|
+
class Rect < Element
|
53
|
+
|
54
|
+
# Create a rectangle at x, y with width and height.
|
55
|
+
def initialize(attrs)
|
56
|
+
super('rect', [ :x, :y, :width, :height, :rx, :ry ] +
|
57
|
+
FillAndStrokeAttrs, attrs)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
# A Polygon line element.
|
63
|
+
class PolyLine < Element
|
64
|
+
|
65
|
+
# Create a polygon line with the provided Points.
|
66
|
+
def initialize(attrs)
|
67
|
+
super('polyline', [ :points ] + FillAndStrokeAttrs, attrs)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
|
@@ -0,0 +1,273 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# = Color.rb -- The TaskJuggler III Project Management Software
|
5
|
+
#
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
7
|
+
# by Chris Schlaeger <chris@linux.com>
|
8
|
+
#
|
9
|
+
# This program is free software; you can redistribute it and/or modify
|
10
|
+
# it under the terms of version 2 of the GNU General Public License as
|
11
|
+
# published by the Free Software Foundation.
|
12
|
+
#
|
13
|
+
|
14
|
+
class TaskJuggler
|
15
|
+
|
16
|
+
class Painter
|
17
|
+
|
18
|
+
# A description of the color. The color is stored internally as an RGB
|
19
|
+
# value. Common names are provided for many popular colors.
|
20
|
+
class Color
|
21
|
+
|
22
|
+
NamedColors = {
|
23
|
+
:aliceblue => [ 240, 248, 255 ],
|
24
|
+
:antiquewhite => [ 250, 235, 215 ],
|
25
|
+
:aqua => [ 0, 255, 255 ],
|
26
|
+
:aquamarine => [ 127, 255, 212 ],
|
27
|
+
:azure => [ 240, 255, 255 ],
|
28
|
+
:beige => [ 245, 245, 220 ],
|
29
|
+
:bisque => [ 255, 228, 196 ],
|
30
|
+
:black => [ 0, 0, 0 ],
|
31
|
+
:blanchedalmond => [ 255, 235, 205 ],
|
32
|
+
:blue => [ 0, 0, 255 ],
|
33
|
+
:blueviolet => [ 138, 43, 226 ],
|
34
|
+
:brown => [ 165, 42, 42 ],
|
35
|
+
:burlywood => [ 222, 184, 135 ],
|
36
|
+
:cadetblue => [ 95, 158, 160 ],
|
37
|
+
:chartreuse => [ 127, 255, 0 ],
|
38
|
+
:chocolate => [ 210, 105, 30 ],
|
39
|
+
:coral => [ 255, 127, 80 ],
|
40
|
+
:cornflowerblue => [ 100, 149, 237 ],
|
41
|
+
:cornsilk => [ 255, 248, 220 ],
|
42
|
+
:crimson => [ 220, 20, 60 ],
|
43
|
+
:cyan => [ 0, 255, 255 ],
|
44
|
+
:darkblue => [ 0, 0, 139 ],
|
45
|
+
:darkcyan => [ 0, 139, 139 ],
|
46
|
+
:darkgoldenrod => [ 184, 134, 11 ],
|
47
|
+
:darkgray => [ 169, 169, 169 ],
|
48
|
+
:darkgreen => [ 0, 100, 0 ],
|
49
|
+
:darkgrey => [ 169, 169, 169 ],
|
50
|
+
:darkkhaki => [ 189, 183, 107 ],
|
51
|
+
:darkmagenta => [ 139, 0, 139 ],
|
52
|
+
:darkolivegreen => [ 85, 107, 47 ],
|
53
|
+
:darkorange => [ 255, 140, 0 ],
|
54
|
+
:darkorchid => [ 153, 50, 204 ],
|
55
|
+
:darkred => [ 139, 0, 0 ],
|
56
|
+
:darksalmon => [ 233, 150, 122 ],
|
57
|
+
:darkseagreen => [ 143, 188, 143 ],
|
58
|
+
:darkslateblue => [ 72, 61, 139 ],
|
59
|
+
:darkslategray => [ 47, 79, 79 ],
|
60
|
+
:darkslategrey => [ 47, 79, 79 ],
|
61
|
+
:darkturquoise => [ 0, 206, 209 ],
|
62
|
+
:darkviolet => [ 148, 0, 211 ],
|
63
|
+
:deeppink => [ 255, 20, 147 ],
|
64
|
+
:deepskyblue => [ 0, 191, 255 ],
|
65
|
+
:dimgray => [ 105, 105, 105 ],
|
66
|
+
:dimgrey => [ 105, 105, 105 ],
|
67
|
+
:dodgerblue => [ 30, 144, 255 ],
|
68
|
+
:firebrick => [ 178, 34, 34 ],
|
69
|
+
:floralwhite => [ 255, 250, 240 ],
|
70
|
+
:forestgreen => [ 34, 139, 34 ],
|
71
|
+
:fuchsia => [ 255, 0, 255 ],
|
72
|
+
:gainsboro => [ 220, 220, 220 ],
|
73
|
+
:ghostwhite => [ 248, 248, 255 ],
|
74
|
+
:gold => [ 255, 215, 0 ],
|
75
|
+
:goldenrod => [ 218, 165, 32 ],
|
76
|
+
:gray => [ 128, 128, 128 ],
|
77
|
+
:grey => [ 128, 128, 128 ],
|
78
|
+
:green => [ 0, 128, 0 ],
|
79
|
+
:greenyellow => [ 173, 255, 47 ],
|
80
|
+
:honeydew => [ 240, 255, 240 ],
|
81
|
+
:hotpink => [ 255, 105, 180 ],
|
82
|
+
:indianred => [ 205, 92, 92 ],
|
83
|
+
:indigo => [ 75, 0, 130 ],
|
84
|
+
:ivory => [ 255, 255, 240 ],
|
85
|
+
:khaki => [ 240, 230, 140 ],
|
86
|
+
:lavender => [ 230, 230, 250 ],
|
87
|
+
:lavenderblush => [ 255, 240, 245 ],
|
88
|
+
:lawngreen => [ 124, 252, 0 ],
|
89
|
+
:lemonchiffon => [ 255, 250, 205 ],
|
90
|
+
:lightblue => [ 173, 216, 230 ],
|
91
|
+
:lightcoral => [ 240, 128, 128 ],
|
92
|
+
:lightcyan => [ 224, 255, 255 ],
|
93
|
+
:lightgoldenrodyellow => [ 250, 250, 210 ],
|
94
|
+
:lightgray => [ 211, 211, 211 ],
|
95
|
+
:lightgreen => [ 144, 238, 144 ],
|
96
|
+
:lightgrey => [ 211, 211, 211 ],
|
97
|
+
:lightpink => [ 255, 182, 193 ],
|
98
|
+
:lightsalmon => [ 255, 160, 122 ],
|
99
|
+
:lightseagreen => [ 32, 178, 170 ],
|
100
|
+
:lightskyblue => [ 135, 206, 250 ],
|
101
|
+
:lightslategray => [ 119, 136, 153 ],
|
102
|
+
:lightslategrey => [ 119, 136, 153 ],
|
103
|
+
:lightsteelblue => [ 176, 196, 222 ],
|
104
|
+
:lightyellow => [ 255, 255, 224 ],
|
105
|
+
:lime => [ 0, 255, 0 ],
|
106
|
+
:limegreen => [ 50, 205, 50 ],
|
107
|
+
:linen => [ 250, 240, 230 ],
|
108
|
+
:magenta => [ 255, 0, 255 ],
|
109
|
+
:maroon => [ 128, 0, 0 ],
|
110
|
+
:mediumaquamarine => [ 102, 205, 170 ],
|
111
|
+
:mediumblue => [ 0, 0, 205 ],
|
112
|
+
:mediumorchid => [ 186, 85, 211 ],
|
113
|
+
:mediumpurple => [ 147, 112, 219 ],
|
114
|
+
:mediumseagreen => [ 60, 179, 113 ],
|
115
|
+
:mediumslateblue => [ 123, 104, 238 ],
|
116
|
+
:mediumspringgreen => [ 0, 250, 154 ],
|
117
|
+
:mediumturquoise => [ 72, 209, 204 ],
|
118
|
+
:mediumvioletred => [ 199, 21, 133 ],
|
119
|
+
:midnightblue => [ 25, 25, 112 ],
|
120
|
+
:mintcream => [ 245, 255, 250 ],
|
121
|
+
:mistyrose => [ 255, 228, 225 ],
|
122
|
+
:moccasin => [ 255, 228, 181 ],
|
123
|
+
:navajowhite => [ 255, 222, 173 ],
|
124
|
+
:navy => [ 0, 0, 128 ],
|
125
|
+
:oldlace => [ 253, 245, 230 ],
|
126
|
+
:olive => [ 128, 128, 0 ],
|
127
|
+
:olivedrab => [ 107, 142, 35 ],
|
128
|
+
:orange => [ 255, 165, 0 ],
|
129
|
+
:orangered => [ 255, 69, 0 ],
|
130
|
+
:orchid => [ 218, 112, 214 ],
|
131
|
+
:palegoldenrod => [ 238, 232, 170 ],
|
132
|
+
:palegreen => [ 152, 251, 152 ],
|
133
|
+
:paleturquoise => [ 175, 238, 238 ],
|
134
|
+
:palevioletred => [ 219, 112, 147 ],
|
135
|
+
:papayawhip => [ 255, 239, 213 ],
|
136
|
+
:peachpuff => [ 255, 218, 185 ],
|
137
|
+
:peru => [ 205, 133, 63 ],
|
138
|
+
:pink => [ 255, 192, 203 ],
|
139
|
+
:plum => [ 221, 160, 221 ],
|
140
|
+
:powderblue => [ 176, 224, 230 ],
|
141
|
+
:purple => [ 128, 0, 128 ],
|
142
|
+
:red => [ 255, 0, 0 ],
|
143
|
+
:rosybrown => [ 188, 143, 143 ],
|
144
|
+
:royalblue => [ 65, 105, 225 ],
|
145
|
+
:saddlebrown => [ 139, 69, 19 ],
|
146
|
+
:salmon => [ 250, 128, 114 ],
|
147
|
+
:sandybrown => [ 244, 164, 96 ],
|
148
|
+
:seagreen => [ 46, 139, 87 ],
|
149
|
+
:seashell => [ 255, 245, 238 ],
|
150
|
+
:sienna => [ 160, 82, 45 ],
|
151
|
+
:silver => [ 192, 192, 192 ],
|
152
|
+
:skyblue => [ 135, 206, 235 ],
|
153
|
+
:slateblue => [ 106, 90, 205 ],
|
154
|
+
:slategray => [ 112, 128, 144 ],
|
155
|
+
:slategrey => [ 112, 128, 144 ],
|
156
|
+
:snow => [ 255, 250, 250 ],
|
157
|
+
:springgreen => [ 0, 255, 127 ],
|
158
|
+
:steelblue => [ 70, 130, 180 ],
|
159
|
+
:tan => [ 210, 180, 140 ],
|
160
|
+
:teal => [ 0, 128, 128 ],
|
161
|
+
:thistle => [ 216, 191, 216 ],
|
162
|
+
:tomato => [ 255, 99, 71 ],
|
163
|
+
:turquoise => [ 64, 224, 208 ],
|
164
|
+
:violet => [ 238, 130, 238 ],
|
165
|
+
:wheat => [ 245, 222, 179 ],
|
166
|
+
:white => [ 255, 255, 255 ],
|
167
|
+
:whitesmoke => [ 245, 245, 245 ],
|
168
|
+
:yellow => [ 255, 255, 0 ],
|
169
|
+
:yellowgreen => [ 154, 205, 50 ]
|
170
|
+
}
|
171
|
+
|
172
|
+
# Create a new Color object.
|
173
|
+
def initialize(*args)
|
174
|
+
if args.length == 1
|
175
|
+
unless NamedColors.include?(args[0])
|
176
|
+
raise "Unknown color name #{args[0]}"
|
177
|
+
end
|
178
|
+
|
179
|
+
@r, @g, @b = NamedColors[args[0]]
|
180
|
+
elsif args.length == 3
|
181
|
+
args.each do |v|
|
182
|
+
unless v >= 0 && v < 256
|
183
|
+
raise ArgumentError, "RGB values (#{args.join(', ')}) must " +
|
184
|
+
"be between 0 and 255."
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
@r, @g, @b = args
|
189
|
+
elsif args.length == 4
|
190
|
+
unless args[0] >= 0 && args[0] < 360
|
191
|
+
raise ArgumentError, "Hue value must be between 0 and 360"
|
192
|
+
end
|
193
|
+
unless args[1] >= 0 && args[1] <= 255
|
194
|
+
raise ArgumentError, "Saturation value (#{args[1]}) must be " +
|
195
|
+
"between 0 and 255"
|
196
|
+
end
|
197
|
+
unless args[2] >= 0 && args[2] <= 255
|
198
|
+
raise ArgumentError, "Color value (#{args[2]}) must be " +
|
199
|
+
"between 0 and 255"
|
200
|
+
end
|
201
|
+
@r, @g, @b = hsvToRgb(*args[0..2])
|
202
|
+
else
|
203
|
+
raise ArgumentError
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def to_rgb
|
208
|
+
[ @r, @g, @b ]
|
209
|
+
end
|
210
|
+
|
211
|
+
def to_hsv
|
212
|
+
rgbToHsv(@r, @g, @b)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Convert the RGB value into a String format that is used in HTML.
|
216
|
+
def to_s
|
217
|
+
format("#%02x%02x%02x", @r, @g, @b)
|
218
|
+
end
|
219
|
+
|
220
|
+
private
|
221
|
+
|
222
|
+
def hsvToRgb(h, s, v)
|
223
|
+
hi = (h / 60.0).floor % 6
|
224
|
+
f = (h / 60.0) - (h / 60.0).floor
|
225
|
+
p = (v * (1.0 - s / 255.0)).to_i
|
226
|
+
q = (v * (1.0 - (f * s / 255.0))).to_i
|
227
|
+
t = (v * (1.0 - ((1.0 - f) * s / 255.0))).to_i
|
228
|
+
[ [ v, t, p ],
|
229
|
+
[ q, v, p ],
|
230
|
+
[ p, v, t ],
|
231
|
+
[ p, q, v ],
|
232
|
+
[ t, p, v ],
|
233
|
+
[ v, p, q ] ][hi]
|
234
|
+
end
|
235
|
+
|
236
|
+
def rgbToHsv(*rgb)
|
237
|
+
max = rgb.max
|
238
|
+
min = rgb.min
|
239
|
+
chroma = (max - min).to_f
|
240
|
+
v = max
|
241
|
+
|
242
|
+
if (max != 0.0)
|
243
|
+
s = chroma / max * 255.0
|
244
|
+
else
|
245
|
+
s = 0.0
|
246
|
+
end
|
247
|
+
|
248
|
+
r, g, b = rgb
|
249
|
+
if (s == 0.0)
|
250
|
+
h = 0.0
|
251
|
+
else
|
252
|
+
if (r == max)
|
253
|
+
h = (g - b) / chroma
|
254
|
+
elsif (g == max)
|
255
|
+
h = 2.0 + (b - r) / chroma
|
256
|
+
elsif (b == max)
|
257
|
+
h = 4.0 + (r - g) / chroma
|
258
|
+
end
|
259
|
+
|
260
|
+
h *= 60.0
|
261
|
+
|
262
|
+
h += 360.0 if h < 0.0
|
263
|
+
end
|
264
|
+
|
265
|
+
[ h.to_i, s.to_i, v.to_i ]
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
|