koprojectview.cpp
1/*
2 This file is part of KOrganizer.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18*/
19
20#include <tqlayout.h>
21#include <tqheader.h>
22#include <tqpushbutton.h>
23#include <tqfont.h>
24#include <tqlabel.h>
25#include <tqlineedit.h>
26#include <tqlistbox.h>
27#include <tqpopupmenu.h>
28#include <tqstrlist.h>
29#include <tqlistview.h>
30
31#include <tdeapplication.h>
32#include <kdebug.h>
33#include <tdelocale.h>
34#include <tdeglobal.h>
35#include <kiconloader.h>
36#include <tdemessagebox.h>
37#include <tdeconfig.h>
38#include <tdestandarddirs.h>
39
40#include <libkcal/vcaldrag.h>
41
42#include "KGantt.h"
43
44#include "koprojectview.h"
45
46using namespace KOrg;
47
48KOProjectViewItem::KOProjectViewItem(Todo *event,KGanttItem* parentTask,
49 const TQString& text,
50 const TQDateTime& start,
51 const TQDateTime& end) :
52 KGanttItem(parentTask,text,start,end)
53{
54 mEvent = event;
55}
56
57KOProjectViewItem::~KOProjectViewItem()
58{
59}
60
61Todo *KOProjectViewItem::event()
62{
63 return mEvent;
64}
65
66
67KOProjectView::KOProjectView(Calendar *calendar,TQWidget* parent,
68 const char* name) :
69 KOrg::BaseView(calendar,parent,name)
70{
71 TQBoxLayout *topLayout = new TQVBoxLayout(this);
72
73 TQBoxLayout *topBar = new TQHBoxLayout;
74 topLayout->addLayout(topBar);
75
76 TQLabel *title = new TQLabel(i18n("Project View"),this);
77 title->setFrameStyle(TQFrame::Panel|TQFrame::Raised);
78 topBar->addWidget(title,1);
79
80 TQPushButton *zoomIn = new TQPushButton(i18n("Zoom In"),this);
81 topBar->addWidget(zoomIn,0);
82 connect(zoomIn,TQ_SIGNAL(clicked()),TQ_SLOT(zoomIn()));
83
84 TQPushButton *zoomOut = new TQPushButton(i18n("Zoom Out"),this);
85 topBar->addWidget(zoomOut,0);
86 connect(zoomOut,TQ_SIGNAL(clicked()),TQ_SLOT(zoomOut()));
87
88 TQPushButton *menuButton = new TQPushButton(i18n("Select Mode"),this);
89 topBar->addWidget(menuButton,0);
90 connect(menuButton,TQ_SIGNAL(clicked()),TQ_SLOT(showModeMenu()));
91
92 createMainTask();
93
94 mGantt = new KGantt(mMainTask,this);
95 topLayout->addWidget(mGantt,1);
96
97#if 0
98 mGantt->addHoliday(2000, 10, 3);
99 mGantt->addHoliday(2001, 10, 3);
100 mGantt->addHoliday(2000, 12, 24);
101
102 for(int i=1; i<7; ++i)
103 mGantt->addHoliday(2001, 1, i);
104#endif
105}
106
107void KOProjectView::createMainTask()
108{
109 mMainTask = new KGanttItem(0,i18n("main task"),
110 TQDateTime::currentDateTime(),
111 TQDateTime::currentDateTime());
112 mMainTask->setMode(KGanttItem::Rubberband);
113 mMainTask->setStyle(KGanttItem::DrawBorder | KGanttItem::DrawText |
114 KGanttItem::DrawHandle);
115}
116
117void KOProjectView::readSettings()
118{
119 kdDebug(5850) << "KOProjectView::readSettings()" << endl;
120
121 //TDEConfig *config = tdeApp->config();
122 TDEConfig config( "korganizerrc", true, false); // Open read-only, no kdeglobals
123 config.setGroup("Views");
124
125 TQValueList<int> sizes = config.readIntListEntry("Separator ProjectView");
126 if (sizes.count() == 2) {
127 mGantt->splitter()->setSizes(sizes);
128 }
129}
130
131void KOProjectView::writeSettings(TDEConfig *config)
132{
133 kdDebug(5850) << "KOProjectView::writeSettings()" << endl;
134
135 config->setGroup("Views");
136
137 TQValueList<int> list = mGantt->splitter()->sizes();
138 config->writeEntry("Separator ProjectView",list);
139}
140
141
142void KOProjectView::updateView()
143{
144 kdDebug(5850) << "KOProjectView::updateView()" << endl;
145
146 // Clear Gantt view
147 TQPtrList<KGanttItem> subs = mMainTask->getSubItems();
148 KGanttItem *t=subs.first();
149 while(t) {
150 KGanttItem *nt=subs.next();
151 delete t;
152 t = nt;
153 }
154
155#if 0
156 KGanttItem* t1 = new KGanttItem(mGantt->getMainTask(), "task 1, no subtasks",
157 TQDateTime::currentDateTime().addDays(10),
158 TQDateTime::currentDateTime().addDays(20) );
159
160 KGanttItem* t2 = new KGanttItem(mGantt->getMainTask(), "task 2, subtasks, no rubberband",
161 TQDateTime(TQDate(2000,10,1)),
162 TQDateTime(TQDate(2000,10,31)) );
163#endif
164
165 Todo::List todoList = calendar()->todos();
166
167/*
168 kdDebug(5850) << "KOProjectView::updateView(): Todo List:" << endl;
169 Event *t;
170 for(t = todoList.first(); t; t = todoList.next()) {
171 kdDebug(5850) << " " << t->getSummary() << endl;
172
173 if (t->getRelatedTo()) {
174 kdDebug(5850) << " (related to " << t->getRelatedTo()->getSummary() << ")" << endl;
175 }
176
177 TQPtrList<Event> l = t->getRelations();
178 Event *c;
179 for(c=l.first();c;c=l.next()) {
180 kdDebug(5850) << " - relation: " << c->getSummary() << endl;
181 }
182 }
183*/
184
185 // Put for each Event a KOProjectViewItem in the list view. Don't rely on a
186 // specific order of events. That means that we have to generate parent items
187 // recursively for proper hierarchical display of Todos.
188 mTodoMap.clear();
189 Todo::List::ConstIterator it;
190 for( it = todoList.begin(); it != todoList.end(); ++it ) {
191 if ( !mTodoMap.contains( *it ) ) {
192 insertTodoItem( *it );
193 }
194 }
195}
196
197TQMap<Todo *,KGanttItem *>::ConstIterator
198 KOProjectView::insertTodoItem(Todo *todo)
199{
200// kdDebug(5850) << "KOProjectView::insertTodoItem(): " << todo->getSummary() << endl;
201 Todo *relatedTodo = dynamic_cast<Todo *>(todo->relatedTo());
202 if (relatedTodo) {
203// kdDebug(5850) << " has Related" << endl;
204 TQMap<Todo *,KGanttItem *>::ConstIterator itemIterator;
205 itemIterator = mTodoMap.find(relatedTodo);
206 if (itemIterator == mTodoMap.end()) {
207// kdDebug(5850) << " related not yet in list" << endl;
208 itemIterator = insertTodoItem (relatedTodo);
209 }
210 KGanttItem *task = createTask(*itemIterator,todo);
211 return mTodoMap.insert(todo,task);
212 } else {
213// kdDebug(5850) << " no Related" << endl;
214 KGanttItem *task = createTask(mMainTask,todo);
215 return mTodoMap.insert(todo,task);
216 }
217}
218
219KGanttItem *KOProjectView::createTask(KGanttItem *parent,Todo *todo)
220{
221 TQDateTime startDt;
222 TQDateTime endDt;
223
224 if (todo->hasStartDate() && !todo->hasDueDate()) {
225 // start date but no due date
226 startDt = todo->dtStart();
227 endDt = TQDateTime::currentDateTime();
228 } else if (!todo->hasStartDate() && todo->hasDueDate()) {
229 // due date but no start date
230 startDt = todo->dtDue();
231 endDt = todo->dtDue();
232 } else if (!todo->hasStartDate() || !todo->hasDueDate()) {
233 startDt = TQDateTime::currentDateTime();
234 endDt = TQDateTime::currentDateTime();
235 } else {
236 startDt = todo->dtStart();
237 endDt = todo->dtDue();
238 }
239
240 KGanttItem *task = new KOProjectViewItem(todo,parent,todo->summary(),startDt,
241 endDt);
242 connect(task,TQ_SIGNAL(changed(KGanttItem*, KGanttItem::Change)),
243 TQ_SLOT(taskChanged(KGanttItem*,KGanttItem::Change)));
244 if (todo->relations().count() > 0) {
245 task->setBrush(TQBrush(TQColor(240,240,240), TQBrush::Dense4Pattern));
246 }
247
248 return task;
249}
250
251void KOProjectView::updateConfig()
252{
253 // FIXME: to be implemented.
254}
255
257{
258 Incidence::List selected;
259
260/*
261 KOProjectViewItem *item = (KOProjectViewItem *)(mTodoListView->selectedItem());
262 if (item) selected.append(item->event());
263*/
264
265 return selected;
266}
267
268DateList KOProjectView::selectedDates()
269{
270 DateList selected;
271 return selected;
272}
273
274void KOProjectView::changeIncidenceDisplay(Incidence *, int)
275{
276 updateView();
277}
278
279void KOProjectView::showDates(const TQDate &, const TQDate &)
280{
281 updateView();
282}
283
284void KOProjectView::showIncidences( const Incidence::List & )
285{
286 kdDebug(5850) << "KOProjectView::showIncidences( const Incidence::List & ): not yet implemented" << endl;
287}
288
289#if 0
290void KOProjectView::editItem(TQListViewItem *item)
291{
292 emit editIncidenceSignal(((KOProjectViewItem *)item)->event());
293}
294
295void KOProjectView::showItem(TQListViewItem *item)
296{
297 emit showIncidenceSignal(((KOProjectViewItem *)item)->event());
298}
299
300void KOProjectView::popupMenu(TQListViewItem *item,const TQPoint &,int)
301{
302 mActiveItem = (KOProjectViewItem *)item;
303 if (item) mItemPopupMenu->popup(TQCursor::pos());
304 else mPopupMenu->popup(TQCursor::pos());
305}
306
307void KOProjectView::newTodo()
308{
309 emit newTodoSignal();
310}
311
312void KOProjectView::newSubTodo()
313{
314 if (mActiveItem) {
315 emit newSubTodoSignal(mActiveItem->event());
316 }
317}
318
319void KOProjectView::itemClicked(TQListViewItem *item)
320{
321 if (!item) return;
322
323 KOProjectViewItem *todoItem = (KOProjectViewItem *)item;
324 int completed = todoItem->event()->isCompleted(); // Completed or not?
325
326 if (todoItem->isOn()) {
327 if (!completed) {
328 todoItem->event()->setCompleted(true);
329 }
330 } else {
331 if (completed) {
332 todoItem->event()->setCompleted(false);
333 }
334 }
335}
336#endif
337
338void KOProjectView::showModeMenu()
339{
340 mGantt->menu()->popup(TQCursor::pos());
341}
342
343void KOProjectView::taskChanged(KGanttItem *task,KGanttItem::Change change)
344{
345 if (task == mMainTask) return;
346
347 KOProjectViewItem *item = (KOProjectViewItem *)task;
348
349 if (change == KGanttItem::StartChanged) {
350 item->event()->setDtStart(task->getStart());
351 } else if (change == KGanttItem::EndChanged) {
352 item->event()->setDtDue(task->getEnd());
353 }
354}
355
356void KOProjectView::zoomIn()
357{
358 mGantt->zoom(2);
359}
360
361void KOProjectView::zoomOut()
362{
363 mGantt->zoom(0.5);
364}
365
366#include "koprojectview.moc"
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Incidence * relatedTo() const
Incidence::List relations() const
TQString summary() const
bool hasDueDate() const
bool isCompleted() const
bool hasStartDate() const
void setDtDue(const TQDateTime &dtDue, bool first=false)
void setCompleted(bool completed)
TQDateTime dtStart(bool first=false) const
void setDtStart(const TQDateTime &dtStart)
TQDateTime dtDue(bool first=false) const
This class provides an item of the project view.
Definition: koprojectview.h:47
Incidence::List selectedIncidences()
This class provides an interface for all views being displayed within the main calendar view.
Definition: baseview.h:60
virtual Calendar * calendar()
Return calendar object of this view.
Definition: baseview.h:89
void editIncidenceSignal(Incidence *, const TQDate &)
instructs the receiver to begin editing the incidence specified in some manner.
void showIncidenceSignal(Incidence *, const TQDate &)
instructs the receiver to show the incidence in read-only mode.