bool
ReportManager::showReport(QListViewItem* lvi, bool& showReportTab)
{
    ManagedReportInfo* mr = 0;
    showReportTab = true;
    if (!lvi)
    {
        /* If the lvi is null then we try to show the current report or the
         * first interactive report. */
        if (browser->currentItem())
            lvi = browser->currentItem();
        else if (qtReports->firstChild())
            lvi = (qtReports->firstChild());
    }
    for (std::list<ManagedReportInfo*>::const_iterator mri = reports.begin();
         mri != reports.end(); ++mri)
        if ((*mri)->getBrowserEntry() == lvi)
            mr = *mri;

    if (!mr)
    {
        /* In case there is no corresponding list view entry we show the
         * summary report. The summary report has no report definition, so it
         * can be identified by a 0 pointer. */
        for (std::list<ManagedReportInfo*>::const_iterator
             mri = reports.begin(); mri != reports.end(); ++mri)
            if ((*mri)->getProjectReport() == 0)
            {
                mr = *mri;
                break;
            }
    }

    TjUIReportBase* tjr = mr->getReport();
    Report *rep = mr->getProjectReport();
    const char * type = rep ? rep->getType() : "";
    bool result = true;
    if (tjr == 0)
    {
        if (rep == 0)
            tjr = new TjSummaryReport(reportStack, this, project);
        else if (strcmp(type, "QtTaskReport") == 0)
            tjr = new TjTaskReport(reportStack, this, rep);
        else if (strcmp(type, "QtResourceReport") == 0)
            tjr = new TjResourceReport(reportStack, this, rep);
        else if (strncmp(type, "CSV", 3) == 0)
        {
            if (!rep->generate())
                result = false;
            // show the CSV file in preferred CSV handler
            QString baseDir;
            if (rep->getFileName()[0].latin1() == '/')
                baseDir = "/";
            else
                baseDir = rep->getDefinitionFile();
            KURL reportUrl =
                KURL::fromPathOrURL(baseDir);
            reportUrl.setFileName(rep->getFileName());
            changeStatusBar(i18n("Displaying CSV report: '%1'")
                            .arg(rep->getFileName()));
            KRun::runURL(reportUrl, "text/x-csv");
        }
        else if (strncmp(type, "SVG", 3) == 0)
        {
            if (!rep->generate())
                result = false;
            // show the SVG file in preferred SVG handler
            KURL reportUrl =
                KURL::fromPathOrURL(rep->getDefinitionFile());
            reportUrl.setFileName(rep->getFileName());

            changeStatusBar(i18n("Displaying SVG report: '%1'")
                            .arg(rep->getFileName()));
            KRun::runURL(reportUrl, "image/svg+xml");
        }
        else if (strncmp(type, "HTML", 4) == 0)
            tjr = new TjHTMLReport(reportStack, this, rep);
        else if (strncmp(type, "ICal", 4) == 0)
        {
            if (!rep->generate())
                result = false;
            else
            {
                // show the TODO list in Korganizer
                KURL reportUrl =
                    KURL::fromPathOrURL(rep->getDefinitionFile());
                reportUrl.setFileName(rep->getFileName());

                changeStatusBar(i18n("Displaying iCalendar: '%1'")
                                .arg(rep->getFileName()));
                KRun::runURL(reportUrl, "text/calendar");
            }
        }
        else if (strncmp(type, "Export", 6) == 0)
        {
            // Generate the report file
            if (!rep->generate())
                result = false;
            else
            {
                // Get the full file name as URL and show it in the editor
                KURL reportUrl =
                    KURL::fromPathOrURL(rep->getFullFileName());
                if (reportUrl.url().right(4) == ".tjp")
                {
                    changeStatusBar(i18n("Starting new TaskJuggler for '%1'")
                                    .arg(rep->getFileName()));
                    KRun::runURL(reportUrl, "application/x-tjp");
                }
                else
                {
                    emit signalEditFile(reportUrl);
                    showReportTab = false;
                }
            }
        }
        else if (strncmp(type, "XMLReport", 9) == 0)
        {
            bool result = rep->generate();
            if (result)
            {
                KMessageBox::information
                    (mainWindow, i18n("The report '%1' has been generated.")
                     .arg(rep->getFileName()),
                     QString::null, "XMLReportGeneratedInfo");
                changeStatusBar(i18n("The report '%1' has been generated")
                    .arg(rep->getFileName()));
            }
            else
                changeStatusBar(i18n("Could not generated report '%1'")
                    .arg(rep->getFileName()));
        }
        else
        {
            kdDebug() << "Report type " << type << " not yet supported" << endl;
            result = false;
        }

        if (!tjr)
        {
            /* A report with no widget that can be embedded in the report view
             * has been selected. We fall back to show the summary report and
             * unselect the selected browser item. */
            if (browser->currentItem())
                browser->setSelected(browser->currentItem(), false);
            tjr = new TjSummaryReport(reportStack, this, project);
        }

        connect(tjr, SIGNAL(signalChangeStatusBar(const QString&)),
                this, SLOT(changeStatusBar(const QString&)));
        connect(tjr, SIGNAL(signalEditCoreAttributes(CoreAttributes*)),
                this, SLOT(editCoreAttributes(CoreAttributes*)));

        if (!tjr->generateReport())
        {
            delete tjr;
            if (browser->currentItem())
                browser->setSelected(browser->currentItem(), false);
            return false;
        }

        reportStack->addWidget(tjr);
        mr->setReport(tjr);
    }

    // in older versions of KDE, this produces a (seemingly harmless) warning
    //    ASSERT: "id < (int)d->m_list.count()" in ./kdeui/kactionclasses.cpp (433)
    reportStack->raiseWidget(tjr);

    return result;
}