1 #include "todonote.h"
2 #include "textedit.h"
3 #include "todomodel.h"
4
5 #include <QClipboard>
6 #include <QApplication>
7
8 #include <QTreeView>
9 #include <QHeaderView>
10 #include <QScrollArea>
11 #include <QVBoxLayout>
12 #include <QGridLayout>
13 #include <QDataWidgetMapper>
14 #include <QDateTimeEdit>
15 #include <QCalendarWidget>
16 #include <QLabel>
17 #include <QCheckBox>
18 #include <QMenu>
19 #include <QTextStream>
20
21 enum
22 {
23 TODO_ACTION_INSERT,
24 TODO_ACTION_INSERT_SUB,
25 TODO_ACTION_REMOVE,
26 //TODO_ACTION_HIDE_COMPLETED,
27 TODO_ACTION_COUNT,
28 };
29
TodoNote(const QFileInfo & fileinfo,Note::Type type_new)30 TodoNote::TodoNote(const QFileInfo& fileinfo, Note::Type type_new)
31 : Note(fileinfo, type_new)
32 {
33 text_edit = new TextEdit();
34 text_edit->setAcceptRichText(false);
35 text_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
36 // text_edit->setMinimumHeight(100);
37 // text_edit->setMaximumHeight(200);
38
39 model = new TodoModel();
40 proxy_model = new TodoProxyModel();
41 proxy_model->setSourceModel(model);
42
43 tree_view = new QTreeView();
44 tree_view->setModel(proxy_model);
45 tree_view->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
46 tree_view->setSelectionBehavior(QAbstractItemView::SelectRows);
47 #if QT_VERSION >= 0x050000
48 tree_view->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
49 #endif
50
51 #if QT_VERSION < 0x050000
52 tree_view->header()->setResizeMode(QHeaderView::ResizeToContents);
53 #endif
54 tree_view->header()->hide();
55 tree_view->setDragEnabled(true);
56 tree_view->setAcceptDrops(true);
57 tree_view->setDropIndicatorShown(true);
58 tree_view->setDragDropMode(QAbstractItemView::InternalMove);
59 tree_view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
60
61 connect(proxy_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(taskChanged(QModelIndex)));
62 connect(tree_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(taskChanged(QModelIndex)));
63
64 tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
65 tree_view->setAnimated(true);
66
67 connect(tree_view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
68
69 menu_context = new QMenu();
70 menu_context->addAction(tr("Insert new task"), this, SLOT(insertTask()));
71 menu_context->addAction(tr("Insert new task"), this, SLOT(insertSubTask()));
72 menu_context->addAction(tr("Remove this task"), this, SLOT(removeTask()));
73 //menu_context->addAction(tr("Hide completed tasks"), this, SLOT(hideCompletedTasks()));
74 //menu_context->actions()[TODO_ACTION_HIDE_COMPLETED]->setCheckable(true);
75
76 for(int i=2; i<model->columnCount(); ++i)
77 tree_view->setColumnHidden(i, true);
78
79 lb_date_start = new QLabel;
80 lb_date_0 = new QLabel(tr("Created: "), lb_date_start);
81 lb_date_stop = new QLabel;
82 lb_date_1 = new QLabel(tr("Completed: "), lb_date_stop);
83 dt_date_limit = new QDateTimeEdit;
84 dt_date_limit->setCalendarPopup(true);
85 cb_date_limit = new QCheckBox(tr("Limited: "), dt_date_limit);
86 cb_date_limit->setCheckable(true);
87
88 grid_layout = new QGridLayout();
89 QGridLayout* l = qobject_cast<QGridLayout*>(grid_layout);
90 l->addWidget(lb_date_0, 0, 0);
91 l->addWidget(lb_date_start, 0, 1);
92 l->addWidget(lb_date_1, 1, 0);
93 l->addWidget(lb_date_stop, 1, 1);
94 l->addWidget(cb_date_limit, 2, 0);
95 l->addWidget(dt_date_limit, 2, 1);
96
97 extra_layout = new QVBoxLayout;
98 extra_layout->addItem(grid_layout);
99 extra_layout->addWidget(text_edit);
100
101 extra_widget = new QWidget;
102 extra_widget->setLayout(extra_layout);
103 extra_widget->hide();
104
105 main_layout = new QVBoxLayout();
106 main_layout->addWidget(tree_view);
107 main_layout->addWidget(extra_widget);
108
109 area = new QScrollArea();
110 area->setLayout(main_layout);
111
112 load(); //loading note's content
113
114 mapper = new QDataWidgetMapper();
115 mapper->setModel(proxy_model);
116 mapper->addMapping(text_edit, 6, "plainText");
117 mapper->addMapping(lb_date_start, 2, "text");
118 mapper->addMapping(lb_date_stop, 3, "text");
119 lb_date_start->setLocale(settings.getLocale());
120 dt_date_limit->setLocale(settings.getLocale());
121 dt_date_limit->calendarWidget()->setLocale(settings.getLocale());
122
123 tree_view->setCurrentIndex(QModelIndex());
124 }
125
~TodoNote()126 TodoNote::~TodoNote()
127 {
128 tree_view->deleteLater();
129 proxy_model->deleteLater();
130 model->deleteLater();
131 text_edit->deleteLater();
132 extra_layout->deleteLater();
133 main_layout->deleteLater();
134 extra_widget->deleteLater();
135 area->deleteLater();
136 lb_date_start->deleteLater();
137 lb_date_stop->deleteLater();
138 dt_date_limit->deleteLater();
139 cb_date_limit->deleteLater();
140 grid_layout->deleteLater();
141 mapper->deleteLater();
142
143 menu_context->deleteLater();
144 }
145
retranslate(const QLocale & locale)146 void TodoNote::retranslate(const QLocale& locale)
147 {
148 menu_context->actions()[TODO_ACTION_INSERT]->setText(tr("Insert new task"));
149 menu_context->actions()[TODO_ACTION_INSERT_SUB]->setText(tr("Insert new task"));
150 menu_context->actions()[TODO_ACTION_REMOVE]->setText(tr("Remove this task"));
151 //menu_context->actions()[TODO_ACTION_HIDE_COMPLETED]->setText(tr("Hide completed tasks"));
152 lb_date_0->setText(tr("Created: "));
153 lb_date_1->setText(tr("Completed: "));
154 cb_date_limit->setText(tr("Limited: "));
155 lb_date_start->setLocale(locale);
156 dt_date_limit->setLocale(locale);
157 dt_date_limit->calendarWidget()->setLocale(locale);
158 }
159
160 //Reading file
load()161 void TodoNote::load()
162 {
163 file.close();
164 if(!file.exists())
165 {
166 file.open(QIODevice::WriteOnly);
167 file.close();
168 }
169 if(file.open(QIODevice::ReadOnly))
170 {
171 domDocument = model->load(file);
172 file.close();
173 }
174 }
175
176 //Saving note
save(bool forced)177 void TodoNote::save(bool forced)
178 {
179 if(!(content_changed || forced)) return; //If file doesn't need in saving, exiting from function
180 file.close();
181 if(file.open(QFile::WriteOnly))
182 {
183 QTextStream out(&file);
184 domDocument->save(out, QDomNode::EncodingFromDocument);
185 content_changed = false;
186 }
187 }
188
189 //Returning widget (it's can be placed to tabwidget)
widget()190 QWidget* TodoNote::widget()
191 {
192 return area;
193 }
194
195 //Coping note's content to clipboard
copy() const196 void TodoNote::copy() const
197 {
198 // QClipboard* clipboard = QApplication::clipboard();
199 // clipboard->setPixmap(*label->pixmap());
200 }
201
contextMenuRequested(const QPoint & pos)202 void TodoNote::contextMenuRequested(const QPoint& pos)
203 {
204 QModelIndex index = tree_view->indexAt(pos);
205 menu_context->actions()[TODO_ACTION_INSERT]->setVisible(!index.isValid());
206 menu_context->actions()[TODO_ACTION_INSERT_SUB]->setVisible(index.isValid());
207 menu_context->actions()[TODO_ACTION_REMOVE]->setEnabled(index.isValid());
208 QPoint pos_global = tree_view->mapToGlobal(pos);
209 menu_context->exec(pos_global);
210 }
211
insertTask()212 void TodoNote::insertTask()
213 {
214 QModelIndex index;
215 int row = model->rowCount(index);
216 model->insertRow(row, index);
217 //Setting current index to created task
218 QModelIndex child_index = model->index(row, 0);
219 QModelIndex proxy_index = proxy_model->mapFromSource(child_index);
220 tree_view->setCurrentIndex(proxy_index);
221 }
222
insertSubTask()223 void TodoNote::insertSubTask()
224 {
225 QModelIndex proxy_index = tree_view->currentIndex();
226 QModelIndex index = proxy_model->mapToSource(proxy_index);
227 int row = model->rowCount(index);
228 model->insertRow(row, index);
229 //Setting current index to created task
230 QModelIndex child_index = index.child(row, 0);
231 proxy_index = proxy_model->mapFromSource(child_index);
232 tree_view->setCurrentIndex(proxy_index);
233 }
234
removeTask()235 void TodoNote::removeTask()
236 {
237 QModelIndex proxy_index = tree_view->currentIndex();
238 QModelIndex index = proxy_model->mapToSource(proxy_index);
239 if(index.isValid())
240 model->removeRow(index.row(), index.parent());
241 }
242
hideCompletedTasks()243 void TodoNote::hideCompletedTasks()
244 {
245 //bool hide_completed = menu_context->actions()[TODO_ACTION_HIDE_COMPLETED]->isChecked();
246 //proxy_model->hideDoneTasks(hide_completed);
247 }
248
taskChanged(const QModelIndex & proxy_index)249 void TodoNote::taskChanged(const QModelIndex& proxy_index)
250 {
251 extra_widget->setVisible(proxy_index.isValid());
252 if(!proxy_index.isValid()) return;
253 mapper->setRootIndex(proxy_index.parent());
254 mapper->setCurrentModelIndex(proxy_index);
255 QModelIndex index = proxy_model->mapToSource(proxy_index);
256 Task* task = static_cast<Task*>(index.internalPointer());
257 //
258 disconnect(dt_date_limit, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(noteDateLimitChanged(QDateTime)));
259 disconnect(cb_date_limit, SIGNAL(toggled(bool)), this, SLOT(noteLimitChanged(bool)));
260 dt_date_limit->setDateTime(task->dateLimit());
261 cb_date_limit->setChecked(task->limited());
262 connect(dt_date_limit, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(noteDateLimitChanged(QDateTime)));
263 connect(cb_date_limit, SIGNAL(toggled(bool)), this, SLOT(noteLimitChanged(bool)));
264 //
265 bool task_done = task->done();
266 lb_date_1->setVisible(task_done);
267 lb_date_stop->setVisible(task_done);
268 cb_date_limit->setHidden(task_done);
269 dt_date_limit->setHidden(task_done);
270 dt_date_limit->setEnabled(task->limited());
271
272 }
273
noteDateLimitChanged(const QDateTime & date)274 void TodoNote::noteDateLimitChanged(const QDateTime& date)
275 {
276 QModelIndex proxy_index = tree_view->currentIndex();
277 QModelIndex index = proxy_model->mapToSource(proxy_index);
278 if(!index.isValid()) return;
279 QModelIndex date_limit_index = index.sibling(index.row(), 4);
280 model->setData(date_limit_index, date, Qt::EditRole);
281 }
282
noteLimitChanged(bool limited)283 void TodoNote::noteLimitChanged(bool limited)
284 {
285 QDateTime date = limited?QDateTime::currentDateTime().addDays(7):QDateTime();
286 noteDateLimitChanged(date);
287 }
288
isDocumentSupported() const289 bool TodoNote::isDocumentSupported() const
290 {
291 return false;
292 }
293
document() const294 QTextDocument *TodoNote::document() const
295 {
296 return 0;
297 }
298