A Navigator is an automatically generated menu to navigate a list of reports. The hierarchical structure of the reports will be reused to group them. The actual structure of the Navigator depends on the output format.
# File lib/taskjuggler/reports/Navigator.rb, line 104 def initialize(id, project) @id = id @project = project @hideReport = LogicalExpression.new(LogicalOperation.new(0)) @elements = [] end
Generate an output format independant version of the navigator. This is a tree of NavigatorElement objects.
# File lib/taskjuggler/reports/Navigator.rb, line 113 def generate(allReports, currentReports, reportDef, parentElement) element = nextParentElement = nextParentReport = nil currentReports.each do |report| hasURL = report.get('formats').include?(:html) # Only generate menu entries for container reports or leaf reports # have a HTML output format. next if (report.leaf? && !hasURL) || !allReports.include?(report) # What label should be used for the menu entry? It's either the name # of the report or the user specified title. label = report.get('title') || report.name url = findReportURL(report, allReports, reportDef) # Now we have all data so we can create the actual menu entry. parentElement.elements << (element = NavigatorElement.new(parentElement, label, url)) # Check if 'report' matches the 'reportDef' report or is a child of # it. if reportDef == report || reportDef.isChildOf?(report) nextParentReport = report nextParentElement = element element.current = true end end if nextParentReport && nextParentReport.container? generate(allReports, nextParentReport.kids, reportDef, nextParentElement) end end
# File lib/taskjuggler/reports/Navigator.rb, line 146 def to_html # The the Report object that contains this Navigator. reportDef ||= @project.reportContexts.last.report raise "Report context missing" unless reportDef # Compile a list of all reports that the user wants to include in the # menu. reports = filterReports return nil if reports.empty? # Make sure the report is actually in the filtered list. unless reports.include?(reportDef) @project.warning('nav_in_hidden_rep', "Navigator requested for a report that is not " + "included in the navigator list.", reportDef.sourceFileInfo) return nil end # Find the list of reports that become the top-level menu entries. topLevelReports = [ reportDef ] report = reportDef while report.parent report = report.parent topLevelReports = report.kids end generate(reports, topLevelReports, reportDef, content = NavigatorElement.new(nil)) content.to_html end
# File lib/taskjuggler/reports/Navigator.rb, line 180 def filterReports list = PropertyList.new(@project.reports) list.setSorting([[ 'seqno', true, -1 ]]) list.sort! # Remove all reports that the user doesn't want to have include. query = @project.reportContexts.last.query.dup query.scopeProperty = nil query.scenarioIdx = query.scenario = nil list.delete_if do |property| query.property = property @hideReport.eval(query) end list end
Find the URL to be used for the current Navigator menu entry.
# File lib/taskjuggler/reports/Navigator.rb, line 208 def findReportURL(report, allReports, reportDef) return nil unless allReports.include?(report) if report.get('formats').include?(:html) # The element references an HTML report. Point to it. if @project.reportContexts.last.report.interactive? url = "/taskjuggler?project=#{report.project['projectid']};" + "report=#{report.fullId}" else url = report.name + '.html' url = normalizeURL(url, reportDef.name) end return url else # The menu element is just a entry for another sub-menu. The the URL # from the first kid of the report that has a URL. report.kids.each do |r| if (url = findReportURL(r, allReports, reportDef)) return url end end end nil end
Remove the URL or directory path from url1 that is identical to url2.
# File lib/taskjuggler/reports/Navigator.rb, line 197 def normalizeURL(url1, url2) cut = 0 url1.length.times do |i| return url1[cut, url1.length - cut] if url1[i] != url2[i] cut = i + 1 if url1[i] == / end url1 end