]> git.sven.stormbind.net Git - sven/vym.git/blob - taskeditor.cpp
a6f691966a66576cbd9f63130405d3af9e5b71d3
[sven/vym.git] / taskeditor.cpp
1 #include "taskeditor.h"
2
3 #include <QAbstractTableModel>
4 #include <QAction>
5 #include <QDebug>
6 #include <QHeaderView>
7 #include <QMenu>
8 #include <QSortFilterProxyModel>
9 #include <QTextEdit>
10 #include <QToolBar>
11 #include <QVBoxLayout>
12
13 #include "branchitem.h"
14 #include "mainwindow.h"
15 #include "task.h"
16 #include "taskmodel.h"
17 #include "vymmodel.h"
18
19 extern Main *mainWindow;
20 extern Settings settings;
21 extern QMenu* taskContextMenu;
22 extern TaskModel* taskModel;
23
24 TaskEditor::TaskEditor(QWidget *)
25 {
26     // Creat Table view
27     view = new QTableView; 
28
29     QVBoxLayout* mainLayout = new QVBoxLayout;
30
31     QToolBar *tb=new QToolBar ("TaskEditor filters");
32     tb->setToolButtonStyle (Qt::ToolButtonTextBesideIcon);
33     mainLayout->addWidget (tb);
34
35     // Original icon from KDE: /usr/share/icons/oxygen/16x16/actions/view-filter.png
36
37     QIcon icon=QIcon (":/view-filter.png");
38     QAction *a = new QAction(icon,  tr( "Current map","TaskEditor" ),this );
39     a->setCheckable(true);
40     a->setChecked  (settings.value("/taskeditor/filterMap", false).toBool());
41     tb->addAction (a);
42     connect( a, SIGNAL( triggered() ), this, SLOT(toggleFilterMap() ) );
43     actionToggleFilterMap = a;
44
45     a = new QAction(icon,  tr( "Active tasks","TaskEditor" ),this );
46     a->setCheckable(true);
47     a->setChecked  (settings.value("/taskeditor/filterActive", false).toBool());
48     tb->addAction (a);
49     connect( a, SIGNAL( triggered() ), this, SLOT(toggleFilterActive() ) );
50     actionToggleFilterActive = a;
51
52     a = new QAction(icon,  tr( "New tasks","TaskEditor" ),this );
53     a->setCheckable(true);
54     a->setChecked  (settings.value("/taskeditor/filterNew", false).toBool());
55     tb->addAction (a);
56     connect( a, SIGNAL( triggered() ), this, SLOT(toggleFilterNew() ) );
57     actionToggleFilterNew = a;
58
59     a = new QAction(icon,  "Flag", this); //tr( "Flags","TaskEditor" ),this );   // FIXME-1 add translation
60     a->setCheckable(true);
61     a->setChecked  (settings.value("/taskeditor/filterNew", false).toBool());
62     if (settings.value( "/mainwindow/showTestMenu",false).toBool())
63         tb->addAction (a);
64     connect( a, SIGNAL( triggered() ), this, SLOT(toggleFilterFlags() ) );
65     actionToggleFilterFlags = a;
66
67     // Forward Enter and Return to MapEditor
68     a = new QAction(icon, tr( "Edit heading","TaskEditor" ), this);
69     a->setShortcut ( Qt::Key_Return);           
70     a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
71     addAction (a);
72     connect( a, SIGNAL( triggered() ), mainWindow, SLOT( editHeading() ) );
73     a = new QAction( tr( "Edit heading","TaskEditor" ), this);
74     a->setShortcut ( Qt::Key_Enter);                    
75     a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
76     addAction (a);
77     connect( a, SIGNAL( triggered() ), mainWindow, SLOT( editHeading() ) );
78
79     // Clone actions defined in MainWindow
80     foreach (QAction* qa, mainWindow->taskEditorActions)
81     {
82         a = new QAction( this );
83         a->setShortcut( qa->shortcut() );
84         a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
85         connect( a, SIGNAL( triggered() ), qa, SLOT( trigger() ) );
86         addAction(a);
87     }
88
89     mainLayout->addWidget (view);
90     setLayout (mainLayout);
91
92     view->setSelectionBehavior(QAbstractItemView::SelectRows);
93     view->horizontalHeader()->setStretchLastSection(true);
94     view->verticalHeader()->hide();
95     view->setEditTriggers(QAbstractItemView::NoEditTriggers);
96
97     filterActiveModel = new TaskFilterModel;
98     filterActiveModel->setSourceModel(taskModel);
99
100     view->setModel (filterActiveModel);
101     view->setSortingEnabled(true);
102     view->horizontalHeader()->setSortIndicator (0,Qt::AscendingOrder);
103
104     blockExternalSelect=false;
105
106     connect (
107         view->selectionModel(),SIGNAL (selectionChanged (QItemSelection,QItemSelection)),
108         this, SLOT (selectionChanged (QItemSelection,QItemSelection)));
109     
110     // layout changes trigger resorting
111     connect( taskModel, SIGNAL( layoutChanged() ), this, SLOT(sort() ) );
112
113     // Enable wordwrap when data changes
114     connect ( 
115         taskModel, SIGNAL( dataChanged( QModelIndex, QModelIndex)),
116         view, SLOT( resizeRowsToContents() ) );
117     connect ( 
118         view->horizontalHeader(), SIGNAL( sectionResized(int, int, int)),
119         view, SLOT( resizeRowsToContents() ) );
120
121
122     // Initialize view filters according to previous settings
123     setFilterMap();
124     setFilterActive();
125     setFilterNew();
126     setFilterFlags();
127
128     // Initialize column widths
129     QString s;
130     for (int i=0; i<6; i++)
131     {
132         s=QString("/taskeditor/columnWidth/%1").arg(i);
133         if (settings.contains (s) )
134             view->setColumnWidth (i, settings.value(s, 100).toInt() );
135     }
136
137     // Initialize display of parents of a task
138     bool ok;
139     int i=settings.value ("/taskeditor/showParentsLevel", 0).toInt(&ok);
140     if (ok) taskModel->setShowParentsLevel(i);
141
142 }
143
144 TaskEditor::~TaskEditor()
145 {
146     settings.setValue ("/taskeditor/filterMap",actionToggleFilterMap->isChecked());
147     settings.setValue ("/taskeditor/filterActive",actionToggleFilterActive->isChecked());
148     settings.setValue ("/taskeditor/filterNew",actionToggleFilterNew->isChecked());
149     settings.setValue ("/taskeditor/showParentsLevel",taskModel->getShowParentsLevel() );
150     for (int i=0; i<7; i++)
151         settings.setValue (QString("/taskeditor/columnWidth/%1").arg(i),view->columnWidth(i) );
152 }
153
154 void TaskEditor::setMapName (const QString &n)
155 {
156     currentMapName=n;
157     setFilterMap();
158 }
159
160 bool TaskEditor::isUsedFilterMap()
161 {
162     return actionToggleFilterMap->isChecked();
163 }
164
165 void TaskEditor::setFilterMap () 
166 {
167     if (isUsedFilterMap() )
168         filterActiveModel->setMapFilter(currentMapName);
169     else
170         filterActiveModel->setMapFilter(QString() );
171     sort();
172 }
173
174 bool TaskEditor::isUsedFilterActive()
175 {
176     return actionToggleFilterActive->isChecked();
177 }
178
179 void TaskEditor::setFilterActive () 
180 {
181     filterActiveModel->setFilter (actionToggleFilterActive->isChecked() );   
182     sort();     
183 }
184
185 void TaskEditor::setFilterNew ()
186 {
187     filterActiveModel->setFilterNew (actionToggleFilterNew->isChecked() );
188     sort();
189 }
190
191 void TaskEditor::setFilterFlags ()  // FIXME-1 experimental
192 {
193     filterActiveModel->setFilterFlags (actionToggleFilterFlags->isChecked() );
194     sort();
195 }
196
197 void TaskEditor::showSelection()
198 {
199     QModelIndexList list=view->selectionModel()->selectedIndexes();
200     if (list.count()>0)
201         // Usually whole row is selected, so just go for first cell
202         view->scrollTo(taskModel->index(taskModel->getTask(list.first())), QAbstractItemView::EnsureVisible);
203 }
204
205 bool TaskEditor::select (Task *task)    
206 {
207     if (task)
208     {
209         blockExternalSelect=true;
210         QModelIndex i0b=taskModel->index (task); 
211         QModelIndex i0e=taskModel->indexRowEnd (task); 
212
213         QModelIndex i1b=filterActiveModel->mapFromSource(i0b ); 
214         QModelIndex i1e=filterActiveModel->mapFromSource(i0e ); 
215
216         QItemSelection sel (i1b, i1e);
217
218         view->selectionModel()->select (sel, QItemSelectionModel::ClearAndSelect  );
219         blockExternalSelect=false;
220         return true;
221     }
222     return false;
223 }
224
225 void TaskEditor::clearSelection()
226 {
227     view->selectionModel()->clearSelection();
228 }
229
230 void TaskEditor::selectionChanged ( const QItemSelection & selected, const QItemSelection & )
231 {// FIXME-3 what, if multiple selection in MapEditor?
232     // Avoid segfault on quit, when selected is empty
233     if (selected.indexes().isEmpty() ) return;
234
235     QItemSelection sel0=filterActiveModel->mapSelectionToSource (selected);
236     QModelIndex ix=sel0.indexes().first();
237     Task *t=taskModel->getTask (ix);
238     if (t) 
239     {
240         BranchItem *bi=t->getBranch();
241         if (bi) 
242         {
243             VymModel *m=bi->getModel();
244             if (!blockExternalSelect) m->select (bi);
245             if (m!=mainWindow->currentModel() )
246                 mainWindow->gotoModel (m);
247             view->setStyleSheet( 
248             QString ("selection-color: %1;" 
249                      "selection-background-color: %2;").arg(bi->getHeadingColor().name() ).arg(m->getSelectionColor().name() ) );
250             view->scrollTo (selected.indexes().first() );   
251         }
252     }
253 }
254
255 void TaskEditor::contextMenuEvent ( QContextMenuEvent * e )
256 {
257     taskContextMenu->popup (e->globalPos() );
258 }
259
260 void TaskEditor::sort()
261 {
262     QHeaderView *hv=view->horizontalHeader();
263     view->sortByColumn( hv->sortIndicatorSection(), hv->sortIndicatorOrder() );
264     filterActiveModel->invalidate();    
265
266 }
267
268 void TaskEditor::toggleFilterMap ()
269 {
270     setFilterMap ();
271 }
272
273 void TaskEditor::toggleFilterActive ()
274 {
275     setFilterActive();
276
277 }
278 void TaskEditor::toggleFilterNew ()
279 {
280     setFilterNew();
281 }
282
283 void TaskEditor::toggleFilterFlags ()
284 {
285     setFilterFlags();
286 }