class TaskJuggler::Navigator

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.

Attributes

hideReport[RW]
id[R]

Public Class Methods

new(id, project) click to toggle source
# File lib/taskjuggler/reports/Navigator.rb, line 105
def initialize(id, project)
  @id = id
  @project = project
  @hideReport = LogicalExpression.new(LogicalOperation.new(0))
  @elements = []
end

Public Instance Methods

generate(allReports, currentReports, reportDef, parentElement) click to toggle source

Generate an output format independant version of the navigator. This is a tree of NavigatorElement objects.

# File lib/taskjuggler/reports/Navigator.rb, line 114
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
to_html() click to toggle source
# File lib/taskjuggler/reports/Navigator.rb, line 147
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

Private Instance Methods

filterReports() click to toggle source
# File lib/taskjuggler/reports/Navigator.rb, line 181
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
findReportURL(report, allReports, reportDef) click to toggle source

Find the URL to be used for the current Navigator menu entry.

# File lib/taskjuggler/reports/Navigator.rb, line 209
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
normalizeURL(url1, url2) click to toggle source

Remove the URL or directory path from url1 that is identical to url2.

# File lib/taskjuggler/reports/Navigator.rb, line 198
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