00001 #include "taskworker.h"
00002
00003 #include <controllerfactory.h>
00004 #include <focusinterface.h>
00005 #include <models/taskmodel.h>
00006 #include <models/resourcemodel.h>
00007 #include <models/userrequirementsmodel.h>
00008 #include <models/resourcerequirementsmodel.h>
00009
00010 #include <domain/taskmanagerdata.h>
00011 #include <domain/user.h>
00012 #include <domain/invitation.h>
00013
00014 #include <tools/stringexception.h>
00015 #include <tools/functions.h>
00016
00017 #include <QPluginLoader>
00018 #include <QDir>
00019 #include <QDebug>
00020
00021 #ifdef Q_OS_WIN32
00022 #define FILTER "focus_*.dll"
00023 #else
00024 #define FILTER "libfocus_*.so"
00025 #endif
00026
00027 using namespace control;
00028
00029 ControllerInterface::ActionType TaskWorker::actionType() const
00030 {
00031 return CustomAction;
00032 }
00033
00034 ControllerInterface::DataType TaskWorker::dataType() const
00035 {
00036 return NoData;
00037 }
00038
00039 QString TaskWorker::description() const
00040 {
00041 return "Focus work";
00042 }
00043
00044 QString TaskWorker::name() const
00045 {
00046 return "TaskWorker";
00047 }
00048
00049 bool TaskWorker::userIsValid() const
00050 {
00051 return userHasLoggedIn() && !userIsAdmin();
00052 }
00053
00054 void TaskWorker::execute()
00055 {
00056 Q_ASSERT(!focusStrategies.isEmpty());
00057
00058 QMap<QString, FocusInterface*> strategyMap;
00059
00060 Q_FOREACH (FocusInterface* c, focusStrategies)
00061 strategyMap[c->description()] = c;
00062
00063 data::StringInputData choice = ui->getChoice(strategyMap.keys(),
00064 "Please choose how you want to focus:");
00065
00066 if (!choice.processData)
00067 return;
00068
00069 Q_ASSERT(strategyMap.contains(choice));
00070
00071 currentTasks = data->tasksForUser(user());
00072
00073 Q_FOREACH (const domain::Invitation* inv, user()->invitations())
00074 currentTasks << data->task(inv->task());
00075
00076 if (!strategyMap[choice]->applyFocus(¤tTasks))
00077 return;
00078
00079 if (currentTasks.isEmpty())
00080 ui->showMessage("No tasks in the selected focus.");
00081 else
00082 showTaskList();
00083 }
00084
00085 void TaskWorker::execute(const domain::StorableData* data)
00086 {
00087 Q_ASSERT(taskUpdater != 0);
00088 Q_ASSERT(taskModifier != 0);
00089
00090 domain::Task* task = this->data->task(qobject_cast<const domain::Task*>(data));
00091
00092 if (task == 0)
00093 throw tools::StringException("Given data is not a task.");
00094
00095 QString changeFocusOption = "Change focus";
00096 QString returnOption = "Return to task list";
00097 QString modifyOption = "Modify task details";
00098 QString updateOption = "Update task status";
00099
00100 QStringList options = QStringList() << changeFocusOption << returnOption
00101 << modifyOption << updateOption;
00102
00103 QList<domain::Task*> subTasksList;
00104
00105 Q_FOREACH (const domain::Task* subTask, task->subTasks())
00106 subTasksList << this->data->task(subTask);
00107
00108 data::TaskRepresentation rep;
00109 TaskModel subTasks(this->data, tools::makeConstList(subTasksList));
00110 rep.subTasks = &subTasks;
00111 rep.type = data::TaskTypeDetails(task->taskType());
00112 data::TaskDetails details(task);
00113 rep.details = details;
00114 UserRequirementsModel userReqs(task);
00115 rep.userReqs = &userReqs;
00116 ResourceRequirementsModel resourceReqs(task);
00117 rep.resourceReqs = &resourceReqs;
00118
00119 control::data::StringInputData input = ui->showTaskDetails(rep, options);
00120
00121 if (!input.processData)
00122 return;
00123
00124 QString chosenOption = input.data;
00125
00126 if (chosenOption == changeFocusOption)
00127 execute();
00128 else if (chosenOption == returnOption)
00129 showTaskList();
00130 else if (chosenOption == modifyOption)
00131 taskModifier->run(task);
00132 else if (chosenOption == updateOption)
00133 taskUpdater->run(task);
00134 else
00135 qFatal("Unkown option chosen.");
00136 }
00137
00138 void TaskWorker::showTaskList()
00139 {
00140 TaskModel taskModel(data, tools::makeConstList(currentTasks));
00141 data::SelectionData selection = ui->getSelection("Select a task", &taskModel);
00142
00143 if (!selection.processData)
00144 return;
00145
00146 if (selection.selection.isEmpty())
00147 {
00148 ui->showWarning("No task selected.");
00149 return;
00150 }
00151
00152 Q_ASSERT(selection.selection.count() == 1);
00153
00154 try
00155 {
00156 execute(taskModel.taskForIndex(selection.selection.first()));
00157 }
00158 catch (tools::StringException e)
00159 {
00160 ui->showError(e.message());
00161 }
00162 }
00163
00164 void TaskWorker::init(domain::TaskManagerData* data, ui::UiInterface* ui,
00165 ControllerFactory* factory)
00166 {
00167 ControllerInterface::init(data, ui, factory);
00168
00169 QDir pluginsDir = PLUGINS_PATH;
00170 pluginsDir.setNameFilters(QStringList() << FILTER);
00171
00172
00173 QStringList files = pluginsDir.entryList(QDir::Files);
00174
00175 Q_FOREACH (QString fileName, files)
00176 {
00177 QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
00178
00179 if (pluginLoader.load())
00180 {
00181 FocusInterface* strategy =
00182 qobject_cast<FocusInterface*>(pluginLoader.instance());
00183
00184 if (strategy != 0)
00185 {
00186 strategy->init(data, ui);
00187 focusStrategies << strategy;
00188 }
00189 }
00190 else
00191 {
00192 qDebug() << "Failed to load" << fileName
00193 << "because" << pluginLoader.errorString();
00194 }
00195 }
00196
00197 if (focusStrategies.isEmpty())
00198 throw tools::StringException("No focus strategies found.");
00199
00200 taskModifier = factory->controllerByType(TaskData, ModifyAction);
00201
00202 if (taskModifier == 0)
00203 throw tools::StringException("No controller to modify a task.");
00204
00205 taskUpdater = factory->controllerByType(TaskData, UpdateAction);
00206
00207 if (taskUpdater == 0)
00208 throw tools::StringException("No controller to update a task's status.");
00209 }
00210
00211 Q_EXPORT_PLUGIN2(controller_taskworker, TaskWorker)
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230