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 <kstandarddirs.h>
39 
40 #include <libkcal/vcaldrag.h>
41 
42 #include "KGantt.h"
43 
44 #include "koprojectview.h"
45 
46 using namespace KOrg;
47 
48 KOProjectViewItem::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 
57 KOProjectViewItem::~KOProjectViewItem()
58 {
59 }
60 
61 Todo *KOProjectViewItem::event()
62 {
63  return mEvent;
64 }
65 
66 
67 KOProjectView::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 
107 void 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 
117 void KOProjectView::readSettings()
118 {
119  kdDebug(5850) << "KOProjectView::readSettings()" << endl;
120 
121  //TDEConfig *config = kapp->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 
131 void 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 
142 void 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 
197 TQMap<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 
219 KGanttItem *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 
251 void 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 
268 DateList KOProjectView::selectedDates()
269 {
270  DateList selected;
271  return selected;
272 }
273 
274 void KOProjectView::changeIncidenceDisplay(Incidence *, int)
275 {
276  updateView();
277 }
278 
279 void KOProjectView::showDates(const TQDate &, const TQDate &)
280 {
281  updateView();
282 }
283 
284 void KOProjectView::showIncidences( const Incidence::List & )
285 {
286  kdDebug(5850) << "KOProjectView::showIncidences( const Incidence::List & ): not yet implemented" << endl;
287 }
288 
289 #if 0
290 void KOProjectView::editItem(TQListViewItem *item)
291 {
292  emit editIncidenceSignal(((KOProjectViewItem *)item)->event());
293 }
294 
295 void KOProjectView::showItem(TQListViewItem *item)
296 {
297  emit showIncidenceSignal(((KOProjectViewItem *)item)->event());
298 }
299 
300 void 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 
307 void KOProjectView::newTodo()
308 {
309  emit newTodoSignal();
310 }
311 
312 void KOProjectView::newSubTodo()
313 {
314  if (mActiveItem) {
315  emit newSubTodoSignal(mActiveItem->event());
316  }
317 }
318 
319 void 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 
338 void KOProjectView::showModeMenu()
339 {
340  mGantt->menu()->popup(TQCursor::pos());
341 }
342 
343 void 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 
356 void KOProjectView::zoomIn()
357 {
358  mGantt->zoom(2);
359 }
360 
361 void 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
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.
virtual Calendar * calendar()
Return calendar object of this view.
Definition: baseview.h:89