diff --git a/schema/plan-0.7.0.dtd b/schema/plan-0.7.0.dtd index e9e07581..b6b41c6a 100644 --- a/schema/plan-0.7.0.dtd +++ b/schema/plan-0.7.0.dtd @@ -1,385 +1,386 @@ + name CDATA #IMPLIED + type CDATA #IMPLIED + coordinator CDATA #IMPLIED> diff --git a/src/libs/kernel/CMakeLists.txt b/src/libs/kernel/CMakeLists.txt index d7d031a4..7a209038 100644 --- a/src/libs/kernel/CMakeLists.txt +++ b/src/libs/kernel/CMakeLists.txt @@ -1,76 +1,77 @@ include_directories( ${PLANKERNEL_INCLUDES} ${PLANKUNDO2_INCLUDES} ${PLANSTORE_INCLUDES} ) ########### KPlato kernel library ############### set(plankernel_LIB_SRCS kptglobal.cpp kptlocale.cpp kpteffortcostmap.cpp kptdocuments.cpp kptaccount.cpp kptappointment.cpp kptnode.cpp kptproject.cpp kptrelation.cpp ResourceGroup.cpp Resource.cpp kptresourcerequest.cpp kpttask.cpp kptduration.cpp kptdatetime.cpp kptcalendar.cpp kptschedule.cpp kptwbsdefinition.cpp kptcommand.cpp kptpackage.cpp kptdebug.cpp commands/NamedCommand.cpp commands/MacroCommand.cpp commands/SetTaskModulesCommand.cpp commands/AddResourceCmd.cpp commands/RemoveResourceCmd.cpp commands/AddParentGroupCmd.cpp commands/RemoveParentGroupCmd.cpp commands/AddParentGroupCmd.cpp commands/RemoveParentGroupCmd.cpp commands/ModifyResourceRequestAlternativeCmd.cpp + commands/ResourceGroupModifyCoordinatorCmd.cpp kptschedulerplugin.cpp kptconfigbase.cpp KPlatoXmlLoaderBase.cpp ) add_library(plankernel SHARED ${plankernel_LIB_SRCS}) generate_export_header(plankernel) target_link_libraries(plankernel PUBLIC plankundo2 planstore planwidgetutils # KF5::I18n # KF5::CoreAddons ) if(KF5Holidays_FOUND) target_link_libraries(plankernel PUBLIC KF5::Holidays) endif() set_target_properties(plankernel PROPERTIES VERSION ${GENERIC_PLAN_LIB_VERSION} SOVERSION ${GENERIC_PLAN_LIB_SOVERSION} ) install(TARGETS plankernel ${INSTALL_TARGETS_DEFAULT_ARGS}) # TODO: with the new embedded JSON data for plugins there is no schema ATM to define extended properties # plan_schedulerplugin.desktop if(BUILD_TESTING) add_subdirectory( tests ) endif() diff --git a/src/libs/kernel/ResourceGroup.cpp b/src/libs/kernel/ResourceGroup.cpp index 8b23c96a..fe2be907 100644 --- a/src/libs/kernel/ResourceGroup.cpp +++ b/src/libs/kernel/ResourceGroup.cpp @@ -1,416 +1,428 @@ /* This file is part of the KDE project * Copyright (C) 2001 Thomas zander * Copyright (C) 2004-2007, 2012 Dag Andersen * Copyright (C) 2016 Dag Andersen * Copyright (C) 2019 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 "ResourceGroup.h" #include "Resource.h" #include "kptresourcerequest.h" #include "kptlocale.h" #include "kptaccount.h" #include "kptappointment.h" #include "kptproject.h" #include "kpttask.h" #include "kptdatetime.h" #include "kptcalendar.h" #include "kpteffortcostmap.h" #include "kptschedule.h" #include "kptxmlloaderobject.h" #include "kptdebug.h" #include #include #include using namespace KPlato; ResourceGroup::ResourceGroup() : QObject(nullptr) , m_blockChanged(false) , m_shared(false) { m_project = nullptr; m_parent = nullptr; m_type = Type_Work; //debugPlan<<"("<removeChildGroup(this); } else if (m_project) { m_project->takeResourceGroup(this); // also removes id } for (Resource *r : m_resources) { r->removeParentGroup(this); } qDeleteAll(m_childGroups); //debugPlan<<"("<m_project; //Don't copy //m_parent = group->m_parent; //Don't copy // m_id = group->m_id; //Don't copy m_type = group->m_type; m_name = group->m_name; } void ResourceGroup::blockChanged(bool on) { m_blockChanged = on; } void ResourceGroup::changed() { if (!m_blockChanged) { emit dataChanged(this); if (m_project) { emit m_project->resourceGroupChanged(this); } } } void ResourceGroup::setId(const QString& id) { //debugPlan<project() : m_project; } void ResourceGroup::setProject(Project *project) { if (project != m_project) { if (m_project) { removeId(); } } m_project = project; foreach (Resource *r, m_resources) { r->setProject(project); } } bool ResourceGroup::isScheduled() const { foreach (Resource *r, m_resources) { if (r->isScheduled()) { return true; } } return false; } bool ResourceGroup::isBaselined(long id) const { Q_UNUSED(id); foreach (const Resource *r, m_resources) { if (r->isBaselined()) { return true; } } return false; } ResourceGroup *ResourceGroup::parentGroup() const { return m_parent; } void ResourceGroup::setParentGroup(ResourceGroup *parent) { m_parent = parent; } int ResourceGroup::indexOf(ResourceGroup *group) const { return m_childGroups.indexOf(group); } int ResourceGroup::numChildGroups() const { return m_childGroups.count(); } void ResourceGroup::addChildGroup(ResourceGroup *group, int row) { Q_ASSERT(!m_childGroups.contains(group)); int pos = row < 0 ? m_childGroups.count() : row; emit groupToBeAdded(project(), this, pos); m_childGroups.insert(pos, group); group->setParentGroup(this); emit groupAdded(group); } ResourceGroup *ResourceGroup::childGroupAt(int row) const { return m_childGroups.value(row); } QList ResourceGroup::childGroups() const { return m_childGroups; } void ResourceGroup::removeChildGroup(ResourceGroup *child) { int row = m_childGroups.indexOf(child); emit groupToBeRemoved(project(), this, row, child); m_childGroups.removeOne(child); child->setParentGroup(nullptr); emit groupRemoved(); } void ResourceGroup::addResource(Resource* resource, Risk *risk) { addResource(m_resources.count(), resource, risk); } void ResourceGroup::addResource(int index, Resource* resource, Risk*) { if (!m_resources.contains(resource)) { int i = index == -1 ? m_resources.count() : index; emit resourceToBeAdded(this, i); m_resources.insert(i, resource); emit resourceAdded(resource); } resource->addParentGroup(this); } Resource *ResourceGroup::takeResource(Resource *resource) { Resource *r = 0; int i = m_resources.indexOf(resource); if (i != -1) { emit resourceToBeRemoved(this, i, resource); r = m_resources.takeAt(i); emit resourceRemoved(); r->removeParentGroup(this); } return r; } int ResourceGroup::indexOf(const Resource *resource) const { return m_resources.indexOf(const_cast(resource)); //??? } Risk* ResourceGroup::getRisk(int) { return 0L; } void ResourceGroup::addRequiredResource(ResourceGroup*) { } ResourceGroup* ResourceGroup::getRequiredResource(int) { return 0L; } void ResourceGroup::deleteRequiredResource(int) { } bool ResourceGroup::load(KoXmlElement &element, XMLLoaderObject &status) { //debugPlan; setId(element.attribute("id")); m_name = element.attribute("name"); setType(element.attribute("type")); m_shared = element.attribute("shared", "0").toInt(); + m_coordinator = element.attribute("coordinator"); KoXmlNode n = element.firstChild(); for (; ! n.isNull(); n = n.nextSibling()) { if (! n.isElement()) { continue; } KoXmlElement e = n.toElement(); if (e.tagName() == "resource-group") { ResourceGroup *child = new ResourceGroup(); if (child->load(e, status)) { addChildGroup(child); } else { errorPlanXml<<"Faild to load ResourceGroup"; delete child; } } else if (status.version() < "0.7.0" && e.tagName() == "resource") { // Load the resource Resource *child = new Resource(); if (child->load(e, status)) { child->addParentGroup(this); } else { // TODO: Complain about this delete child; } } } return true; } void ResourceGroup::save(QDomElement &element) const { //debugPlan; QDomElement me = element.ownerDocument().createElement("resource-group"); element.appendChild(me); me.setAttribute("id", m_id); me.setAttribute("name", m_name); me.setAttribute("type", m_type); me.setAttribute("shared", m_shared); + me.setAttribute("coordinator", m_coordinator); for (ResourceGroup *g : m_childGroups) { g->save(me); } } void ResourceGroup::saveWorkPackageXML(QDomElement &element, const QList &lst) const { QDomElement me = element.ownerDocument().createElement("resource-group"); element.appendChild(me); me.setAttribute("id", m_id); me.setAttribute("name", m_name); foreach (Resource *r, m_resources) { if (lst.contains(r)) { r->save(me); } } } void ResourceGroup::initiateCalculation(Schedule &sch) { clearNodes(); } int ResourceGroup::units() const { int u = 0; foreach (const Resource *r, m_resources) { u += r->units(); } return u; } ResourceGroup *ResourceGroup::findId(const QString &id) const { Project *p = project(); return p ? p->findResourceGroup(id) : nullptr; } void ResourceGroup::removeId(const QString &id) { Project *p = project(); if (p) { p->removeResourceGroupId(id); } } void ResourceGroup::insertId(const QString &id) { //debugPlan; Project *p = project(); if (p) { p->insertResourceGroupId(id, this); } } Appointment ResourceGroup::appointmentIntervals() const { Appointment a; foreach (Resource *r, m_resources) { a += r->appointmentIntervals(); } return a; } DateTime ResourceGroup::startTime(long id) const { DateTime dt; foreach (Resource *r, m_resources) { DateTime t = r->startTime(id); if (! dt.isValid() || t < dt) { dt = t; } } return dt; } DateTime ResourceGroup::endTime(long id) const { DateTime dt; foreach (Resource *r, m_resources) { DateTime t = r->endTime(id); if (! dt.isValid() || t > dt) { dt = t; } } return dt; } bool ResourceGroup::isShared() const { return m_shared; } void ResourceGroup::setShared(bool on) { m_shared = on; } QDebug operator<<(QDebug dbg, const KPlato::ResourceGroup *g) { dbg.nospace().noquote()<<"ResourceGroup["; if (g) { dbg<<'('<<(void*)g<<')'<name()<<','<id()<<','<numChildGroups(); } else { dbg<<(void*)g; } dbg<<']'; return dbg.space().quote(); } diff --git a/src/libs/kernel/ResourceGroup.h b/src/libs/kernel/ResourceGroup.h index 9afe8ba5..02a05c10 100644 --- a/src/libs/kernel/ResourceGroup.h +++ b/src/libs/kernel/ResourceGroup.h @@ -1,228 +1,232 @@ /* This file is part of the KDE project * Copyright (C) 2001 Thomas Zander zander@kde.org * Copyright (C) 2004-2007 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 KPTRESOURCEGROUP_H #define KPTRESOURCEGROUP_H #include "plankernel_export.h" #include "kptglobal.h" #include "kptduration.h" #include "kptdatetime.h" #include "kptappointment.h" #include "kptcalendar.h" #include #include #include #include /// The main namespace. namespace KPlato { class Account; class Risk; class Effort; class Appointment; class Task; class Node; class Project; class Resource; class ResourceRequest; class ResourceRequestCollection; class Schedule; class ResourceSchedule; class Schedule; class XMLLoaderObject; class DateTimeInterval; /** * This class represents a group of similar resources to be assigned to a task * e.g. The list of employees, computer resources, etc */ /* IDEA; lets create a resourceGroup that has the intelligence to import PIM schedules * from the kroupware project and use the schedules to use the factory pattern to build * Resources (probably a derived class) which returns values on getFirstAvailableTime * and friends based on the schedules we got from the PIM projects. * (Thomas Zander mrt-2003 by suggestion of Shaheed) */ class PLANKERNEL_EXPORT ResourceGroup : public QObject { Q_OBJECT public: /// Default constructor explicit ResourceGroup(); explicit ResourceGroup(const ResourceGroup *group); ~ResourceGroup() override; enum Type { Type_Work, Type_Material }; QString id() const { return m_id; } void setId(const QString& id); Project *project() const; void setName(const QString& n); const QString &name() const { return m_name;} /// A free-text type void setType(const QString &type); QString type() const; + QString coordinator() const; + void setCoordinator(const QString &coordinator); + bool isScheduled() const; /// Return true if any resource in this group is baselined bool isBaselined(long id = BASELINESCHEDULE) const; ResourceGroup *parentGroup() const; void setParentGroup(ResourceGroup *parent); int indexOf(ResourceGroup *group) const; int numChildGroups() const; void addChildGroup(ResourceGroup *group, int row = -1); ResourceGroup *childGroupAt(int i) const; QList childGroups() const; void removeChildGroup(ResourceGroup *group); /** Manage the resources in this list *

At some point we will have to look at not mixing types of resources * (e.g. you can't add a person to a list of computers * *

Risks must always be associated with a resource, so there is no option * to manipulate risks (@ref Risk) separately */ void addResource(Resource *resource, Risk *risk = nullptr); void addResource(int index, Resource*, Risk*); Resource *takeResource(Resource *resource); QList resources() const { return m_resources; } int indexOf(const Resource *resource) const; Resource *resourceAt(int pos) const { return m_resources.value(pos); } int numResources() const { return m_resources.count(); } Risk* getRisk(int); /** Manage the dependent resources. This is a list of the resource * groups that must have available resources for this resource to * perform the work *

see also @ref getRequiredResource, @ref getRequiredResource */ void addRequiredResource(ResourceGroup*); /** Manage the dependent resources. This is a list of the resource * groups that must have available resources for this resource to * perform the work *

see also @ref addRequiredResource, @ref getRequiredResource */ ResourceGroup* getRequiredResource(int); /** Manage the dependent resources. This is a list of the resource * groups that must have available resources for this resource to * perform the work *

see also @ref getRequiredResource, @ref addRequiredResource */ void deleteRequiredResource(int); bool load(KoXmlElement &element, XMLLoaderObject &status); void save(QDomElement &element) const; /// Save workpackage document. Include only resources listed in @p lst void saveWorkPackageXML(QDomElement &element, const QList &lst) const; void initiateCalculation(Schedule &sch); void addNode(Node *node) { m_nodes.append(node); } void clearNodes() { m_nodes.clear(); } Calendar *defaultCalendar() { return m_defaultCalendar; } int units() const; ResourceGroup *findId() const { return findId(m_id); } ResourceGroup *findId(const QString &id) const; void removeId() { return removeId(m_id); } void removeId(const QString &id); void insertId(const QString &id); Appointment appointmentIntervals() const; // m_project is set when the resourcegroup is added to the project, // and reset when the resourcegroup is removed from the project void setProject(Project *project); void copy(const ResourceGroup *group); DateTime startTime(long id) const; DateTime endTime(long id) const; void blockChanged(bool on = true); /// A resource can be local to this project, or /// defined externally and shared with other projects bool isShared() const; /// Set resource to be shared if on = true, or local if on = false void setShared(bool on); #ifndef NDEBUG void printDebug(const QString& ident); #endif Q_SIGNALS: void dataChanged(KPlato::ResourceGroup *group); void groupToBeAdded(KPlato::Project *project, KPlato::ResourceGroup *parent, int row); void groupAdded(KPlato::ResourceGroup *child); void groupToBeRemoved(KPlato::Project *project, KPlato::ResourceGroup *parent, int row, KPlato::ResourceGroup *group); void groupRemoved(); void resourceToBeAdded(KPlato::ResourceGroup *group, int row); void resourceAdded(KPlato::Resource *resource); void resourceToBeRemoved(KPlato::ResourceGroup *group, int row, KPlato::Resource *resource); void resourceRemoved(); protected: virtual void changed(); private: Project *m_project; QString m_id; // unique id QString m_name; ResourceGroup *m_parent; QList m_childGroups; QList m_resources; QList m_risks; QList m_requires; QList m_nodes; //The nodes that want resources from us Calendar *m_defaultCalendar; QString m_type; + QString m_coordinator; bool m_blockChanged; bool m_shared; }; } // namespace KPlato PLANKERNEL_EXPORT QDebug operator<<(QDebug dbg, const KPlato::ResourceGroup *g); #endif diff --git a/src/libs/models/ResourceGroupItemModel.cpp b/src/libs/models/ResourceGroupItemModel.cpp index f2a7d6cc..e172b35f 100644 --- a/src/libs/models/ResourceGroupItemModel.cpp +++ b/src/libs/models/ResourceGroupItemModel.cpp @@ -1,913 +1,921 @@ /* This file is part of the KDE project * Copyright (C) 2007 Dag Andersen * Copyright (C) 2011, 2012 Dag Andersen * Copyright (C) 2016 Dag Andersen * Copyright (C) 2019 Dag Andersen * Copyright (C) 2020 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 "ResourceGroupItemModel.h" #include #include "AddParentGroupCmd.h" #include "RemoveParentGroupCmd.h" +#include #include "kptlocale.h" #include "kptcommonstrings.h" #include "kptcommand.h" #include "kptitemmodelbase.h" #include "kptcalendar.h" #include "kptduration.h" #include "kptnode.h" #include "kptproject.h" #include "kpttask.h" #include "kptresource.h" #include "kptdatetime.h" #include "kptdebug.h" #include #include #include #include #include #include #include #ifdef PLAN_KCONTACTS_FOUND #include #include #endif using namespace KPlato; ResourceGroupItemModel::ResourceGroupItemModel(QObject *parent) : ItemModelBase(parent) , m_resourcesEnabled(false) { } ResourceGroupItemModel::~ResourceGroupItemModel() { } void ResourceGroupItemModel::setResourcesEnabled(bool enable) { beginResetModel(); m_resourcesEnabled = enable; endResetModel(); } bool ResourceGroupItemModel::resourcesEnabled() const { return m_resourcesEnabled; } void ResourceGroupItemModel::slotResourceToBeAdded(ResourceGroup *group, int row) { debugPlan<resourceGroups()) { connectSignals(g, false); } } m_project = project; if (m_project) { connect(m_project, &Project::aboutToBeDeleted, this, &ResourceGroupItemModel::projectDeleted); connect(m_project, &Project::localeChanged, this, &ResourceGroupItemModel::slotLayoutChanged); connect(m_project, &Project::resourceGroupChanged, this, &ResourceGroupItemModel::slotResourceGroupChanged, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(m_project, &Project::resourceGroupToBeAdded, this, &ResourceGroupItemModel::slotResourceGroupToBeAdded, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(m_project, &Project::resourceGroupAdded, this, &ResourceGroupItemModel::slotResourceGroupAdded, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(m_project, &Project::resourceGroupToBeRemoved, this, &ResourceGroupItemModel::slotResourceGroupToBeRemoved, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(m_project, &Project::resourceGroupRemoved, this, &ResourceGroupItemModel::slotResourceGroupRemoved, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); for (ResourceGroup *g : m_project->resourceGroups()) { connectSignals(g, true); } } m_groupModel.setProject(m_project); m_resourceModel.setProject(m_project); endResetModel(); } void ResourceGroupItemModel::connectSignals(ResourceGroup *group, bool enable) { if (enable) { connect(group, &ResourceGroup::dataChanged, this, &ResourceGroupItemModel::slotResourceGroupChanged, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(group, &ResourceGroup::groupToBeAdded, this, &ResourceGroupItemModel::slotResourceGroupToBeAdded, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(group, &ResourceGroup::groupAdded, this, &ResourceGroupItemModel::slotResourceGroupAdded, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(group, &ResourceGroup::groupToBeRemoved, this, &ResourceGroupItemModel::slotResourceGroupToBeRemoved, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(group, &ResourceGroup::groupRemoved, this, &ResourceGroupItemModel::slotResourceGroupRemoved, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(group, &ResourceGroup::resourceToBeAdded, this, &ResourceGroupItemModel::slotResourceToBeAdded, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(group, &ResourceGroup::resourceAdded, this, &ResourceGroupItemModel::slotResourceAdded, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(group, &ResourceGroup::resourceToBeRemoved, this, &ResourceGroupItemModel::slotResourceToBeRemoved, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); connect(group, &ResourceGroup::resourceRemoved, this, &ResourceGroupItemModel::slotResourceRemoved, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); } else { disconnect(group, &ResourceGroup::dataChanged, this, &ResourceGroupItemModel::slotResourceGroupChanged); disconnect(group, &ResourceGroup::groupToBeAdded, this, &ResourceGroupItemModel::slotResourceGroupToBeAdded); disconnect(group, &ResourceGroup::groupAdded, this, &ResourceGroupItemModel::slotResourceGroupAdded); disconnect(group, &ResourceGroup::groupToBeRemoved, this, &ResourceGroupItemModel::slotResourceGroupToBeRemoved); disconnect(group, &ResourceGroup::groupRemoved, this, &ResourceGroupItemModel::slotResourceGroupRemoved); disconnect(group, &ResourceGroup::resourceToBeAdded, this, &ResourceGroupItemModel::slotResourceToBeAdded); disconnect(group, &ResourceGroup::resourceAdded, this, &ResourceGroupItemModel::slotResourceAdded); disconnect(group, &ResourceGroup::resourceToBeRemoved, this, &ResourceGroupItemModel::slotResourceToBeRemoved); disconnect(group, &ResourceGroup::resourceRemoved, this, &ResourceGroupItemModel::slotResourceRemoved); } for (ResourceGroup *g : group->childGroups()) { connectSignals(g, enable); } for (Resource *r : group->resources()) { connectSignals(r, enable); } } void ResourceGroupItemModel::connectSignals(Resource *resource, bool enable) { if (m_resourcesEnabled) { if (enable) { connect(resource, &Resource::dataChanged, this, &ResourceGroupItemModel::slotResourceChanged, Qt::ConnectionType(Qt::AutoConnection | Qt::UniqueConnection)); } else { disconnect(resource, &Resource::dataChanged, this, &ResourceGroupItemModel::slotResourceChanged); } } } Qt::ItemFlags ResourceGroupItemModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = ItemModelBase::flags(index); if (!m_readWrite) { //debugPlan<<"read only"<isShared()) { flags &= ~Qt::ItemIsEditable; return flags; } flags |= Qt::ItemIsDropEnabled; switch (index.column()) { case ResourceGroupModel::Name: flags |= Qt::ItemIsEditable; break; case ResourceGroupModel::Type: flags |= Qt::ItemIsEditable; break; + case ResourceGroupModel::Coordinator: flags |= Qt::ItemIsEditable; break; default: flags &= ~Qt::ItemIsEditable; } } else if (m_resourcesEnabled) { Resource *r = resource(index); if (r) { flags |= Qt::ItemIsDragEnabled; flags &= ~Qt::ItemIsEditable; } } return flags; } QModelIndex ResourceGroupItemModel::parent(const QModelIndex &index) const { if (!index.isValid() || m_project == 0) { return QModelIndex(); } //debugPlan<(index.internalPointer()); if (!p) { return QModelIndex(); } ResourceGroup *gp = p ? p->parentGroup() : nullptr; int row = gp ? gp->indexOf(p) : m_project->indexOf(p); return createIndex(row, 0, gp); } QModelIndex ResourceGroupItemModel::index(int row, int column, const QModelIndex &parent) const { if (m_project == 0 || column < 0 || column >= columnCount() || row < 0) { return QModelIndex(); } if (!parent.isValid()) { if (row < m_project->numResourceGroups()) { return createIndex(row, column); } return QModelIndex(); } ResourceGroup *g = group(parent); if (g) { if (row < g->numChildGroups()) { return createIndex(row, column, g); } else if (m_resourcesEnabled) { return createIndex(row, column, g); } } return QModelIndex(); } QModelIndex ResourceGroupItemModel::index(const ResourceGroup *group, int column) const { if (m_project == nullptr || group == nullptr) { return QModelIndex(); } int row = -1; if (group->parentGroup()) { row = group->parentGroup()->indexOf(const_cast(group)); } else { row = m_project->indexOf(const_cast(group)); } if (row < 0) { return QModelIndex(); } return createIndex(row, column, group->parentGroup()); } int ResourceGroupItemModel::columnCount(const QModelIndex &/*parent*/) const { return m_groupModel.propertyCount(); } int ResourceGroupItemModel::rowCount(const QModelIndex &parent) const { if (m_project == nullptr) { return 0; } if (!parent.isValid()) { return m_project->numResourceGroups(); } int rows = 0; ResourceGroup *g = group(parent); if (g) { rows = g->numChildGroups(); if (m_resourcesEnabled) { rows += g->numResources(); } } // else a resource so no children return rows; } QVariant ResourceGroupItemModel::name(const ResourceGroup *res, int role) const { //debugPlan<name()<<","<name(); case Qt::StatusTipRole: case Qt::WhatsThisRole: return QVariant(); } return QVariant(); } bool ResourceGroupItemModel::setName(ResourceGroup *res, const QVariant &value, int role) { switch (role) { case Qt::EditRole: if (value.toString() == res->name()) { return false; } emit executeCommand(new ModifyResourceGroupNameCmd(res, value.toString(), kundo2_i18n("Modify resourcegroup name"))); return true; } return false; } QVariant ResourceGroupItemModel::type(const ResourceGroup *res, int role) const { switch (role) { case Qt::DisplayRole: case Qt::ToolTipRole: case Qt::EditRole: return res->type(); case Qt::TextAlignmentRole: return Qt::AlignCenter; case Qt::StatusTipRole: case Qt::WhatsThisRole: return QVariant(); } return QVariant(); } bool ResourceGroupItemModel::setType(ResourceGroup *res, const QVariant &value, int role) { switch (role) { case Qt::EditRole: { emit executeCommand(new ModifyResourceGroupTypeCmd(res, value.toString(), kundo2_i18n("Modify resourcegroup type"))); return true; } } return false; } bool ResourceGroupItemModel::setUnits(ResourceGroup *res, const QVariant &value, int role) { return false; } bool ResourceGroupItemModel::setCoordinator(ResourceGroup *res, const QVariant &value, int role) { + switch (role) { + case Qt::EditRole: { + emit executeCommand(new ResourceGroupModifyCoordinatorCmd(res, value.toString(), kundo2_i18n("Modify resourcegroup coordinator"))); + return true; + } + } return false; } QVariant ResourceGroupItemModel::data(const QModelIndex &index, int role) const { if (role == Qt::TextAlignmentRole) { // use same alignment as in header (headers always horizontal) return headerData(index.column(), Qt::Horizontal, role); } ResourceGroup *g = group(index); if (g) { return m_groupModel.data(g, index.column(), role); } if (m_resourcesEnabled) { Resource *r = resource(index); if (r) { return m_resourceModel.data(r, index.column(), role); } } return QVariant(); } bool ResourceGroupItemModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (ItemModelBase::setData(index, value, role)) { return true; } if (!index.isValid()) { return false; } if (role != Qt::EditRole && role != Qt::CheckStateRole) { return false; } if ((flags(index) & (Qt::ItemIsEditable | Qt::ItemIsUserCheckable)) == 0) { return false; } ResourceGroup *g = group(index); if (g) { bool result = false; switch (index.column()) { case ResourceGroupModel::Name: result = setName(g, value, role); break; case ResourceGroupModel::Scope: return false; // Not editable case ResourceGroupModel::Type: result = setType(g, value, role); break; case ResourceGroupModel::Units: result = setUnits(g, value, role); break; case ResourceGroupModel::Coordinator: result = setCoordinator(g, value, role); break; default: qWarning("data: invalid display value column %d", index.column()); return false; } if (result) { emit dataChanged(index, index); } } return false; } QVariant ResourceGroupItemModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole || role == Qt::TextAlignmentRole) { return m_groupModel.headerData(section, role); } } if (role == Qt::ToolTipRole) { return m_groupModel.headerData(section, role); } return ItemModelBase::headerData(section, orientation, role); } QAbstractItemDelegate *ResourceGroupItemModel::createDelegate(int col, QWidget *parent) const { Q_UNUSED(col) Q_UNUSED(parent) return nullptr; } ResourceGroup *ResourceGroupItemModel::group(const QModelIndex &index) const { if (!index.isValid()) { return nullptr; } ResourceGroup *parent = static_cast(index.internalPointer()); if (parent) { return parent->childGroupAt(index.row()); } return m_project->resourceGroupAt(index.row()); } Resource *ResourceGroupItemModel::resource(const QModelIndex &index) const { if (!m_resourcesEnabled || !index.isValid()) { return nullptr; } ResourceGroup *parent = static_cast(index.internalPointer()); if (!parent) { return nullptr; } int row = index.row() - parent->numChildGroups(); return parent->resourceAt(row); } void ResourceGroupItemModel::slotResourceChanged(Resource *res) { for (ResourceGroup *g : res->parentGroups()) { int row = g->indexOf(res) + g->numChildGroups(); emit dataChanged(createIndex(row, 0, g), createIndex(row, columnCount() - 1, g)); } } void ResourceGroupItemModel::slotResourceGroupChanged(ResourceGroup *group) { ResourceGroup *parent = group->parentGroup(); QModelIndex idx = index(group); emit dataChanged(idx, idx.sibling(idx.row(), columnCount() - 1)); } Qt::DropActions ResourceGroupItemModel::supportedDropActions() const { return Qt::MoveAction | Qt::CopyAction; } bool ResourceGroupItemModel::dropAllowed(const QModelIndex &index, int dropIndicatorPosition, const QMimeData *data) { if (data->hasFormat("application/x-vnd.kde.plan.resourcegroupitemmodel.internal")) { QByteArray encodedData = data->data("application/x-vnd.kde.plan.resourcegroupitemmodel.internal"); QDataStream stream(&encodedData, QIODevice::ReadOnly); int i = 0; foreach (Resource *r, resourceList(stream)) { if (r->isShared()) { return false; } } } //debugPlan<error() || ! m_dropDataMap.contains(job)) { debugPlan<<(job->error() ? "Job error":"Error: no such job"); } else if (QMimeDatabase().mimeTypeForData(m_dropDataMap[ job ].data).inherits(QStringLiteral("text/x-vcard"))) { ResourceGroup *g = 0; if (m_dropDataMap[ job ].parent.isValid()) { g = group(m_dropDataMap[ job ].parent); } else { g = group(index(m_dropDataMap[ job ].row, m_dropDataMap[ job ].column, m_dropDataMap[ job ].parent)); } if (g == nullptr) { debugPlan<<"No group"<findResource(uid)) { r->setId(uid); } r->setName(lst[a].formattedName()); r->setEmail(lst[a].preferredEmail()); m->addCommand(new AddResourceCmd(group, r)); } if (m->isEmpty()) { delete m; return false; } emit executeCommand(m); return true; #else Q_UNUSED(group); Q_UNUSED(data); return false; #endif } bool ResourceGroupItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { debugPlan< 0) { return false; } ResourceGroup *g = nullptr; if (parent.isValid()) { g = group(parent); } else { g = group(index(row, column, parent)); } if (g == nullptr) { debugPlan<<"No group"<formats()<name(); if (data->hasFormat("application/x-vnd.kde.plan.resourcegroupitemmodel.internal")) { debugPlan<data("application/x-vnd.kde.plan.resourcegroupitemmodel.internal"); QDataStream stream(&encodedData, QIODevice::ReadOnly); int i = 0; foreach (Resource *r, resourceList(stream)) { if (r->parentGroups().value(0) == g) { continue; } if (m == 0) m = new MacroCommand(KUndo2MagicString()); m->addCommand(new MoveResourceCmd(g, r)); ++i; } if (m) { KUndo2MagicString msg = kundo2_i18np("Move resource", "Move %1 resources", i); MacroCommand *c = new MacroCommand(msg); c->addCommand(m); emit executeCommand(c); } return true; } if (action == Qt::CopyAction) { MacroCommand *m = 0; QByteArray encodedData = data->data("application/x-vnd.kde.plan.resourcegroupitemmodel.internal"); QDataStream stream(&encodedData, QIODevice::ReadOnly); int i = 0; foreach (Resource *r, resourceList(stream)) { Resource *nr = new Resource(r); if (m == 0) m = new MacroCommand(KUndo2MagicString()); m->addCommand(new AddResourceCmd(g, nr)); ++i; } if (m) { KUndo2MagicString msg = kundo2_i18np("Copy resource", "Copy %1 resources", i); MacroCommand *c = new MacroCommand(msg); c->addCommand(m); emit executeCommand(c); } return true; } return true; } if (data->hasFormat("text/x-vcard") || data->hasFormat("text/directory")) { if (action != Qt::CopyAction) { return false; } QString f = data->hasFormat("text/x-vcard") ? "text/x-vcard" : "text/directory"; return createResources(g, data->data(f)); } if (data->hasFormat("text/uri-list")) { const QList urls = data->urls(); if (urls.isEmpty()) { return false; } bool result = false; foreach (const QUrl &url, urls) { if (url.scheme() != "akonadi") { debugPlan<setSide(KIO::StatJob::SourceSide); const bool isUrlReadable = statJob->exec(); if (! isUrlReadable) { debugPlan<start(); result = true; } return result; } return false; } QList ResourceGroupItemModel::resourceList(QDataStream &stream) { QList lst; while (!stream.atEnd()) { QString id; stream >> id; Resource *r = m_project->findResource(id); if (r) { lst << r; } } debugPlan< rows; foreach (const QModelIndex &index, indexes) { if (index.isValid() && !rows.contains(index.row())) { //debugPlan<id(); } else if (group(index)) { rows.clear(); break; } } } if (!rows.isEmpty()) { m->setData("application/x-vnd.kde.plan.resourcegroupitemmodel.internal", encodedData); } return m; } QModelIndex ResourceGroupItemModel::insertGroup(ResourceGroup *group, ResourceGroup *parent) { //debugPlan; if (parent) { emit executeCommand(new AddResourceGroupCmd(m_project, parent, group, kundo2_i18n("Add resource group"))); QModelIndex idx = index(group); return idx; } emit executeCommand(new AddResourceGroupCmd(m_project, group, kundo2_i18n("Add resource group"))); return index(group); } QModelIndex ResourceGroupItemModel::insertResource(ResourceGroup *parent, Resource *r, Resource * /*after*/) { //debugPlan; emit executeCommand(new AddParentGroupCmd(r, parent, kundo2_i18n("Add resource"))); int row = parent->indexOf(r) + parent->numChildGroups(); if (row != -1) { return createIndex(row, 0, parent); } return QModelIndex(); } int ResourceGroupItemModel::sortRole(int column) const { return Qt::DisplayRole; } //---------- ParentGroupItemModel::ParentGroupItemModel(QObject *parent) : QSortFilterProxyModel(parent) , m_model(new ResourceGroupItemModel(this)) , m_resource(nullptr) , m_groupIsCheckable(false) { setSourceModel(m_model); m_model->setReadWrite(true); m_model->setResourcesEnabled(true); } ParentGroupItemModel::~ParentGroupItemModel() { } int ParentGroupItemModel::columnCount(const QModelIndex &idx) const { Q_UNUSED(idx); return 1; } Qt::ItemFlags ParentGroupItemModel::flags(const QModelIndex &idx) const { QModelIndex index = mapToSource(idx); Qt::ItemFlags f = m_model->flags(index); if (m_resource && m_groupIsCheckable && m_model->group(index)) { f |= Qt::ItemIsUserCheckable; } return f; } QVariant ParentGroupItemModel::data(const QModelIndex &idx, int role) const { if (m_resource && m_groupIsCheckable && role == Qt::CheckStateRole) { ResourceGroup *group = m_model->group(mapToSource(idx)); if (group) { return m_resource->groupIndexOf(group) >= 0 ? Qt::Checked : Qt::Unchecked; } } return QSortFilterProxyModel::data(idx, role); } bool ParentGroupItemModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role == Qt::CheckStateRole && m_resource) { ResourceGroup *g = m_model->group(mapToSource(index)); if (g) { if (value.toInt() == Qt::Checked) { emit executeCommand(new AddParentGroupCmd(m_resource, g, kundo2_i18n("Add parent group"))); } else { emit executeCommand(new RemoveParentGroupCmd(m_resource, g, kundo2_i18n("Remove parent group"))); } return true; } return false; } return QSortFilterProxyModel::setData(index, value, role); } void ParentGroupItemModel::setProject(Project *project) { m_model->setProject(project); } void ParentGroupItemModel::setResource(Resource *resource) { beginResetModel(); if (m_resource) { disconnect(resource, &Resource::resourceGroupAdded, this, &ParentGroupItemModel::slotResourceAdded); disconnect(resource, &Resource::resourceGroupRemoved, this, &ParentGroupItemModel::slotResourceRemoved); } m_resource = resource; if (m_resource) { connect(resource, &Resource::resourceGroupAdded, this, &ParentGroupItemModel::slotResourceAdded); connect(resource, &Resource::resourceGroupRemoved, this, &ParentGroupItemModel::slotResourceRemoved); for (ResourceGroup *g : m_resource->parentGroups()) { m_model->setData(m_model->index(g), Qt::Checked, Qt::CheckStateRole); } } endResetModel(); } void ParentGroupItemModel::setGroupIsCheckable(bool checkable) { m_groupIsCheckable = checkable; } bool ParentGroupItemModel::groupIsCheckable() const { return m_groupIsCheckable; } void ParentGroupItemModel::slotResourceAdded(KPlato::ResourceGroup *group) { QModelIndex idx = mapFromSource(m_model->index(group)); emit dataChanged(idx, idx); } void ParentGroupItemModel::slotResourceRemoved() { beginResetModel(); endResetModel(); } void ParentGroupItemModel::setResourcesEnabled(bool enable) { m_model->setResourcesEnabled(enable); } bool ParentGroupItemModel::resourcesEnabled() const { return m_model->resourcesEnabled(); } diff --git a/src/libs/models/ResourceGroupModel.cpp b/src/libs/models/ResourceGroupModel.cpp index 92f1bbaf..08c5a880 100644 --- a/src/libs/models/ResourceGroupModel.cpp +++ b/src/libs/models/ResourceGroupModel.cpp @@ -1,227 +1,229 @@ /* This file is part of the KDE project * Copyright (C) 2019 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 "ResourceGroupModel.h" #include "ResourceGroup.h" #include "kptlocale.h" #include "kptcommonstrings.h" #include #include "kptcommand.h" #include "kptcalendar.h" #include "kptduration.h" #include "kptnode.h" #include "kptproject.h" #include "kpttask.h" #include "kptdatetime.h" #include "kptdebug.h" #include #include #include #include #include #include #include #ifdef PLAN_KCONTACTS_FOUND #include #include #endif using namespace KPlato; //-------------------------------------- ResourceGroupModel::ResourceGroupModel(QObject *parent) : QObject(parent) , m_project(nullptr) { } ResourceGroupModel::~ResourceGroupModel() { } const QMetaEnum ResourceGroupModel::columnMap() const { return metaObject()->enumerator(metaObject()->indexOfEnumerator("Properties")); } void ResourceGroupModel::setProject(Project *project) { m_project = project; } int ResourceGroupModel::propertyCount() const { return columnMap().keyCount(); } QVariant ResourceGroupModel::name(const ResourceGroup *group, int role) const { //debugPlan<name()<<","<name(); case Qt::ToolTipRole: if (!group->isShared()) { return group->name(); } return xi18nc("@info:tooltip", "%1 is a Shared resource group and can thus be shared with other projects", group->name()); break; case Qt::StatusTipRole: case Qt::WhatsThisRole: return QVariant(); } return QVariant(); } QVariant ResourceGroupModel::scope(const ResourceGroup *group, int role) const { switch (role) { case Qt::DisplayRole: return group->isShared() ? i18n("Shared") : i18n("Local"); case Qt::ToolTipRole: if (!group->isShared()) { return xi18nc("@info:tooltip", "%1 is a Local resource group and can only be used in this project", group->name()); } return xi18nc("@info:tooltip", "%1 is a Shared resource group and can thus be shared with other projects", group->name()); case Qt::EditRole: return group->isShared() ? "Shared" : "Local"; case Role::EnumList: return QStringList() << i18n("Local") << i18n("Shared"); case Role::EnumListValue: return group->isShared() ? 1 : 0; case Qt::TextAlignmentRole: return Qt::AlignCenter; case Qt::StatusTipRole: case Qt::WhatsThisRole: return QVariant(); } return QVariant(); } QVariant ResourceGroupModel::type(const ResourceGroup *group, int role) const { switch (role) { case Qt::DisplayRole: case Qt::ToolTipRole: case Qt::EditRole: return group->type(); case Qt::TextAlignmentRole: return Qt::AlignCenter; case Qt::StatusTipRole: case Qt::WhatsThisRole: return QVariant(); } return QVariant(); } QVariant ResourceGroupModel::units(const ResourceGroup *group, int role) const { switch (role) { case Qt::DisplayRole: case Qt::EditRole: return group->units(); case Qt::TextAlignmentRole: return Qt::AlignCenter; case Qt::ToolTipRole: case Qt::StatusTipRole: case Qt::WhatsThisRole: return QVariant(); } return QVariant(); } QVariant ResourceGroupModel::coordinator(const ResourceGroup *group, int role) const { switch (role) { case Qt::DisplayRole: + return group->coordinator(); case Qt::EditRole: case Qt::ToolTipRole: + return QVariant(); case Qt::TextAlignmentRole: return Qt::AlignCenter; case Qt::StatusTipRole: case Qt::WhatsThisRole: return QVariant(); } return QVariant(); } QVariant ResourceGroupModel::data(const ResourceGroup *group, int property, int role) const { if (role == Role::ObjectType) { return OT_ResourceGroup; } QVariant result; if (group == 0) { return result; } switch (property) { case Name: result = name(group, role); break; case Scope: result = scope(group, role); break; case Type: result = type(group, role); break; case Units: result = units(group, role); break; case Coordinator: result = coordinator(group, role); break; default: if (role == Qt::DisplayRole) { result = QString(); } break; } return result; } QVariant ResourceGroupModel::headerData(int section, int role) { if (role == Qt::DisplayRole) { switch (section) { case Name: return i18n("Name"); case Scope: return i18n("Origin"); case Type: return i18n("Type"); case Units: return i18n("Units"); case Coordinator: return i18n("Coordinator"); default: return QVariant(); } } else if (role == Qt::TextAlignmentRole) { switch (section) { case Units: return (int)(Qt::AlignRight|Qt::AlignVCenter); default: return QVariant(); } } else if (role == Qt::ToolTipRole) { switch (section) { - case Name: return ToolTip::resourceName(); - case Scope: return ToolTip::resourceScope(); - case Type: return ToolTip::resourceType(); - case Units: return ToolTip::resourceUnits(); - case Coordinator: return i18n("TODO"); + case Name: return ToolTip::resourceGroupName(); + case Scope: return ToolTip::resourceGroupScope(); + case Type: return ToolTip::resourceGroupType(); + case Units: return ToolTip::resourceGroupUnits(); + case Coordinator: return ToolTip::resourceGroupCoordinator(); default: return QVariant(); } } return QVariant(); } diff --git a/src/libs/models/kptcommonstrings.cpp b/src/libs/models/kptcommonstrings.cpp index fe08a0cb..fa992b5f 100644 --- a/src/libs/models/kptcommonstrings.cpp +++ b/src/libs/models/kptcommonstrings.cpp @@ -1,198 +1,204 @@ /* This file is part of the KDE project Copyright (C) 2009, 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 "kptcommonstrings.h" #include #include namespace KPlato { QString ToolTip::nodeName() { return xi18nc("@info:tooltip", "The name of the task"); } QString ToolTip::nodeType() { return xi18nc("@info:tooltip", "Task type"); } QString ToolTip::nodeResponsible() { return xi18nc("@info:tooltip", "The person responsible for this task"); } QString ToolTip::allocation() { return xi18nc("@info:tooltip", "List of resource allocations"); } QString ToolTip::nodeConstraint() { return xi18nc("@info:tooltip", "The timing constraint type"); } QString ToolTip::nodeConstraintStart() { return xi18nc("@info:tooltip", "Constraint start time"); } QString ToolTip::nodeConstraintEnd() { return xi18nc("@info:tooltip", "Constraint end time"); } QString ToolTip::nodeDescription() { return xi18nc("@info:tooltip", "Task notes"); } QString ToolTip::nodeWBS() { return xi18nc("@info:tooltip", "Work Breakdown Structure Code"); } QString ToolTip::nodeLevel() { return xi18nc("@info:tooltip", "Node level"); } QString ToolTip::nodeRisk() { return xi18nc("@info:tooltip", "Risk controls the PERT distribution used when calculating the actual estimate for this task"); } QString ToolTip::nodePriority() { return xi18nc("@info:tooltip", "Scheduling priority.Atm. only the TJ Scheduler supports priority."); } QString ToolTip::nodeRunningAccount() { return xi18nc("@info:tooltip", "Account for running costs"); } QString ToolTip::nodeStartupAccount() { return xi18nc("@info:tooltip", "Account for cost incurred at startup of the task"); } QString ToolTip::nodeStartupCost() { return xi18nc("@info:tooltip", "The cost incurred at startup of the task"); } QString ToolTip::nodeShutdownAccount() { return xi18nc("@info:tooltip", "Account for cost incurred at shutdown of the task"); } QString ToolTip::nodeShutdownCost() { return xi18nc("@info:tooltip", "The cost incurred at shutdown of the task"); } QString ToolTip::nodeStartTime() { return xi18nc("@info:tooltip", "Planned start time"); } QString ToolTip::nodeEndTime() { return xi18nc("@info:tooltip", "Planned finish time"); } QString ToolTip::nodeEarlyStart() { return xi18nc("@info:tooltip", "Earliest start time allowed by dependencies"); } QString ToolTip::nodeEarlyFinish() { return xi18nc("@info:tooltip", "Earliest finish time allowed by dependencies"); } QString ToolTip::nodeLateStart() { return xi18nc("@info:tooltip", "Latest start time allowed by dependencies"); } QString ToolTip::nodeLateFinish() { return xi18nc("@info:tooltip", "Latest finish time allowed by dependencies"); } QString ToolTip::nodeDuration() { return xi18nc("@info:tooltip", "The planned duration"); } QString ToolTip::nodeVarianceDuration() { return xi18nc("@info:tooltip", "The variance of the duration"); } QString ToolTip::nodeOptimisticDuration() { return xi18nc("@info:tooltip", "The optimistic duration"); } QString ToolTip::nodePessimisticDuration() { return xi18nc("@info:tooltip", "The pessimistic duration"); } QString ToolTip::nodePositiveFloat() { return xi18nc("@info:tooltip", "The duration by which a tasks start can be delayed without affecting the project completion time"); } QString ToolTip::nodeNegativeFloat() { return xi18nc("@info:tooltip", "The duration by which the duration of a task or path has to be reduced in order to fulfill a timing constraint"); } QString WhatsThis::nodeNegativeFloat() { return xi18nc("@info:whatsthis", "Negative float is the duration by which the duration of a task or path has to be reduced in order to fulfill a timing constraint."); } QString ToolTip::nodeFreeFloat() { return xi18nc("@info:tooltip", "The duration by which a task can be delayed or extended without affecting the start of any succeeding task"); } QString WhatsThis::nodeFreeFloat() { return xi18nc("@info:whatsthis", "Free float is the duration by which a task can be delayed or extended without affecting the start of any succeeding task."); } QString ToolTip::nodeStartFloat() { return xi18nc("@info:tooltip", "The duration from Early Start to Late Start"); } QString WhatsThis::nodeStartFloat() { return xi18nc("@info:whatsthis", "Start float is the duration from Early Start to Late Start."); } QString ToolTip::nodeFinishFloat() { return xi18nc("@info:tooltip", "The duration from Early Finish to Late Finish"); } QString WhatsThis::nodeFinishFloat() { return xi18nc("@info:whatsthis", "Finish float is the duration from Early Finish to Late Finish."); } QString ToolTip::nodeAssignment() { return xi18nc("@info:tooltip", "The resources assigned to the task"); } QString ToolTip::nodeStatus() { return xi18nc("@info:tooltip", "Task status"); } QString ToolTip::nodeCompletion() { return xi18nc("@info:tooltip", "Task completion"); } QString ToolTip::nodePlannedEffortTo() { return xi18nc("@info:tooltip", "Planned effort"); } QString ToolTip::nodeActualEffortTo() { return xi18nc("@info:tooltip", "Actual effort"); } QString ToolTip::nodeRemainingEffort() { return xi18nc("@info:tooltip", "Remaining effort"); } QString ToolTip::nodePlannedCostTo() { return xi18nc("@info:tooltip", "Planned cost"); } QString ToolTip::nodeActualCostTo() { return xi18nc("@info:tooltip", "Actual cost"); } QString ToolTip::completionStartedTime() { return xi18nc("@info:tooltip", "Time when task was actually started"); } QString ToolTip::completionStarted() { return xi18nc("@info:tooltip", "Shows if the task is started"); } QString ToolTip::completionFinishedTime() { return xi18nc("@info:tooltip", "Time when task was actually finished"); } QString ToolTip::completionFinished() { return xi18nc("@info:tooltip", "Shows if the task is finished"); } QString ToolTip::completionStatusNote() { return xi18nc("@info:tooltip", "Status Note"); } QString ToolTip::estimateExpected() { return xi18nc("@info:tooltip", "Calculated expected estimate"); } QString ToolTip::estimateVariance() { return xi18nc("@info:tooltip", "Calculated estimate variance"); } QString ToolTip::estimateOptimistic() { return xi18nc("@info:tooltip", "Optimistic estimate"); } QString ToolTip::estimatePessimistic() { return xi18nc("@info:tooltip", "Pessimistic estimate"); } QString ToolTip::estimateType() { return xi18nc("@info:tooltip", "Type of estimate"); } QString ToolTip::estimateCalendar() { return xi18nc("@info:tooltip", "The calendar used when estimate type is Duration"); } QString ToolTip::estimate() { return xi18nc("@info:tooltip", "The most likely estimate"); } QString ToolTip::optimisticRatio() { return xi18nc("@info:tooltip", "Optimistic estimate"); } QString ToolTip::pessimisticRatio() { return xi18nc("@info:tooltip", "Pessimistic estimate"); } QString ToolTip::riskType() { return xi18nc("@info:tooltip", "Type of risk"); } QString ToolTip::nodeSchedulingStatus() { return xi18nc("@info:tooltip", "Shows the tasks scheduling status"); } QString ToolTip::nodeNotScheduled() { return xi18nc("@info:tooltip", "The task has not been scheduled"); } QString ToolTip::nodeAssignmentMissing() { return i18n("An effort has been estimated, but no resource has been assigned"); } QString ToolTip::nodeResourceOverbooked() { return xi18nc("@info:tooltip", "A resource assigned to this task is overbooked"); } QString ToolTip::nodeResourceUnavailable() { return xi18nc("@info:tooltip", "A resource assigned to this task is not available"); } QString ToolTip::nodeConstraintsError() { return xi18nc("@info:tooltip", "A timing constraint could not be met"); } QString ToolTip::nodeEffortNotMet() { return xi18nc("@info:tooltip", "The assigned resource could not meet the estimated effort"); } QString ToolTip::nodeSchedulingError() { return xi18nc("@info:tooltip", "A scheduling error occurred"); } QString ToolTip::nodeBCWS() { return xi18nc("@info:tooltip", "Budgeted Cost of Work Scheduled"); } QString ToolTip::nodeBCWP() { return xi18nc("@info:tooltip", "Budgeted Cost of Work Performed"); } QString ToolTip::nodeACWP() { return xi18nc("@info:tooltip", "Actual Cost of Work Performed"); } QString ToolTip::nodePerformanceIndex() { return i18n("Schedule performance index (BCWP/BCWS)"); } - QString ToolTip::resourceName() { return xi18nc("@info:tooltip", "The name of the resource or resource group"); } - QString ToolTip::resourceScope() { return xi18nc("@info:tooltip", "The origin of the resource or resource group"); } - QString ToolTip::resourceType() { return xi18nc("@info:tooltip", "The type of the resource or resource group"); } + QString ToolTip::resourceName() { return xi18nc("@info:tooltip", "The name of the resource"); } + QString ToolTip::resourceScope() { return xi18nc("@info:tooltip", "The origin of the resource"); } + QString ToolTip::resourceType() { return xi18nc("@info:tooltip", "The type of the resource"); } QString ToolTip::resourceInitials() { return xi18nc("@info:tooltip", "The initials of the resource"); } QString ToolTip::resourceEMail() { return xi18nc("@info:tooltip", "The e-mail address of the resource"); } QString ToolTip::resourceCalendar() { return xi18nc("@info:tooltip", "The calendar defines when the resource is working"); } QString ToolTip::resourceUnits() { return xi18nc("@info:tooltip", "The maximum load that can be assigned"); } QString ToolTip::resourceAvailableFrom() { return xi18nc("@info:tooltip", "Defines when the resource is available to the project"); } QString ToolTip::resourceAvailableUntil() { return xi18nc("@info:tooltip", "Defines when the resource is available to the project"); } QString ToolTip::resourceNormalRate() { return xi18nc("@info:tooltip", "The cost pr hour, normal hours"); } QString ToolTip::resourceOvertimeRate() { return xi18nc("@info:tooltip", "The cost pr hour, overtime hours"); } QString ToolTip::resourceFixedCost() { return xi18nc("@info:tooltip", "The fixed cost"); } QString ToolTip::resourceAccount() { return xi18nc("@info:tooltip", "The account where the resource cost is accumulated"); } + QString ToolTip::resourceGroupName() { return xi18nc("@info:tooltip", "The name of the resource group"); } + QString ToolTip::resourceGroupScope() { return xi18nc("@info:tooltip", "The origin of the resource group"); } + QString ToolTip::resourceGroupType() { return xi18nc("@info:tooltip", "The type of the resource group"); } + QString ToolTip::resourceGroupUnits() { return xi18nc("@info:tooltip", "The aggregated units for the resources in the resource group"); } + QString ToolTip::resourceGroupCoordinator() { return xi18nc("@info:tooltip", "The coordinator of the resource group"); } + QString ToolTip::accountName() { return xi18nc("@info:tooltip", "The name of the account"); } QString ToolTip::accountDescription() { return xi18nc("@info:tooltip", "The description of the account"); } QString ToolTip::scheduleName() { return xi18nc("@info:tooltip", "The name and scheduling mode of the schedule"); } QString ToolTip::scheduleState() { return xi18nc("@info:tooltip", "The schedules state"); } QString ToolTip::scheduleOverbooking() { return xi18nc("@info:tooltip", "Controls resource overbooking when scheduling"); } QString WhatsThis::scheduleOverbooking() { return xi18nc("@info:whatsthis", "Controls resource overbooking when scheduling." "If overbooking is allowed, a resource may be booked (on working days) to work more than it is available. This can happen if the resource is allocated to multiple tasks or are booked on other projects." "If overbooking is to be avoided, resources will not be booked more than they are available. On resource conflict, tasks will be delayed until the resource is available." ); } QString ToolTip::scheduleDistribution() { return xi18nc("@info:tooltip", "The distribution to be used during scheduling"); } QString WhatsThis::scheduleDistribution() { return xi18nc("@info:whatsthis", "The distribution to be used during scheduling" "If distribution is 'None', the tasks estimate is used as is during scheduling." "If distribution is 'PERT', the estimate used is calculated based on the entered optimistic- (O), pessimistic-(P) and most likely (M) estimate. The formula used for this is (O + 4 * M + P) / 6." ); } QString ToolTip::scheduleCalculate() { return xi18nc("@info:tooltip", "Defines the schedules to be calculated"); } QString ToolTip::scheduleStart() { return xi18nc("@info:tooltip", "The scheduled start time"); } QString ToolTip::scheduleFinish() { return xi18nc("@info:tooltip", "The scheduled finish time"); } QString ToolTip::schedulingDirection() { return xi18nc("@info:tooltip", "The scheduling direction"); } QString WhatsThis::schedulingDirection() { return xi18nc("@info:whatsthis", "The scheduling direction." "If direction is Forward, the project is scheduled starting at the projects earliest start time specified in the main project dialog." "If direction is Backward, the project is scheduled starting at the projects latest finish time specified in the main project dialog." ); } QString ToolTip::scheduleScheduler() { return xi18nc("@info:tooltip", "The scheduler used for calculating the project schedule"); } QString WhatsThis::scheduleScheduler() { return xi18nc("@info:whatsthis", "The scheduler used for calculating the project schedule." "The default built-in scheduler is the Network Scheduler." "Other schedulers presently available is RCPS if libRCPS is installed on your system. " "RCPS is a genetics based resource constrained project scheduler." ); } QString ToolTip::scheduleGranularity() { return xi18nc("@info:tooltip", "The granularity used when calculating the project schedule"); } QString ToolTip::scheduleMode() { return xi18nc("@info:tooltip", "The scheduling mode:" "" "Manual: Calculation must be initiated manually." "Auto: Calculation is initiated automatically." "" ""); } QString ToolTip::documentUrl() { return xi18nc("@info:tooltip", "The url of the document"); } QString ToolTip::documentType() { return xi18nc("@info:tooltip", "The type of the document"); } QString ToolTip::documentStatus() { return xi18nc("@info:tooltip", "The status of the document"); } QString ToolTip::documentSendAs() { return xi18nc("@info:tooltip", "Defines how this document is sent"); } QString ToolTip::calendarName() { return xi18nc("@info:tooltip", "The name of the calendar"); } QString ToolTip::calendarTimeZone() { return xi18nc("@info:tooltip", "The timezone of the calendar"); } QString ToolTip::relationParent() { return xi18nc("@info:tooltip", "The name of the required task"); } QString ToolTip::relationChild() { return xi18nc("@info:tooltip", "The name of the dependent task"); } QString ToolTip::relationType() { return xi18nc("@info:tooltip", "The type of relation"); } QString ToolTip::relationLag() { return xi18nc("@info:tooltip", "The relations time lag"); } // Work around string freeze KUndo2MagicString UndoText::removeDocument() { return kundo2_i18n("Remove document"); } } //namespace KPlato diff --git a/src/libs/models/kptcommonstrings.h b/src/libs/models/kptcommonstrings.h index f5eb6c7d..c217876c 100644 --- a/src/libs/models/kptcommonstrings.h +++ b/src/libs/models/kptcommonstrings.h @@ -1,173 +1,179 @@ /* This file is part of the KDE project Copyright (C) 2009, 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 KPTCOMMONSTRINGS_H #define KPTCOMMONSTRINGS_H #include "planmodels_export.h" class KUndo2MagicString; class QString; namespace KPlato { struct PLANMODELS_EXPORT ToolTip { static QString nodeName(); static QString nodeType(); static QString nodeResponsible(); static QString allocation(); static QString nodeConstraint(); static QString nodeConstraintStart(); static QString nodeConstraintEnd(); static QString nodeDescription(); static QString nodeWBS(); static QString nodeLevel(); static QString nodeRisk(); static QString nodePriority(); static QString nodeRunningAccount(); static QString nodeStartupAccount(); static QString nodeStartupCost(); static QString nodeShutdownAccount(); static QString nodeShutdownCost(); static QString nodeStartTime(); static QString nodeEndTime(); static QString nodeEarlyStart(); static QString nodeEarlyFinish(); static QString nodeLateStart(); static QString nodeLateFinish(); static QString nodeDuration(); static QString nodeVarianceDuration(); static QString nodeOptimisticDuration(); static QString nodePessimisticDuration(); static QString nodePositiveFloat(); static QString nodeNegativeFloat(); static QString nodeFreeFloat(); static QString nodeStartFloat(); static QString nodeFinishFloat(); static QString nodeAssignment(); static QString nodeStatus(); static QString nodeCompletion(); static QString nodePlannedEffortTo(); static QString nodeActualEffortTo(); static QString nodeRemainingEffort(); static QString nodePlannedCostTo(); static QString nodeActualCostTo(); static QString completionStartedTime(); static QString completionStarted(); static QString completionFinishedTime(); static QString completionFinished(); static QString completionStatusNote(); static QString estimateExpected(); static QString estimateVariance(); static QString estimateOptimistic(); static QString estimatePessimistic(); static QString estimateType(); static QString estimateCalendar(); static QString estimate(); static QString optimisticRatio(); static QString pessimisticRatio(); static QString riskType(); static QString nodeSchedulingStatus(); static QString nodeNotScheduled(); static QString nodeAssignmentMissing(); static QString nodeResourceOverbooked(); static QString nodeResourceUnavailable(); static QString nodeConstraintsError(); static QString nodeEffortNotMet(); static QString nodeSchedulingError(); static QString nodeBCWS(); static QString nodeBCWP(); static QString nodeACWP(); static QString nodePerformanceIndex(); static QString resourceName(); static QString resourceScope(); static QString resourceType(); static QString resourceInitials(); static QString resourceEMail(); static QString resourceCalendar(); static QString resourceUnits(); static QString resourceAvailableFrom(); static QString resourceAvailableUntil(); static QString resourceNormalRate(); static QString resourceOvertimeRate(); static QString resourceFixedCost(); static QString resourceAccount(); + static QString resourceGroupName(); + static QString resourceGroupScope(); + static QString resourceGroupType(); + static QString resourceGroupUnits(); + static QString resourceGroupCoordinator(); + static QString accountName(); static QString accountDescription(); static QString scheduleName(); static QString scheduleState(); static QString scheduleOverbooking(); static QString scheduleDistribution(); static QString scheduleCalculate(); static QString scheduleStart(); static QString scheduleFinish(); static QString schedulingDirection(); static QString scheduleScheduler(); static QString scheduleGranularity(); static QString scheduleMode(); static QString documentUrl(); static QString documentType(); static QString documentStatus(); static QString documentSendAs(); static QString calendarName(); static QString calendarTimeZone(); static QString relationParent(); static QString relationChild(); static QString relationType(); static QString relationLag(); }; //namespace ToolTip struct PLANMODELS_EXPORT WhatsThis { static QString nodeNegativeFloat(); static QString nodeFreeFloat(); static QString nodeStartFloat(); static QString nodeFinishFloat(); static QString scheduleOverbooking(); static QString scheduleDistribution(); static QString schedulingDirection(); static QString scheduleScheduler(); }; //namespace WhatsThis struct PLANMODELS_EXPORT UndoText { static KUndo2MagicString removeDocument(); }; //namespace Undo } //namespace KPlato #endif