1 /*
2  * %kadu copyright begin%
3  * Copyright 2011 Piotr Galiszewski (piotr.galiszewski@kadu.im)
4  * Copyright 2010, 2012 Bartosz Brachaczek (b.brachaczek@gmail.com)
5  * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Rafał Przemysław Malinowski (rafal.przemyslaw.malinowski@gmail.com)
6  * %kadu copyright end%
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #pragma once
23 
24 #include "status/status-change-source.h"
25 #include "status/status.h"
26 
27 #include <QtCore/QMap>
28 #include <QtCore/QPointer>
29 #include <injeqt/injeqt.h>
30 
31 class Account;
32 class StatusChanger;
33 class StatusContainerManager;
34 class StatusContainer;
35 
36 /**
37  * @addtogroup Status
38  * @{
39  */
40 
41 /**
42  * @class StatusChangerManager
43  * @author Rafał 'Vogel' Malinowski
44  * @short Class responsible for managing list of StatusChanger instnaces.
45  *
46  * Every Status in Kadu can be modified by plugins that registers instances of StatusChanger class in StatusChangerManager
47  * singleton.
48  *
49  * For example: media player plugin can register StatusChanger that adds title of currenly playing song at the beggining
50  * or at the end of user set description. Autoaway plugin can register StatusChanger that lowers availability depending
51  * on user activity (like chaning status from online to away or do not distrurb or even offline).
52  *
53  * Using StatusChanger classes instead of directly changing status allows for easy stacking of plugins that can modify
54  * status and for easy rewerting to user set status and description. Modifications of every StatusChanger are applied
55  * in order provided by theirs priorities.
56  *
57  * To get modifies status use setStatus method of StatusChangerManager instead of StatusContainer one. This will create
58  * modified status and set it on StatusContainer. Every change of modification of any registered StatusChanger will
59  * be automatically applied on registered status containers.
60  *
61  * StatusChangerManager also allows receiving originally set status (not modified) by manuallySetStatus method.
62  */
63 class KADUAPI StatusChangerManager : public QObject
64 {
65 	Q_OBJECT
66 
67 	QPointer<StatusContainerManager> m_statusContainerManager;
68 	QMap<StatusContainer *, Status> Statuses;
69 	QList<StatusChanger *> StatusChangers;
70 
71 private slots:
72 	INJEQT_SET void setStatusContainerManager(StatusContainerManager *statusContainerManager);
73 
74 	/**
75 	 * @author Rafał 'Vogel' Malinowski
76 	 * @short Slot called when any of registered StatusChanger changes way it modifies status.
77 	 * @param container change is touching this status container's status
78 	 * @param source source of given status change
79 	 *
80 	 * This slot called when any of registered StatusChanger changes way it modifies status for given
81 	 * statusContainer. If statusContainer is null, status for all registered status containers is
82 	 * modified.
83 	 *
84 	 * By default source is set to SourceStatusChanger. Thanks to that this slot can be connected to signals from StatusChanger
85 	 * instances with only one parameter.
86 	 *
87 	 * If source is set to SourceUser then status change is performed even if new status is the same as previous one.
88 	 */
89 	void statusChanged(StatusContainer *container = 0, StatusChangeSource source = SourceStatusChanger);
90 
91 public:
92 	Q_INVOKABLE explicit StatusChangerManager(QObject *parent = nullptr);
93 	virtual ~StatusChangerManager();
94 
95 	/**
96 	 * @author Rafał 'Vogel' Malinowski
97 	 * @short Registers new StatusChanger object.
98 	 * @param statusChanger new statusChanger to register.
99 	 *
100 	 * Registers new StatusChanger instance. Calling this method causes recomputation of all status contaieners' statuses.
101 	 */
102 	void registerStatusChanger(StatusChanger *statusChanger);
103 
104 	/**
105 	 * @author Rafał 'Vogel' Malinowski
106 	 * @short Unregisters StatusChanger object.
107 	 * @param statusChanger statusChanger to unregister.
108 	 *
109 	 * Unregisters StatusChanger instance. Calling this method causes recomputation of all status contaieners' statuses.
110 	 */
111 	void unregisterStatusChanger(StatusChanger *statusChanger);
112 
113 	/**
114 	 * @author Rafał 'Vogel' Malinowski
115 	 * @short Sets status on given status container with modifications.
116 	 * @param statusContainer StatusContainer to set status on.
117 	 * @param status status to be modified and then set on statusContainer
118 	 *
119 	 * This methods stores given status as manually set status (to receive by manuallySetStatus) and then modifies
120 	 * it using all registered StatusChangers. After all changes are done, new status is set on statusContainer
121 	 * using StatusContainer::setStatus method.
122 	 */
123 	void setStatusManually(StatusContainer *statusContainer, Status status);
124 
125 	/**
126 	 * @author Rafał 'Vogel' Malinowski
127 	 * @short Returns manually (unchanged) status from given StatusContainer.
128 	 * @param statusContainer StatusContainer to get status from.
129 	 *
130 	 * This methods returns manually set status from given StatusContainer. This is the last status that was
131 	 * set using StatusChangerManager::setStatus method.
132 	 */
133 	Status manuallySetStatus(StatusContainer *statusContainer);
134 
135 signals:
136 	/**
137 	 * @short Emited just before status is changed by user.
138 	 * @param statusContainer StatusContainer that changes status on.
139 	 * @param status status to be set on given statusContainer
140 	 *
141 	 * This signal can be used by status changers to disable themself in case user changes status.
142 	 */
143 	void manualStatusAboutToBeChanged(StatusContainer *statusContainer, Status status);
144 
145 };
146 
147 /**
148  * @addtogroup Status
149  * @}
150  */
151