diff --git a/src/libs/kernel/ResourceGroup.cpp b/src/libs/kernel/ResourceGroup.cpp index 611b3865..a6b788ed 100644 --- a/src/libs/kernel/ResourceGroup.cpp +++ b/src/libs/kernel/ResourceGroup.cpp @@ -1,432 +1,431 @@ /* 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")); if (status.version() < "07.0") { m_shared = element.attribute("shared", "0").toInt(); } else { m_shared = element.attribute("origin", "local") != "local"; } 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("shared", m_shared ? "shared" : "local"); 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 02a05c10..e6ffc2c4 100644 --- a/src/libs/kernel/ResourceGroup.h +++ b/src/libs/kernel/ResourceGroup.h @@ -1,232 +1,230 @@ /* 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