diff --git a/src/libs/ui/CMakeLists.txt b/src/libs/ui/CMakeLists.txt index e14b9b18..bd7fb803 100644 --- a/src/libs/ui/CMakeLists.txt +++ b/src/libs/ui/CMakeLists.txt @@ -1,210 +1,211 @@ include_directories( ${PLANKERNEL_INCLUDES} ${PLANMODELS_INCLUDES} ${PLANMAIN_INCLUDES} ${PLANWIDGETS_INCLUDES} ${KDEPIMLIBS_INCLUDE_DIR} ) #add_subdirectory( tests ) ########### KPlato private library ############### if (PLAN_USE_KREPORT) message(STATUS "-- Building plan with reports capability") add_subdirectory(reports/items) set(planreports_LIB_SRC reports/reportview.cpp reports/reportdata.cpp reports/reportsourceeditor.cpp reports/reportscripts.cpp ) set(planreports_ui_LIB_SRCS reports/reportsourceeditor.ui reports/reportnavigator.ui reports/reportsectionswidget.ui reports/reportgroupsectionswidget.ui reports/reporttoolswidget.ui ) endif() set(planui_LIB_SRCS ${planreports_LIB_SRC} Help.cpp TasksEditController.cpp TasksEditDialog.cpp welcome/WelcomeView.cpp reportsgenerator/ReportsGeneratorView.cpp kptganttitemdelegate.cpp kptworkpackagesendpanel.cpp kptworkpackagesenddialog.cpp kptdocumentseditor.cpp kptdocumentspanel.cpp kptdocumentsdialog.cpp kptitemviewsettup.cpp kptsplitterview.cpp kptrelationeditor.cpp kptdependencyeditor.cpp kptusedefforteditor.cpp kpttaskstatusview.cpp kptcalendareditor.cpp kptviewbase.cpp kptaccountseditor.cpp kptperteditor.cpp kptpertresult.cpp kpttaskeditor.cpp kptresourceeditor.cpp kptscheduleeditor.cpp kptsummarytaskdialog.cpp kptsummarytaskgeneralpanel.cpp kptresourceappointmentsview.cpp kptaccountsviewconfigdialog.cpp kptaccountsview.cpp kpttaskcostpanel.cpp kptmilestoneprogresspanel.cpp kptmilestoneprogressdialog.cpp kpttaskdialog.cpp kptmainprojectdialog.cpp kptmainprojectpanel.cpp kptganttview.cpp gantt/DateTimeTimeLine.cpp gantt/DateTimeGrid.cpp kptrelationdialog.cpp kptrequestresourcespanel.cpp kptresourcedialog.cpp kptstandardworktimedialog.cpp kptintervaledit.cpp kpttaskgeneralpanel.cpp kpttaskprogresspanel.cpp kpttaskprogressdialog.cpp kpttaskdescriptiondialog.cpp kptwbsdefinitiondialog.cpp kptwbsdefinitionpanel.cpp kptresourceassignmentview.cpp kptperformancetablewidget.cpp kptresourceallocationeditor.cpp kptworkpackagemergedialog.cpp kptrecalculatedialog.cpp kpthtmlview.cpp locale/localemon.cpp kptlocaleconfigmoneydialog.cpp ResourceAllocationView.cpp + performance/KPlatoChart.cpp performance/PerformanceStatusBase.cpp performance/ProjectStatusView.cpp performance/PerformanceStatusView.cpp ) ki18n_wrap_ui(planui_LIB_SRCS ${planreports_ui_LIB_SRCS} welcome/WelcomeView.ui kptresourceappointmentsdisplayoptions.ui kptganttchartdisplayoptions.ui kptprintingheaderfooter.ui kptganttprintingoptions.ui kptworkpackagesendpanel.ui kptdocumentspanel.ui performance/PerformanceStatus.ui performance/PerformanceStatusViewSettingsPanel.ui kptcpmwidget.ui kptitemviewsettings.ui kptpertresult.ui standardworktimedialogbase.ui kptwbsdefinitionpanelbase.ui kptaccountsviewconfigurepanelbase.ui kptintervaleditbase.ui kpttaskcostpanelbase.ui kpttaskdescriptionpanelbase.ui kptsummarytaskgeneralpanelbase.ui kptmilestoneprogresspanelbase.ui resourcedialogbase.ui kptmainprojectpanelbase.ui relationpanel.ui kpttaskgeneralpanelbase.ui kpttaskprogresspanelbase.ui kptperteditor.ui kptresourceassignmentview.ui kpttaskstatusviewsettingspanel.ui kptworkpackagemergepanel.ui kptrecalculatedialog.ui kptscheduleeditor.ui locale/localemon.ui ) add_library(planui SHARED ${planui_LIB_SRCS}) generate_export_header(planui) target_link_libraries(planui PUBLIC planmain planmodels KF5::KHtml PRIVATE KChart KF5::ItemViews KF5::IconThemes KF5::Archive KF5::TextWidgets # Qt5::Sql ) if (PLAN_USE_KREPORT) target_link_libraries(planui PUBLIC KReport PRIVATE KPropertyWidgets) endif() if(KF5AkonadiContact_FOUND) target_link_libraries(planui PRIVATE KF5::AkonadiContact) endif() set_target_properties(planui PROPERTIES VERSION ${GENERIC_PLAN_LIB_VERSION} SOVERSION ${GENERIC_PLAN_LIB_SOVERSION} ) install(TARGETS planui ${INSTALL_TARGETS_DEFAULT_ARGS}) install( FILES AccountsEditorUi.rc AccountsViewUi.rc CalendarEditorUi.rc TaskEditorUi.rc DependencyEditorUi.rc ResourceEditorUi.rc ResourceAppointmentsViewUi.rc ScheduleEditorUi.rc GanttViewUi.rc WorkPackageViewUi.rc reportsgenerator/ReportsGeneratorViewUi.rc performance/PerformanceStatusViewUi.rc performance/ProjectStatusViewUi.rc PertResultUi.rc TaskViewUi.rc TaskStatusViewUi.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/calligraplan ) # reports files install(FILES reportsgenerator/ProjectPerformanceCost.odt reportsgenerator/ProjectPerformance.odt reportsgenerator/TaskStatus.odt DESTINATION ${DATA_INSTALL_DIR}/calligraplan/reports ) diff --git a/src/libs/ui/kptperformancetablewidget.cpp b/src/libs/ui/kptperformancetablewidget.cpp index 571fd4c7..5afe8e0c 100644 --- a/src/libs/ui/kptperformancetablewidget.cpp +++ b/src/libs/ui/kptperformancetablewidget.cpp @@ -1,79 +1,84 @@ /* This file is part of the KDE project - Copyright (C) 2011 Dag Andersen - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ + * Copyright (C) 2019 Dag Andersen + * Copyright (C) 2011 Dag Andersen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ // clazy:excludeall=qstring-arg #include "kptperformancetablewidget.h" #include +#include +#include + +using namespace KPlato; -namespace KPlato -{ PerformanceTableWidget::PerformanceTableWidget( QWidget *parent ) : QTableWidget( parent ) { horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch ); verticalHeader()->setSectionResizeMode( QHeaderView::Fixed ); } QSize PerformanceTableWidget::sizeHint() const { QSize s = QTableView::sizeHint(); int h = horizontalHeader()->height(); for ( int r = 0; r < rowCount(); ++r ) { if ( ! verticalHeader()->isSectionHidden( r ) ) { h += verticalHeader()->sectionSize( r ); } } s.setHeight( h + frameWidth() * 2 ); return s; } QSize PerformanceTableWidget::minimumSizeHint() const { return sizeHint(); } //--------- PerformanceTableView::PerformanceTableView( QWidget *parent ) : QTableView( parent ) { horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch ); + horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); + connect(horizontalHeader(), &QHeaderView::customContextMenuRequested, this, &PerformanceTableView::customContextMenuRequested); verticalHeader()->setSectionResizeMode( QHeaderView::Fixed ); + verticalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); + connect(verticalHeader(), &QHeaderView::customContextMenuRequested, this, &PerformanceTableView::customContextMenuRequested); } QSize PerformanceTableView::sizeHint() const { QSize s = QTableView::sizeHint(); int h = horizontalHeader()->height(); for ( int r = 0; r < verticalHeader()->count(); ++r ) { if ( ! verticalHeader()->isSectionHidden( r ) ) { h += verticalHeader()->sectionSize( r ); } } s.setHeight( h + frameWidth() * 2 ); return s; } QSize PerformanceTableView::minimumSizeHint() const { return sizeHint(); } - -} // namespace KPlato diff --git a/src/libs/ui/kptperformancetablewidget.h b/src/libs/ui/kptperformancetablewidget.h index 05746722..d683a827 100644 --- a/src/libs/ui/kptperformancetablewidget.h +++ b/src/libs/ui/kptperformancetablewidget.h @@ -1,50 +1,51 @@ /* This file is part of the KDE project - Copyright (C) 2011 Dag Andersen - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ + * Copyright (C) 2019 Dag Andersen + * Copyright (C) 2011 Dag Andersen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ #ifndef KPTPERFORMANCETABLEWIDGET_H #define KPTPERFORMANCETABLEWIDGET_H #include namespace KPlato { class PerformanceTableWidget : public QTableWidget { Q_OBJECT public: explicit PerformanceTableWidget(QWidget *parent); QSize sizeHint() const; QSize minimumSizeHint() const; }; class PerformanceTableView : public QTableView { Q_OBJECT public: explicit PerformanceTableView(QWidget *parent); QSize sizeHint() const; QSize minimumSizeHint() const; }; } // namespace KPlato #endif diff --git a/src/libs/ui/performance/KPlatoChart.h b/src/libs/ui/performance/KPlatoChart.h index 059b005d..a1a6f593 100644 --- a/src/libs/ui/performance/KPlatoChart.h +++ b/src/libs/ui/performance/KPlatoChart.h @@ -1,66 +1,56 @@ /* This file is part of the KDE project * Copyright (C) 2019 Dag Andersen * Copyright (C) 2007 - 2010 Dag Andersen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KPLATOCHART_H #define KPLATOCHART_H #include -#include -#include -#include namespace KPlato { /* * class KPlato::Chart * - * Wrapper for KChart::Chart to prevent rubberband selection - * with no keyboard modifers. + * Wrapper for KChart::Chart to allow rubberband selection + * with no keyboard modifers when cursor is inside a coordinate plan. * - * By default KChart::Chart eats the mouse events which makes - * implementation of drag and context menu difficult. + * When not inside a plane drag&drop and context menu can be activated. */ class Chart : public KChart::Chart { + Q_OBJECT public: - Chart(QWidget *parent) : KChart::Chart(parent) {} + Chart(QWidget *parent); protected: - void mousePressEvent(QMouseEvent *event) { - if (event->modifiers() != Qt::NoModifier) { - KChart::Chart::mousePressEvent(event); - } else { - event->ignore(); - } - } - void mouseMoveEvent(QMouseEvent *event) { - if (event->modifiers() != Qt::NoModifier) { - KChart::Chart::mouseMoveEvent(event); - } else { - event->ignore(); - } - } + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + +private: + bool m_inplane; }; } #endif diff --git a/src/libs/ui/performance/PerformanceStatusBase.cpp b/src/libs/ui/performance/PerformanceStatusBase.cpp index cf61c158..3cb0319c 100644 --- a/src/libs/ui/performance/PerformanceStatusBase.cpp +++ b/src/libs/ui/performance/PerformanceStatusBase.cpp @@ -1,704 +1,712 @@ /* This file is part of the KDE project * Copyright (C) 2019 Dag Andersen * Copyright (C) 2007 - 2010, 2012 Dag Andersen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ // clazy:excludeall=qstring-arg #include "PerformanceStatusBase.h" #include "kptglobal.h" #include "kptlocale.h" #include "kptcommonstrings.h" #include "kptcommand.h" #include "kptproject.h" #include "kptschedule.h" #include "kpteffortcostmap.h" #include "Help.h" #include "kptdebug.h" #include #include "KoDocument.h" #include "KoPageLayoutWidget.h" #include #include #include #include #include #include #include #include #include #include using namespace KChart; using namespace KPlato; PerformanceStatusPrintingDialog::PerformanceStatusPrintingDialog(ViewBase *view, PerformanceStatusBase *chart, Project *project) : PrintingDialog(view), m_chart(chart), m_project(project) { } int PerformanceStatusPrintingDialog::documentLastPage() const { return documentFirstPage(); } QList PerformanceStatusPrintingDialog::createOptionWidgets() const { QList lst; lst << createPageLayoutWidget(); lst += PrintingDialog::createOptionWidgets(); return lst; } void PerformanceStatusPrintingDialog::printPage(int page, QPainter &painter) { //debugPlan<ui_chart->geometry().size(); qreal r = (qreal)s.width() / (qreal)s.height(); if (rect.height() > rect.width() && r > 0.0) { rect.setHeight(rect.width() / r); } debugPlan<ui_chart->paint(&painter, rect); painter.restore(); } //----------------------------------- PerformanceStatusBase::PerformanceStatusBase(QWidget *parent) : QWidget(parent), m_project(0), m_manager(0) { setupUi(this); ui_performancetable->setModel(new PerformanceDataCurrentDateModel(this)); BackgroundAttributes backgroundAttrs(ui_chart->backgroundAttributes()); backgroundAttrs.setVisible(true); backgroundAttrs.setBrush(Qt::white); ui_chart->setBackgroundAttributes(backgroundAttrs); m_legend = new Legend(ui_chart); ui_chart->replaceLegend(m_legend); m_legend->setObjectName("Chart legend"); backgroundAttrs = m_legend->backgroundAttributes(); m_legend->setBackgroundAttributes(backgroundAttrs); backgroundAttrs.setVisible(true); backgroundAttrs.setBrush(Qt::white); m_legend->setPosition(Position::East); //m_legend->setAlignment((Qt::Alignment)(Qt::AlignTop | Qt::AlignCenter)); m_legenddiagram.setModel(&m_chartmodel); m_legenddiagram.setObjectName("Legend diagram"); m_legend->setDiagram(&m_legenddiagram); // get rid of the default coordinate plane AbstractCoordinatePlane *p = ui_chart->coordinatePlane(); ui_chart->takeCoordinatePlane(p); delete p; createBarChart(); createLineChart(); setupChart(); #ifdef PLAN_CHART_DEBUG ui_tableView->setModel(&m_chartmodel); #endif + setContextMenuPolicy(Qt::PreventContextMenu); connect(&m_chartmodel, &QAbstractItemModel::modelReset, this, &PerformanceStatusBase::slotUpdate); - setContextMenuPolicy (Qt::DefaultContextMenu); + connect(ui_chart, &KPlato::Chart::customContextMenuRequested, this, &PerformanceStatusBase::customContextMenuRequested); + ui_performancetable->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui_performancetable, &PerformanceTableView::customContextMenuRequested, this, &PerformanceStatusBase::slotContextMenuRequested); +} + +void PerformanceStatusBase::slotContextMenuRequested(const QPoint &pos) +{ + emit customContextMenuRequested(mapToGlobal(pos)); } void PerformanceStatusBase::editCopy() { QMimeData *mimeData = new QMimeData; QPixmap pixmap(size()); render(&pixmap); mimeData->setImageData(pixmap); QGuiApplication::clipboard()->setMimeData(mimeData); } void PerformanceStatusBase::setChartInfo(const PerformanceChartInfo &info) { if (info != m_chartinfo) { m_chartinfo = info; setupChart(); } } void PerformanceStatusBase::refreshChart() { ui_performancetable->resize(QSize()); // NOTE: Force grid/axis recalculation, couldn't find a better way :( QResizeEvent event(ui_chart->size(), QSize()); QApplication::sendEvent(ui_chart, &event); m_legend->forceRebuild(); } void PerformanceStatusBase::createBarChart() { m_barchart.effortplane = new CartesianCoordinatePlane(ui_chart); m_barchart.effortplane->setRubberBandZoomingEnabled(true); m_barchart.effortplane->setObjectName("Bar chart, Effort"); m_barchart.costplane = new CartesianCoordinatePlane(ui_chart); m_barchart.costplane->setRubberBandZoomingEnabled(true); m_barchart.costplane->setObjectName("Bar chart, Cost"); BarDiagram *effortdiagram = new BarDiagram(ui_chart, m_barchart.effortplane); effortdiagram->setObjectName("Effort diagram"); m_barchart.dateaxis = new CartesianAxis(); m_barchart.dateaxis->setPosition(CartesianAxis::Bottom); m_barchart.effortaxis = new CartesianAxis(effortdiagram); m_barchart.effortaxis->setPosition(CartesianAxis::Right); effortdiagram->addAxis(m_barchart.effortaxis); m_barchart.effortplane->addDiagram(effortdiagram); // Hide cost in effort diagram effortdiagram->setHidden(0, true); effortdiagram->setHidden(1, true); effortdiagram->setHidden(2, true); m_barchart.effortproxy.setZeroColumns(QList() << 0 << 1 << 2); m_barchart.effortproxy.setSourceModel(&m_chartmodel); effortdiagram->setModel(&(m_barchart.effortproxy)); BarDiagram *costdiagram = new BarDiagram(ui_chart, m_barchart.costplane); costdiagram->setObjectName("Cost diagram"); m_barchart.costaxis = new CartesianAxis(costdiagram); m_barchart.costaxis->setPosition(CartesianAxis::Left); costdiagram->addAxis(m_barchart.costaxis); m_barchart.costplane->addDiagram(costdiagram); // Hide effort in cost diagram costdiagram->setHidden(3, true); costdiagram->setHidden(4, true); costdiagram->setHidden(5, true); m_barchart.costproxy.setZeroColumns(QList() << 3 << 4 << 5); m_barchart.costproxy.setObjectName("Bar: Cost"); m_barchart.costproxy.setSourceModel(&m_chartmodel); costdiagram->setModel(&(m_barchart.costproxy)); m_barchart.effortdiagram = effortdiagram; m_barchart.costdiagram = costdiagram; m_barchart.piplane = new CartesianCoordinatePlane(ui_chart); m_barchart.piplane->setObjectName("Performance Indices"); BarDiagram *pidiagram = new BarDiagram(ui_chart, m_barchart.piplane); pidiagram->setObjectName("PI diagram"); m_barchart.piaxis = new CartesianAxis(pidiagram); pidiagram->addAxis(m_barchart.piaxis); m_barchart.piplane->addDiagram(pidiagram); m_barchart.piproxy.setSourceModel(&m_chartmodel); pidiagram->setModel(&(m_barchart.piproxy)); } void PerformanceStatusBase::createLineChart() { m_linechart.effortplane = new CartesianCoordinatePlane(ui_chart); m_linechart.effortplane->setObjectName("Line chart, Effort"); m_linechart.effortplane->setRubberBandZoomingEnabled(true); m_linechart.costplane = new CartesianCoordinatePlane(ui_chart); m_linechart.costplane->setObjectName("Line chart, Cost"); m_linechart.costplane->setRubberBandZoomingEnabled(true); LineDiagram *effortdiagram = new LineDiagram(ui_chart, m_linechart.effortplane); effortdiagram->setObjectName("Effort diagram"); m_linechart.dateaxis = new CartesianAxis(); m_linechart.dateaxis->setPosition(CartesianAxis::Bottom); m_linechart.effortaxis = new CartesianAxis(effortdiagram); m_linechart.effortaxis->setPosition(CartesianAxis::Right); effortdiagram->addAxis(m_linechart.effortaxis); m_linechart.effortplane->addDiagram(effortdiagram); // Hide cost in effort diagram effortdiagram->setHidden(0, true); effortdiagram->setHidden(1, true); effortdiagram->setHidden(2, true); m_linechart.effortproxy.setZeroColumns(QList() << 0 << 1 << 2); m_linechart.effortproxy.setObjectName("Line: Effort"); m_linechart.effortproxy.setSourceModel(&m_chartmodel); effortdiagram->setModel(&(m_linechart.effortproxy)); LineDiagram *costdiagram = new LineDiagram(ui_chart, m_linechart.costplane); costdiagram->setObjectName("Cost diagram"); m_linechart.costaxis = new CartesianAxis(costdiagram); m_linechart.costaxis->setPosition(CartesianAxis::Left); costdiagram->addAxis(m_linechart.costaxis); m_linechart.costplane->addDiagram(costdiagram); // Hide effort in cost diagram costdiagram->setHidden(3, true); costdiagram->setHidden(4, true); costdiagram->setHidden(5, true); m_linechart.costproxy.setObjectName("Line: Cost"); m_linechart.costproxy.setZeroColumns(QList() << 3 << 4 << 5); m_linechart.costproxy.setSourceModel(&m_chartmodel); costdiagram->setModel(&(m_linechart.costproxy)); m_linechart.effortdiagram = effortdiagram; m_linechart.costdiagram = costdiagram; m_linechart.piplane = new CartesianCoordinatePlane(ui_chart); m_linechart.piplane->setObjectName("Performance Indices"); m_linechart.piplane->setRubberBandZoomingEnabled(true); LineDiagram *pidiagram = new LineDiagram(ui_chart, m_linechart.piplane); pidiagram->setObjectName("PI diagram"); m_linechart.piaxis = new CartesianAxis(pidiagram); pidiagram->addAxis(m_linechart.piaxis); m_linechart.piplane->addDiagram(pidiagram); m_linechart.piproxy.setSourceModel(&m_chartmodel); pidiagram->setModel(&(m_linechart.piproxy)); } void PerformanceStatusBase::setupChart() { while (! ui_chart->coordinatePlanes().isEmpty()) { const CoordinatePlaneList &planes = ui_chart->coordinatePlanes(); ui_chart->takeCoordinatePlane(planes.last()); } if (m_chartinfo.showBarChart) { setupChart(m_barchart); } else if (m_chartinfo.showLineChart) { setupChart(m_linechart); } else { #ifdef PLAN_CHART_DEBUG ui_stack->setCurrentIndex(1); refreshChart(); return; #else setupChart(m_linechart); #endif } ui_stack->setCurrentIndex(0); debugPlan<<"Planes:"<coordinatePlanes(); foreach (AbstractCoordinatePlane *pl, ui_chart->coordinatePlanes()) { CartesianCoordinatePlane *p = dynamic_cast(pl); if (p == 0) continue; GridAttributes ga = p->globalGridAttributes(); ga.setGridVisible(p->referenceCoordinatePlane() == 0); p->setGlobalGridAttributes(ga); } m_legend->setDatasetHidden(0, ! (m_chartinfo.showBaseValues && m_chartinfo.showCost && m_chartinfo.showBCWSCost)); m_legend->setDatasetHidden(1, ! (m_chartinfo.showBaseValues && m_chartinfo.showCost && m_chartinfo.showBCWPCost)); m_legend->setDatasetHidden(2, ! (m_chartinfo.showBaseValues && m_chartinfo.showCost && m_chartinfo.showACWPCost)); m_legend->setDatasetHidden(3, ! (m_chartinfo.showBaseValues && m_chartinfo.showEffort && m_chartinfo.showBCWSEffort)); m_legend->setDatasetHidden(4, ! (m_chartinfo.showBaseValues && m_chartinfo.showEffort && m_chartinfo.showBCWPEffort)); m_legend->setDatasetHidden(5, ! (m_chartinfo.showBaseValues && m_chartinfo.showEffort && m_chartinfo.showACWPEffort)); // spi/cpi m_legend->setDatasetHidden(6, ! (m_chartinfo.showIndices && m_chartinfo.showSpiCost)); m_legend->setDatasetHidden(7, ! (m_chartinfo.showIndices && m_chartinfo.showCpiCost)); m_legend->setDatasetHidden(8, ! (m_chartinfo.showIndices && m_chartinfo.showSpiEffort)); m_legend->setDatasetHidden(9, ! (m_chartinfo.showIndices && m_chartinfo.showCpiEffort)); setEffortValuesVisible(m_chartinfo.effortShown()); setCostValuesVisible(m_chartinfo.costShown()); refreshChart(); } void PerformanceStatusBase::setEffortValuesVisible(bool visible) { ui_performancetable->verticalHeader()->setSectionHidden(1, ! visible); ui_performancetable->setMaximumHeight(ui_performancetable->sizeHint().height()); } void PerformanceStatusBase::setCostValuesVisible(bool visible) { ui_performancetable->verticalHeader()->setSectionHidden(0, ! visible); ui_performancetable->setMaximumHeight(ui_performancetable->sizeHint().height()); } void PerformanceStatusBase::setupChart(ChartContents &cc) { QList erc, ezc, crc, czc; // sourcemodel column numbers int effort_start_column = 3; // proxy column number const PerformanceChartInfo &info = m_chartinfo; debugPlan<<"cost="<(cc.effortplane->diagram())->takeAxis(cc.dateaxis); static_cast(cc.costplane->diagram())->takeAxis(cc.dateaxis); static_cast(cc.piplane->diagram())->takeAxis(cc.dateaxis); cc.costplane->setReferenceCoordinatePlane(0); if (info.showBaseValues) { if (info.showEffort) { // filter cost columns if cost is *not* shown, else hide them and zero out if (! info.showCost) { erc << 0 << 1 << 2; effort_start_column = 0; // no cost, so effort start at 0 } else { ezc << 0 << 1 << 2; cc.effortplane->diagram()->setHidden(0, true); cc.effortplane->diagram()->setHidden(1, true); cc.effortplane->diagram()->setHidden(2, true); } // always disable spi/cpi erc << 6 << 7 << 8 << 9; ezc << 6 << 7 << 8 << 9; // if cost is shown don't return a cost value or else it goes into the effort axis scale calculation //cc.effortproxy.setZeroColumns(info.showCost ? QList() << 0 << 1 << 2 : QList() << 3 << 4 << 5 ); cc.effortaxis->setPosition(info.showCost ? CartesianAxis::Right : CartesianAxis::Left); ui_chart->addCoordinatePlane(cc.effortplane); static_cast(cc.effortplane->diagram())->addAxis(cc.dateaxis); cc.effortplane->setGridNeedsRecalculate(); } if (info.showCost) { // Should never get any effort values in cost diagram czc << 3 << 4 << 5; // remove effort columns from cost if no effort is shown, else hide them if (! info.showEffort) { crc << 3 << 4 << 5; } else { cc.costplane->diagram()->setHidden(3, true); cc.costplane->diagram()->setHidden(4, true); cc.costplane->diagram()->setHidden(5, true); } // always disable spi/cpi erc << 6 << 7 << 8 << 9; ezc << 6 << 7 << 8 << 9; cc.costplane->setReferenceCoordinatePlane(info.showEffort ? cc.effortplane : 0); ui_chart->addCoordinatePlane(cc.costplane); static_cast(cc.costplane->diagram())->addAxis(cc.dateaxis); cc.costplane->setGridNeedsRecalculate(); cc.costplane->diagram()->setHidden(0, ! info.showBCWSCost); cc.costplane->diagram()->setHidden(1, ! info.showBCWPCost); cc.costplane->diagram()->setHidden(2, ! info.showACWPCost); } if (info.showEffort) { cc.effortplane->diagram()->setHidden(effort_start_column, ! info.showBCWSEffort); cc.effortplane->diagram()->setHidden(effort_start_column+1, ! info.showBCWPEffort); cc.effortplane->diagram()->setHidden(effort_start_column+2, ! info.showACWPEffort); cc.effortaxis->setCachedSizeDirty(); cc.effortproxy.reset(); cc.effortproxy.setZeroColumns(ezc); cc.effortproxy.setRejectColumns(erc); } if (info.showCost) { cc.costaxis->setCachedSizeDirty(); cc.costproxy.reset(); cc.costproxy.setZeroColumns(czc); cc.costproxy.setRejectColumns(crc); } } else if (info.showIndices) { cc.piaxis->setPosition(CartesianAxis::Left); ui_chart->addCoordinatePlane(cc.piplane); static_cast(cc.piplane->diagram())->addAxis(cc.dateaxis); cc.piplane->setGridNeedsRecalculate(); cc.piaxis->setCachedSizeDirty(); cc.piproxy.reset(); QList reject; reject << 0 << 1 << 2 << 3 << 4 << 5; if (! info.showSpiCost) { reject << ChartItemModel::SPICost; } if (! info.showCpiCost) { reject << ChartItemModel::CPICost; } if (! info.showSpiEffort) { reject << ChartItemModel::SPIEffort; } if (! info.showCpiEffort) { reject << ChartItemModel::CPIEffort; } cc.piproxy.setRejectColumns(reject); } #if 0 debugPlan<<"Effort:"< 0) { debugPlan<<"Effort:"<diagram()->isHidden(i)?"hide":"show"); } } debugPlan<<"Cost:"< 0) { debugPlan<<"Cost:"<diagram()->isHidden(i)?"hide":"show"); } } foreach(AbstractCoordinatePlane *p, ui_chart->coordinatePlanes()) { debugPlan<referenceCoordinatePlane(); foreach (AbstractDiagram *d, p->diagrams()) { debugPlan<globalPos(); if (event->modifiers() == Qt::NoModifier) { emit customContextMenuRequested(event->globalPos()); } } void PerformanceStatusBase::slotUpdate() { //debugPlan; refreshChart(); } void PerformanceStatusBase::setScheduleManager(ScheduleManager *sm) { //debugPlan; if (sm == m_manager) { return; } m_manager = sm; m_chartmodel.setScheduleManager(sm); static_cast(ui_performancetable->model())->setScheduleManager(sm); } void PerformanceStatusBase::setProject(Project *project) { if (m_project) { disconnect(m_project, &Project::localeChanged, this, &PerformanceStatusBase::slotLocaleChanged); } m_project = project; if (m_project) { connect(m_project, &Project::localeChanged, this, &PerformanceStatusBase::slotLocaleChanged); } m_chartmodel.setProject(project); static_cast(ui_performancetable->model())->setProject(project); slotLocaleChanged(); } void PerformanceStatusBase::slotLocaleChanged() { debugPlan; const QString currencySymbol = m_project->locale()->currencySymbol(); m_linechart.costaxis->setTitleText(i18nc("Chart axis title 1=currency symbol", "Cost (%1)", currencySymbol)); m_linechart.effortaxis->setTitleText(i18nc("Chart axis title", "Effort (hours)")); m_barchart.costaxis->setTitleText(i18nc("Chart axis title 1=currency symbol", "Cost (%1)", currencySymbol)); m_barchart.effortaxis->setTitleText(i18nc("Chart axis title", "Effort (hours)")); } bool PerformanceStatusBase::loadContext(const KoXmlElement &context) { debugPlan; m_chartinfo.showBarChart = context.attribute("show-bar-chart", "0").toInt(); m_chartinfo.showLineChart = context.attribute("show-line-chart", "1").toInt(); m_chartinfo.showTableView = context.attribute("show-table-view", "0").toInt(); m_chartinfo.showBaseValues = context.attribute("show-base-values", "1").toInt(); m_chartinfo.showIndices = context.attribute("show-indeces", "0").toInt(); m_chartinfo.showCost = context.attribute("show-cost", "1").toInt(); m_chartinfo.showBCWSCost = context.attribute("show-bcws-cost", "1").toInt(); m_chartinfo.showBCWPCost = context.attribute("show-bcwp-cost", "1").toInt(); m_chartinfo.showACWPCost = context.attribute("show-acwp-cost", "1").toInt(); m_chartinfo.showEffort = context.attribute("show-effort", "1").toInt(); m_chartinfo.showBCWSEffort = context.attribute("show-bcws-effort", "1").toInt(); m_chartinfo.showBCWPEffort = context.attribute("show-bcwp-effort", "1").toInt(); m_chartinfo.showACWPEffort = context.attribute("show-acwp-effort", "1").toInt(); m_chartinfo.showSpiCost = context.attribute("show-spi-cost", "1").toInt(); m_chartinfo.showCpiCost = context.attribute("show-cpi-cost", "1").toInt(); m_chartinfo.showSpiEffort = context.attribute("show-spi-effort", "1").toInt(); m_chartinfo.showCpiEffort = context.attribute("show-cpi-effort", "1").toInt(); debugPlan<<"Cost:"<project()); dia->printer().setCreator("Plan"); return dia; } void PerformanceStatusBase::setNodes(const QList &nodes) { m_chartmodel.setNodes(nodes); static_cast(ui_performancetable->model())->setNodes(nodes); } //------------------------------------------------ PerformanceStatusViewSettingsPanel::PerformanceStatusViewSettingsPanel(PerformanceStatusBase *view, QWidget *parent) : QWidget(parent), m_view(view) { setupUi(this); #ifndef PLAN_CHART_DEBUG ui_table->hide(); #endif PerformanceChartInfo info = m_view->chartInfo(); ui_linechart->setChecked(info.showLineChart); ui_barchart->setChecked(info.showBarChart); #ifdef PLAN_CHART_DEBUG ui_table->setChecked(info.showTableView); #endif ui_bcwsCost->setCheckState(info.showBCWSCost ? Qt::Checked : Qt::Unchecked); ui_bcwpCost->setCheckState(info.showBCWPCost ? Qt::Checked : Qt::Unchecked); ui_acwpCost->setCheckState(info.showACWPCost ? Qt::Checked : Qt::Unchecked); ui_cost->setChecked(info.showCost); ui_bcwsEffort->setCheckState(info.showBCWSEffort ? Qt::Checked : Qt::Unchecked); ui_bcwpEffort->setCheckState(info.showBCWPEffort ? Qt::Checked : Qt::Unchecked); ui_acwpEffort->setCheckState(info.showACWPEffort ? Qt::Checked : Qt::Unchecked); ui_effort->setChecked(info.showEffort); ui_showbasevalues->setChecked(info.showBaseValues); ui_showindices->setChecked(info.showIndices); ui_spicost->setCheckState(info.showSpiCost ? Qt::Checked : Qt::Unchecked); ui_cpicost->setCheckState(info.showCpiCost ? Qt::Checked : Qt::Unchecked); ui_spieffort->setCheckState(info.showSpiEffort ? Qt::Checked : Qt::Unchecked); ui_cpieffort->setCheckState(info.showCpiEffort ? Qt::Checked : Qt::Unchecked); connect(ui_showbasevalues, &QAbstractButton::toggled, this, &PerformanceStatusViewSettingsPanel::switchStackWidget); connect(ui_showindices, &QAbstractButton::toggled, this, &PerformanceStatusViewSettingsPanel::switchStackWidget); switchStackWidget(); } void PerformanceStatusViewSettingsPanel::slotOk() { PerformanceChartInfo info; info.showLineChart = ui_linechart->isChecked(); info.showBarChart = ui_barchart->isChecked(); info.showTableView = ui_table->isChecked(); info.showBaseValues = ui_showbasevalues->isChecked(); info.showIndices = ui_showindices->isChecked(); info.showBCWSCost = ui_bcwsCost->checkState() == Qt::Unchecked ? false : true; info.showBCWPCost = ui_bcwpCost->checkState() == Qt::Unchecked ? false : true; info.showACWPCost = ui_acwpCost->checkState() == Qt::Unchecked ? false : true; info.showCost = ui_cost->isChecked(); info.showBCWSEffort = ui_bcwsEffort->checkState() == Qt::Unchecked ? false : true; info.showBCWPEffort = ui_bcwpEffort->checkState() == Qt::Unchecked ? false : true; info.showACWPEffort = ui_acwpEffort->checkState() == Qt::Unchecked ? false : true; info.showEffort = ui_effort->isChecked(); info.showSpiCost = ui_spicost->isChecked(); info.showCpiCost = ui_cpicost->isChecked(); info.showSpiEffort = ui_spieffort->isChecked(); info.showCpiEffort = ui_cpieffort->isChecked(); m_view->setChartInfo(info); } void PerformanceStatusViewSettingsPanel::setDefault() { ui_linechart->setChecked(true); ui_bcwsCost->setCheckState(Qt::Checked); ui_bcwpCost->setCheckState(Qt::Checked); ui_acwpCost->setCheckState(Qt::Checked); ui_cost->setChecked(true); ui_bcwsEffort->setCheckState(Qt::Checked); ui_bcwpEffort->setCheckState(Qt::Checked); ui_acwpEffort->setCheckState(Qt::Checked); ui_effort->setChecked(Qt::Unchecked); ui_showbasevalues->setChecked(true); ui_showindices->setChecked(false); ui_spicost->setCheckState(Qt::Checked); ui_cpicost->setCheckState(Qt::Checked); ui_spieffort->setCheckState(Qt::Checked); ui_cpieffort->setCheckState(Qt::Checked); } void PerformanceStatusViewSettingsPanel::switchStackWidget() { if (ui_showbasevalues->isChecked()) { ui_stackWidget->setCurrentIndex(0); } else if (ui_showindices->isChecked()) { ui_stackWidget->setCurrentIndex(1); } //debugPlan<currentIndex(); } diff --git a/src/libs/ui/performance/PerformanceStatusBase.h b/src/libs/ui/performance/PerformanceStatusBase.h index 5739c0ba..72b11515 100644 --- a/src/libs/ui/performance/PerformanceStatusBase.h +++ b/src/libs/ui/performance/PerformanceStatusBase.h @@ -1,259 +1,260 @@ /* This file is part of the KDE project * Copyright (C) 2019 Dag Andersen * Copyright (C) 2007 - 2010 Dag Andersen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef PERFORMANCESTATUSBASE_H #define PERFORMANCESTATUSBASE_H #include "planui_export.h" #include "kptitemmodelbase.h" #include "kptviewbase.h" #include "kptitemviewsettup.h" #include "ui_PerformanceStatus.h" #include "ui_PerformanceStatusViewSettingsPanel.h" #include "kptnodechartmodel.h" #include #include class QItemSelection; class KoDocument; class KoPageLayoutWidget; class PrintingHeaderFooter; namespace KChart { class CartesianCoordinatePlane; class CartesianAxis; class Legend; }; namespace KPlato { class Project; class Node; class ScheduleManager; class TaskStatusItemModel; class NodeItemModel; class PerformanceStatusBase; typedef QList NodeList; struct PerformanceChartInfo { bool showBarChart; bool showLineChart; bool showTableView; bool showBaseValues; bool showIndices; bool showCost; bool showBCWSCost; bool showBCWPCost; bool showACWPCost; bool showEffort; bool showBCWSEffort; bool showBCWPEffort; bool showACWPEffort; bool showSpiCost; bool showCpiCost; bool showSpiEffort; bool showCpiEffort; bool effortShown() const { return (showBaseValues && showEffort) || (showIndices && (showSpiEffort || showCpiEffort)); } bool costShown() const { return (showBaseValues && showCost) || (showIndices && (showSpiCost || showCpiCost)); } bool bcwsCost() const { return showBaseValues && showCost && showBCWSCost; } bool bcwpCost() const { return showBaseValues && showCost && showBCWPCost; } bool acwpCost() const { return showBaseValues && showCost && showACWPCost; } bool bcwsEffort() const { return showBaseValues && showEffort && showBCWSEffort; } bool bcwpEffort() const { return showBaseValues && showEffort && showBCWPEffort; } bool acwpEffort() const { return showBaseValues && showEffort && showACWPEffort; } bool spiCost() const { return showIndices && showSpiCost; } bool cpiCost() const { return showIndices && showCpiCost; } bool spiEffort() const { return showIndices && showSpiEffort; } bool cpiEffort() const { return showIndices && showCpiEffort; } PerformanceChartInfo() { showBarChart = false; showLineChart = true; showTableView = false; showBaseValues = true; showIndices = false; showCost = showBCWSCost = showBCWPCost = showACWPCost = true; showEffort = showBCWSEffort = showBCWPEffort = showACWPEffort = true; showSpiCost = showCost = showSpiEffort = showCpiEffort = true; } bool operator!=(const PerformanceChartInfo &o) const { return ! operator==(o); } bool operator==(const PerformanceChartInfo &o) const { return showBarChart == o.showBarChart && showLineChart == o.showLineChart && showBaseValues == o.showBaseValues && showIndices == o.showIndices && showCost == o.showCost && showBCWSCost == o.showBCWSCost && showBCWPCost == o.showBCWPCost && showACWPCost == o.showACWPCost && showEffort == o.showEffort && showBCWSEffort == o.showBCWSEffort && showBCWPEffort == o.showBCWPEffort && showACWPEffort == o.showACWPEffort && showSpiCost == o.showSpiCost && showCpiCost == o.showCpiCost && showSpiEffort == o.showSpiEffort && showCpiEffort == o.showCpiEffort; } }; class PLANUI_EXPORT PerformanceStatusPrintingDialog : public PrintingDialog { Q_OBJECT public: PerformanceStatusPrintingDialog(ViewBase *view, PerformanceStatusBase *chart, Project *project = 0); ~PerformanceStatusPrintingDialog() {} virtual int documentLastPage() const; virtual QList createOptionWidgets() const; protected: virtual void printPage(int pageNumber, QPainter &painter); private: PerformanceStatusBase *m_chart; Project *m_project; }; class PerformanceStatusBase : public QWidget, public Ui::PerformanceStatus { Q_OBJECT public: explicit PerformanceStatusBase(QWidget *parent); void setProject(Project *project); void setScheduleManager(ScheduleManager *sm); ChartItemModel *model() const { return const_cast(&m_chartmodel); } void setupChart(); void setChartInfo(const PerformanceChartInfo &info); PerformanceChartInfo chartInfo() const { return m_chartinfo; } /// Loads context info into this view. Reimplement. virtual bool loadContext(const KoXmlElement &context); /// Save context info from this view. Reimplement. virtual void saveContext(QDomElement &context) const; /// Create a print job dialog KoPrintJob *createPrintJob(ViewBase *parent); void setNodes(const QList &nodes); void editCopy(); public Q_SLOTS: void refreshChart(); protected: void contextMenuEvent(QContextMenuEvent *event); void createBarChart(); void createLineChart(); void setEffortValuesVisible(bool visible); void setCostValuesVisible(bool visible); protected Q_SLOTS: void slotUpdate(); void slotLocaleChanged(); + void slotContextMenuRequested(const QPoint &pos); private: struct ChartContents { ~ChartContents() { delete dateaxis; delete effortaxis; delete costaxis; delete effortplane; delete costplane; delete effortdiagram; delete costdiagram; } ChartProxyModel costproxy; ChartProxyModel effortproxy; KChart::CartesianCoordinatePlane *effortplane; KChart::CartesianCoordinatePlane *costplane; KChart::AbstractDiagram *effortdiagram; KChart::AbstractDiagram *costdiagram; KChart::CartesianAxis *effortaxis; KChart::CartesianAxis *costaxis; KChart::CartesianAxis *dateaxis; ChartProxyModel piproxy; KChart::CartesianCoordinatePlane *piplane; KChart::AbstractDiagram *pidiagram; KChart::CartesianAxis *piaxis; }; void setupChart(ChartContents &cc); private: Project *m_project; ScheduleManager *m_manager; PerformanceChartInfo m_chartinfo; ChartItemModel m_chartmodel; KChart::Legend *m_legend; KChart::BarDiagram m_legenddiagram; struct ChartContents m_barchart; struct ChartContents m_linechart; }; //-------------------------------------- class PerformanceStatusViewSettingsPanel : public QWidget, public Ui::PerformanceStatusViewSettingsPanel { Q_OBJECT public: explicit PerformanceStatusViewSettingsPanel(PerformanceStatusBase *view, QWidget *parent = 0); public Q_SLOTS: void slotOk(); void setDefault(); Q_SIGNALS: void changed(); protected Q_SLOTS: void switchStackWidget(); private: PerformanceStatusBase *m_view; }; } //namespace KPlato #endif diff --git a/src/libs/ui/performance/PerformanceStatusView.cpp b/src/libs/ui/performance/PerformanceStatusView.cpp index 05c74037..39f7f854 100644 --- a/src/libs/ui/performance/PerformanceStatusView.cpp +++ b/src/libs/ui/performance/PerformanceStatusView.cpp @@ -1,373 +1,398 @@ /* This file is part of the KDE project * Copyright (C) 2019 Dag Andersen * Copyright (C) 2007 - 2010, 2012 Dag Andersen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ // clazy:excludeall=qstring-arg #include "PerformanceStatusView.h" #include "PerformanceStatusBase.h" #include "kptglobal.h" #include "kptlocale.h" #include "kptcommonstrings.h" #include "kptcommand.h" #include "kptproject.h" #include "kptschedule.h" #include "kpteffortcostmap.h" #include "Help.h" #include "kptnodeitemmodel.h" #include "kptdebug.h" #include #include "KoDocument.h" #include "KoPageLayoutWidget.h" +#include + #include #include #include #include #include #include #include #include #include #include #include #include +#include using namespace KChart; using namespace KPlato; //----------------------------------- PerformanceStatusTreeView::PerformanceStatusTreeView(QWidget *parent) : QSplitter(parent) , m_manager(0) { m_tree = new TreeViewBase(this); NodeItemModel *m = new NodeItemModel(m_tree); m_tree->setModel(m); QList lst1; lst1 << 1 << -1; // only display column 0 (NodeName) in tree view m_tree->setDefaultColumns(QList() << 0); m_tree->setColumnsHidden(lst1); m_tree->setSelectionMode(QAbstractItemView::ExtendedSelection); addWidget(m_tree); m_tree->setTreePosition(-1); m_chart = new PerformanceStatusBase(this); addWidget(m_chart); connect(m_tree->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PerformanceStatusTreeView::slotSelectionChanged); QTimer::singleShot(0, this, &PerformanceStatusTreeView::resizeSplitters); } void PerformanceStatusTreeView::slotSelectionChanged(const QItemSelection&, const QItemSelection&) { //debugPlan; QList nodes; foreach (const QModelIndex &i, m_tree->selectionModel()->selectedIndexes()) { Node *n = nodeModel()->node(i); if (! nodes.contains(n)) { nodes.append(n); } } m_chart->setNodes(nodes); } NodeItemModel *PerformanceStatusTreeView::nodeModel() const { return static_cast(m_tree->model()); } void PerformanceStatusTreeView::setScheduleManager(ScheduleManager *sm) { if (!sm && m_manager) { // we should only get here if the only schedule manager is scheduled, // or when last schedule manager is deleted m_domdoc.clear(); QDomElement element = m_domdoc.createElement("expanded"); m_domdoc.appendChild(element); treeView()->saveExpanded(element); } bool tryexpand = sm && !m_manager; bool expand = sm && m_manager && sm != m_manager; QDomDocument doc; if (expand) { QDomElement element = doc.createElement("expanded"); doc.appendChild(element); treeView()->saveExpanded(element); } m_manager = sm; nodeModel()->setScheduleManager(sm); m_chart->setScheduleManager(sm); if (expand) { treeView()->doExpand(doc); } else if (tryexpand) { treeView()->doExpand(m_domdoc); } } Project *PerformanceStatusTreeView::project() const { return nodeModel()->project(); } void PerformanceStatusTreeView::setProject(Project *project) { nodeModel()->setProject(project); m_chart->setProject(project); m_chart->setNodes(QList() << project); } bool PerformanceStatusTreeView::loadContext(const KoXmlElement &context) { debugPlan; bool res = false; res = m_chart->loadContext(context.namedItem("chart").toElement()); res &= m_tree->loadContext(nodeModel()->columnMap(), context.namedItem("tree").toElement()); return res; } void PerformanceStatusTreeView::saveContext(QDomElement &context) const { QDomElement c = context.ownerDocument().createElement("chart"); context.appendChild(c); m_chart->saveContext(c); QDomElement t = context.ownerDocument().createElement("tree"); context.appendChild(t); m_tree->saveContext(nodeModel()->columnMap(), t); } KoPrintJob *PerformanceStatusTreeView::createPrintJob(ViewBase *view) { return m_chart->createPrintJob(view); } // hackish way to get reasonable initial splitter sizes void PerformanceStatusTreeView::resizeSplitters() { int x1 = sizes().value(0); int x2 = sizes().value(1); if (x1 == 0 && x2 == 0) { // not shown yet, try later QTimer::singleShot(100, this, &PerformanceStatusTreeView::resizeSplitters); return; } if (x1 == 0 || x2 == 0) { // one is hidden, do nothing return; } int tot = x1 + x2; x1 = qMax(x1, qMin((tot) / 2, 150)); setSizes(QList() << x1 << (tot - x1)); } void PerformanceStatusTreeView::editCopy() { QMimeData *mimeData = new QMimeData; QPixmap pixmap(size()); render(&pixmap); mimeData->setImageData(pixmap); QGuiApplication::clipboard()->setMimeData(mimeData); } //----------------------------------- PerformanceStatusView::PerformanceStatusView(KoPart *part, KoDocument *doc, QWidget *parent) : ViewBase(part, doc, parent) { debugPlan<<"-------------------- creating PerformanceStatusView -------------------"; setXMLFile("PerformanceStatusViewUi.rc"); QVBoxLayout * l = new QVBoxLayout(this); l->setMargin(0); m_view = new PerformanceStatusTreeView(this); connect(this, &ViewBase::expandAll, m_view->treeView(), &TreeViewBase::slotExpand); connect(this, &ViewBase::collapseAll, m_view->treeView(), &TreeViewBase::slotCollapse); l->addWidget(m_view); setupGui(); - connect(m_view->treeView(), &TreeViewBase::headerContextMenuRequested, this, &ViewBase::slotHeaderContextMenuRequested); - connect(m_view->chartView(), &QWidget::customContextMenuRequested, this, &ViewBase::slotHeaderContextMenuRequested); + connect(m_view->chartView(), &QWidget::customContextMenuRequested, this, &PerformanceStatusView::slotChartContextMenuRequested); connect(m_view->treeView(), SIGNAL(contextMenuRequested(QModelIndex,QPoint,QModelIndexList)), SLOT(slotContextMenuRequested(QModelIndex,QPoint))); Help::add(this, xi18nc("@info:whatsthis", "Task Performance View" "" "Displays performance data aggregated to the selected task." "" "This view supports configuration and printing using the context menu." "More..." "", Help::page("Manual/Task_Performance_View"))); } void PerformanceStatusView::slotEditCopy() { m_view->editCopy(); } + +void PerformanceStatusView::slotChartContextMenuRequested(const QPoint& pos) +{ + debugPlan< lst; + const KActionCollection *c = actionCollection(); + lst << c->action("print"); + lst << c->action("print_preview"); + lst << c->action("print_pdf"); + lst << c->action("print_options"); + lst << new QAction(); + lst.last()->setSeparator(true); + lst << c->action("configure_view"); + if (!lst.isEmpty()) { + QMenu::exec(lst, pos, lst.first()); + } +} + +void PerformanceStatusView::slotTableContextMenuRequested(const QPoint& pos) +{ + debugPlan<treeView()->setContextMenuIndex(index); if (! index.isValid()) { slotHeaderContextMenuRequested(pos); return; } Node *node = m_view->nodeModel()->node(index); if (node == 0) { slotHeaderContextMenuRequested(pos); m_view->treeView()->setContextMenuIndex(QModelIndex()); return; } slotContextMenuRequested(node, pos); m_view->treeView()->setContextMenuIndex(QModelIndex()); } Node *PerformanceStatusView::currentNode() const { return m_view->nodeModel()->node(m_view->treeView()->selectionModel()->currentIndex()); } void PerformanceStatusView::slotContextMenuRequested(Node *node, const QPoint& pos) { debugPlan<name()<<" :"<type()) { case Node::Type_Task: name = "taskview_popup"; break; case Node::Type_Milestone: name = "taskview_milestone_popup"; break; case Node::Type_Summarytask: name = "taskview_summary_popup"; break; default: break; } //debugPlan<setScheduleManager(sm); } void PerformanceStatusView::setProject(Project *project) { m_view->setProject(project); } void PerformanceStatusView::setGuiActive(bool activate) { debugPlan<objectName() == "print_options"); connect(dlg, SIGNAL(finished(int)), SLOT(slotOptionsFinished(int))); dlg->open(); } bool PerformanceStatusView::loadContext(const KoXmlElement &context) { debugPlan; ViewBase::loadContext(context); return m_view->loadContext(context); } void PerformanceStatusView::saveContext(QDomElement &context) const { ViewBase::saveContext(context); m_view->saveContext(context); } KoPrintJob *PerformanceStatusView::createPrintJob() { return m_view->createPrintJob(this); } void PerformanceStatusView::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_dragStartPosition = event->pos(); } ViewBase::mousePressEvent(event); } void PerformanceStatusView::mouseMoveEvent(QMouseEvent *event) { if (!(event->buttons() & Qt::LeftButton)) { ViewBase::mouseMoveEvent(event); return; } if ((event->pos() - m_dragStartPosition).manhattanLength() < QApplication::startDragDistance()) { ViewBase::mouseMoveEvent(event); return; } event->accept(); QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; QPixmap pixmap(m_view->size()); m_view->render(&pixmap); mimeData->setImageData(pixmap); drag->setMimeData(mimeData); drag->exec(Qt::CopyAction); } //----------------- PerformanceStatusViewSettingsDialog::PerformanceStatusViewSettingsDialog(PerformanceStatusView *view, PerformanceStatusTreeView *treeview, QWidget *parent, bool selectPrint) : ItemViewSettupDialog(view, treeview->treeView(), true, parent) { PerformanceStatusViewSettingsPanel *panel = new PerformanceStatusViewSettingsPanel(treeview->chartView(), this); KPageWidgetItem *page = insertWidget(0, panel, i18n("Chart"), i18n("Chart Settings")); setCurrentPage(page); addPrintingOptions(selectPrint); //connect(panel, SIGNAL(changed(bool)), this, SLOT(enableButtonOk(bool))); connect(this, &QDialog::accepted, panel, &PerformanceStatusViewSettingsPanel::slotOk); connect(button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked, panel, &PerformanceStatusViewSettingsPanel::setDefault); } diff --git a/src/libs/ui/performance/PerformanceStatusView.h b/src/libs/ui/performance/PerformanceStatusView.h index 13c794b1..f765c854 100644 --- a/src/libs/ui/performance/PerformanceStatusView.h +++ b/src/libs/ui/performance/PerformanceStatusView.h @@ -1,156 +1,158 @@ /* This file is part of the KDE project * Copyright (C) 2019 Dag Andersen * Copyright (C) 2007 - 2010 Dag Andersen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef PERFORMANCESTATUSVIEW_H #define PERFORMANCESTATUSVIEW_H #include "planui_export.h" #include "PerformanceStatusBase.h" #include "kptitemmodelbase.h" #include "kptviewbase.h" #include "kptitemviewsettup.h" #include "kptnodechartmodel.h" #include #include class QItemSelection; class KoDocument; class KoPageLayoutWidget; class PrintingHeaderFooter; namespace KChart { class CartesianCoordinatePlane; class CartesianAxis; class Legend; }; namespace KPlato { class Project; class Node; class ScheduleManager; class TaskStatusItemModel; class NodeItemModel; class PerformanceStatusBase; class PerformanceStatusTreeView : public QSplitter { Q_OBJECT public: explicit PerformanceStatusTreeView(QWidget *parent); NodeItemModel *nodeModel() const; Project *project() const; void setProject(Project *project); void setScheduleManager(ScheduleManager *sm); /// Loads context info into this view. virtual bool loadContext(const KoXmlElement &context); /// Save context info from this view. virtual void saveContext(QDomElement &context) const; TreeViewBase *treeView() const { return m_tree; } PerformanceStatusBase *chartView() const { return m_chart; } KoPrintJob *createPrintJob(ViewBase *view); void editCopy(); protected Q_SLOTS: void slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); void resizeSplitters(); private: TreeViewBase *m_tree; PerformanceStatusBase *m_chart; ScheduleManager *m_manager; QDomDocument m_domdoc; }; //---------------------------------- class PLANUI_EXPORT PerformanceStatusView : public ViewBase { Q_OBJECT public: PerformanceStatusView(KoPart *part, KoDocument *doc, QWidget *parent); void setupGui(); Project *project() const { return m_view->project(); } virtual void setProject(Project *project); /// Loads context info into this view. Reimplement. virtual bool loadContext(const KoXmlElement &context); /// Save context info from this view. Reimplement. virtual void saveContext(QDomElement &context) const; Node *currentNode() const; KoPrintJob *createPrintJob(); public Q_SLOTS: /// Activate/deactivate the gui virtual void setGuiActive(bool activate); void setScheduleManager(KPlato::ScheduleManager *sm); void slotEditCopy(); protected Q_SLOTS: virtual void slotOptions(); protected: void updateActionsEnabled(bool on); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); private Q_SLOTS: void slotContextMenuRequested(KPlato::Node *node, const QPoint& pos); void slotContextMenuRequested(const QModelIndex &index, const QPoint& pos); + void slotChartContextMenuRequested(const QPoint& pos); + void slotTableContextMenuRequested(const QPoint& pos); private: PerformanceStatusTreeView *m_view; QPoint m_dragStartPosition; }; class PerformanceStatusViewSettingsDialog : public ItemViewSettupDialog { Q_OBJECT public: explicit PerformanceStatusViewSettingsDialog(PerformanceStatusView *view, PerformanceStatusTreeView *treeview, QWidget *parent = 0, bool selectPrint = false); }; } //namespace KPlato #endif diff --git a/src/libs/ui/performance/ProjectStatusView.cpp b/src/libs/ui/performance/ProjectStatusView.cpp index 42b8a111..6679411a 100644 --- a/src/libs/ui/performance/ProjectStatusView.cpp +++ b/src/libs/ui/performance/ProjectStatusView.cpp @@ -1,202 +1,201 @@ /* This file is part of the KDE project * Copyright (C) 2019 Dag Andersen * Copyright (C) 2007 - 2010, 2012 Dag Andersen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ // clazy:excludeall=qstring-arg #include "ProjectStatusView.h" #include "PerformanceStatusBase.h" #include "kptglobal.h" #include "kptlocale.h" #include "kptcommonstrings.h" #include "kptcommand.h" #include "kptproject.h" #include "kptschedule.h" #include "kpteffortcostmap.h" #include "Help.h" #include "kptdebug.h" #include #include "KoDocument.h" #include "KoPageLayoutWidget.h" #include #include #include #include using namespace KChart; using namespace KPlato; ProjectStatusView::ProjectStatusView(KoPart *part, KoDocument *doc, QWidget *parent) : ViewBase(part, doc, parent), m_project(0) { debugPlan<<"-------------------- creating ProjectStatusView -------------------"; setXMLFile("ProjectStatusViewUi.rc"); QVBoxLayout * l = new QVBoxLayout(this); l->setMargin(0); m_view = new PerformanceStatusBase(this); l->addWidget(m_view); setupGui(); connect(m_view, &QWidget::customContextMenuRequested, this, &ViewBase::slotHeaderContextMenuRequested); Help::add(this, xi18nc("@info:whatsthis", "Project Performance View" "" "Displays performance data aggregated to the project level." "" "This view supports configuration and printing using the context menu." "More..." "", Help::page("Manual/Project_Performance_View"))); } void ProjectStatusView::setScheduleManager(ScheduleManager *sm) { //debugPlan; m_view->setScheduleManager(sm); m_view->model()->clearNodes(); if (m_project) { m_view->setNodes(QList() << m_project); } } void ProjectStatusView::setProject(Project *project) { m_project = project; m_view->model()->clearNodes(); m_view->setProject(project); } void ProjectStatusView::setGuiActive(bool activate) { debugPlan<objectName() == "print_options"); connect(dlg, SIGNAL(finished(int)), SLOT(slotOptionsFinished(int))); dlg->open(); } bool ProjectStatusView::loadContext(const KoXmlElement &context) { debugPlan; ViewBase::loadContext(context); return m_view->loadContext(context); } void ProjectStatusView::saveContext(QDomElement &context) const { ViewBase::saveContext(context); m_view->saveContext(context); } KoPrintJob *ProjectStatusView::createPrintJob() { return m_view->createPrintJob(this); } void ProjectStatusView::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_dragStartPosition = event->pos(); } - ViewBase::mousePressEvent(event); + event->ignore(); } void ProjectStatusView::mouseMoveEvent(QMouseEvent *event) { + event->ignore(); if (!(event->buttons() & Qt::LeftButton)) { - ViewBase::mouseMoveEvent(event); return; } if ((event->pos() - m_dragStartPosition).manhattanLength() < QApplication::startDragDistance()) { - ViewBase::mouseMoveEvent(event); return; } event->accept(); QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; QPixmap pixmap(m_view->size()); m_view->render(&pixmap); mimeData->setImageData(pixmap); drag->setMimeData(mimeData); drag->exec(Qt::CopyAction); } void ProjectStatusView::slotEditCopy() { m_view->editCopy(); } //----------------- ProjectStatusViewSettingsDialog::ProjectStatusViewSettingsDialog(ViewBase *base, PerformanceStatusBase *view, QWidget *parent, bool selectPrint) : KPageDialog(parent), m_base(base) { PerformanceStatusViewSettingsPanel *panel = new PerformanceStatusViewSettingsPanel(view, this); KPageWidgetItem *page = new KPageWidgetItem(panel, i18n("Chart")); page->setHeader(i18n("Chart Settings")); addPage(page); QTabWidget *tab = new QTabWidget(); QWidget *w = ViewBase::createPageLayoutWidget(base); tab->addTab(w, w->windowTitle()); m_pagelayout = w->findChild(); Q_ASSERT(m_pagelayout); m_headerfooter = ViewBase::createHeaderFooterWidget(base); m_headerfooter->setOptions(base->printingOptions()); tab->addTab(m_headerfooter, m_headerfooter->windowTitle()); page = addPage(tab, i18n("Printing")); page->setHeader(i18n("Printing Options")); if (selectPrint) { setCurrentPage(page); } connect(this, &QDialog::accepted, panel, &PerformanceStatusViewSettingsPanel::slotOk); //TODO: there was no default button configured, should there? // connect(button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked(bool)), panel, SLOT(setDefault())); connect(this, &QDialog::accepted, this, &ProjectStatusViewSettingsDialog::slotOk); } void ProjectStatusViewSettingsDialog::slotOk() { debugPlan; m_base->setPageLayout(m_pagelayout->pageLayout()); m_base->setPrintingOptions(m_headerfooter->options()); }