]> git.sven.stormbind.net Git - sven/vym.git/blob - src/vymview.cpp
Replace Pierre as the maintainer
[sven/vym.git] / src / vymview.cpp
1 #include "vymview.h"
2
3 #include "branchitem.h"
4 #include "dockeditor.h"
5 #include "mainwindow.h"
6 #include "mapeditor.h"
7 #include "slideeditor.h"
8 #include "treedelegate.h"
9 #include "treeeditor.h"
10
11 extern Main *mainWindow;
12 extern Settings settings;
13
14 VymView::VymView(VymModel *m)
15 {
16     model = m;
17     model->setView(this);
18
19     // Create TreeView
20     treeEditor = new TreeEditor(model);
21
22     selModel = new QItemSelectionModel(model);
23     model->setSelectionModel(selModel);
24
25     treeEditor->setSelectionModel(selModel);
26     treeEditor->setColumnWidth(0, 150);
27     treeEditor->setAnimated(true);
28     treeEditor->resize(20, 200);
29
30     TreeDelegate *delegate = new TreeDelegate(this);
31     treeEditor->setItemDelegate(delegate);
32
33     DockEditor *de;
34     de = new DockEditor(tr("Tree Editor", "Title of dockable editor widget"),
35                         this, model);
36     de->setWidget(treeEditor);
37     de->setAllowedAreas(Qt::AllDockWidgetAreas);
38     addDockWidget(Qt::LeftDockWidgetArea, de);
39     treeEditorDE = de;
40
41     connect(treeEditorDE, SIGNAL(visibilityChanged(bool)), mainWindow,
42             SLOT(updateActions()));
43
44     // Create good old MapEditor
45     mapEditor = model->getMapEditor();
46     if (!mapEditor)
47         mapEditor = new MapEditor(model);
48     setCentralWidget(mapEditor);
49
50     // Create SlideEditor
51     slideEditor = new SlideEditor(model);
52
53     de = new DockEditor(tr("Slide Editor", "Title of dockable editor widget"),
54                         this, model);
55     de->setWidget(slideEditor);
56     de->setAllowedAreas(Qt::AllDockWidgetAreas);
57     addDockWidget(Qt::RightDockWidgetArea, de);
58     slideEditorDE = de;
59     slideEditorDE->hide();
60     connect(slideEditorDE, SIGNAL(visibilityChanged(bool)), mainWindow,
61             SLOT(updateActions()));
62
63     // Connect selections
64
65     // Selection in Model changed
66     connect(
67         selModel,
68         SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
69         this,
70         SLOT(changeSelection(const QItemSelection &, const QItemSelection &)));
71
72     // Needed to update selbox during animation
73     connect(
74         model,
75         SIGNAL(
76             selectionChanged(const QItemSelection &, const QItemSelection &)),
77         mapEditor,
78         SLOT(updateSelection(const QItemSelection &, const QItemSelection &)));
79
80     // Connect data changed signals
81     connect(model,
82             SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
83             mapEditor, SLOT(updateData(const QModelIndex &)));
84
85     connect(model,
86             SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this,
87             SLOT(updateDockWidgetTitles())); // FIXME-3 connect directly to
88                                              // MainWindow and rename method
89                                              // (also updates selection in BPE)
90
91     connect(model,
92             SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
93             mainWindow, SLOT(updateHeadingEditor()));   // FIXME-2 introduced new to update BG color when frameBrush changes
94
95     connect(model, SIGNAL(updateQueries(VymModel *)), mainWindow,
96             SLOT(updateQueries(VymModel *)));
97
98     connect(model, SIGNAL(expandAll()), this, SLOT(expandAll()));
99
100     connect(model, SIGNAL(expandOneLevel()), this, SLOT(expandOneLevel()));
101
102     connect(model, SIGNAL(collapseOneLevel()), this, SLOT(collapseOneLevel()));
103
104     connect(model, SIGNAL(collapseUnselected()), this,
105             SLOT(collapseUnselected()));
106
107     connect(model, SIGNAL(showSelection(bool)), this, SLOT(showSelection(bool)));
108
109     connect(model, SIGNAL(updateLayout()), mapEditor, SLOT(autoLayout()));
110
111     mapEditor->setAntiAlias(mainWindow->isAliased());
112     mapEditor->setSmoothPixmap(mainWindow->hasSmoothPixmapTransform());
113
114     readSettings();
115 }
116
117 VymView::~VymView()
118 {
119     settings.setLocalValue(model->getFilePath(), "/treeEditor/visible",
120                                treeEditorIsVisible());
121     settings.setLocalValue(model->getFilePath(), "/slideEditor/visible",
122                                slideEditorIsVisible());
123 }
124
125 void VymView::readSettings()
126 {
127     if (settings
128             .localValue(model->getFilePath(), "/slideEditor/visible", "false")
129             .toBool())
130         slideEditorDE->show();
131     else
132         slideEditorDE->hide();
133
134     if (settings.localValue(model->getFilePath(), "/treeEditor/visible", "true")
135             .toBool())
136         treeEditorDE->show();
137     else
138         treeEditorDE->hide();
139 }
140
141 VymModel *VymView::getModel() { return model; }
142
143 MapEditor *VymView::getMapEditor() { return mapEditor; }
144
145 bool VymView::treeEditorIsVisible() { return treeEditorDE->isVisible(); }
146
147 bool VymView::slideEditorIsVisible() { return slideEditorDE->isVisible(); }
148
149 void VymView::initFocus() { mapEditor->setFocus(); }
150
151 void VymView::nextSlide() { slideEditor->nextSlide(); }
152
153 void VymView::previousSlide() { slideEditor->previousSlide(); }
154
155 void VymView::setSelectionBrush(const QBrush &brush)
156 {
157     mapEditor->setSelectionBrush(brush);
158     treeEditor->setStyleSheet(
159         "selection-background-color: " + brush.color().name(QColor::HexArgb) + ";" +
160         "background-color: " + mapEditor->getScene()->backgroundBrush().color().name());
161 }
162
163 void VymView::setBackgroundColor(const QColor &col)
164 {
165     mapEditor->getScene()->setBackgroundBrush(col);
166     treeEditor->setStyleSheet(
167         "selection-background-color: " + mapEditor->getSelectionBrush().color().name() + ";" +
168         "background-color: " + col.name());
169     mainWindow->updateHeadingEditor();
170 }
171
172 void VymView::setLinkColor(const QColor &col)
173 {
174     // Set color for "link arrows" in TreeEditor
175     //
176     // Alternatively one could use stylesheets
177     // https://doc.qt.io/qt-6/stylesheet-examples.html#customizing-qtreeview
178     QPalette palette = treeEditor->palette();
179     palette.setColor(QPalette::Text, col);
180     treeEditor->setPalette(palette);
181 }
182
183 void VymView::changeSelection(const QItemSelection &newsel,
184                               const QItemSelection &desel)
185 {
186     // Update note editor and heading editor // FIXME-3 improve this, evtl. move
187     // from mainwindow to here
188     model->updateSelection(newsel, desel);
189     mainWindow->changeSelection(model, newsel, desel);
190     mainWindow->updateDockWidgetTitles(model);
191     mapEditor->updateSelection(newsel, desel);
192
193     showSelection(false);
194 }
195
196 void VymView::updateDockWidgetTitles()
197 {
198     mainWindow->updateDockWidgetTitles(model);
199 }
200
201 void VymView::expandAll() { treeEditor->expandAll(); }
202
203 void VymView::expandOneLevel()
204 {
205     int level = 999999;
206     int d;
207     BranchItem *cur = NULL;
208     BranchItem *prev = NULL;
209     QModelIndex pix;
210
211     // Find level to expand
212     model->nextBranch(cur, prev);
213     while (cur) {
214         pix = model->index(cur);
215         d = cur->depth();
216         if (!treeEditor->isExpanded(pix) && d < level)
217             level = d;
218         model->nextBranch(cur, prev);
219     }
220
221     // Expand all to level
222     cur = NULL;
223     prev = NULL;
224     model->nextBranch(cur, prev);
225     while (cur) {
226         pix = model->index(cur);
227         d = cur->depth();
228         if (!treeEditor->isExpanded(pix) && d <= level &&
229             cur->branchCount() > 0)
230             treeEditor->setExpanded(pix, true);
231         model->nextBranch(cur, prev);
232     }
233 }
234
235 void VymView::collapseOneLevel()
236 {
237     int level = -1;
238     int d;
239     BranchItem *cur = NULL;
240     BranchItem *prev = NULL;
241     QModelIndex pix;
242
243     // Find level to collapse
244     model->nextBranch(cur, prev);
245     while (cur) {
246         pix = model->index(cur);
247         d = cur->depth();
248         if (treeEditor->isExpanded(pix) && d > level)
249             level = d;
250         model->nextBranch(cur, prev);
251     }
252
253     // collapse all to level
254     cur = NULL;
255     prev = NULL;
256     model->nextBranch(cur, prev);
257     while (cur) {
258         pix = model->index(cur);
259         d = cur->depth();
260         if (treeEditor->isExpanded(pix) && d >= level)
261             treeEditor->setExpanded(pix, false);
262         model->nextBranch(cur, prev);
263     }
264 }
265
266 void VymView::collapseUnselected()
267 {
268     QModelIndex pix;
269
270     // Find level to collapse
271     BranchItem *selbi = model->getSelectedBranch();
272     if (!selbi)
273         return;
274
275     QList<BranchItem *> itemPath;
276
277     // Do not include selected branch,
278     // this one also should be collapsed later
279     BranchItem *cur = selbi->parentBranch();
280     BranchItem *prev = NULL;
281
282     while (cur->parentBranch()) {
283         itemPath << cur;
284         cur = cur->parentBranch();
285     }
286
287     cur = NULL;
288
289     // collapse all to level
290     model->nextBranch(cur, prev);
291     while (cur) {
292         pix = model->index(cur);
293         if (treeEditor->isExpanded(pix) && itemPath.indexOf(cur) < 0) {
294             treeEditor->setExpanded(pix, false);
295         }
296         model->nextBranch(cur, prev);
297     }
298 }
299
300 void VymView::showSelection(bool scaled)
301 {
302     QModelIndex ix = model->getSelectedIndex();
303     treeEditor->scrollTo(ix, QAbstractItemView::EnsureVisible);
304     mapEditor->ensureSelectionVisibleAnimated(scaled);
305 }
306
307 void VymView::toggleTreeEditor()
308 {
309     if (treeEditorDE->isVisible()) {
310         treeEditorDE->hide();
311         settings.setLocalValue(model->getFilePath(), "/treeEditor/visible",
312                                "false");
313     }
314     else {
315         treeEditorDE->show();
316         settings.setLocalValue(model->getFilePath(), "/treeEditor/visible",
317                                "true");
318     }
319     model->setChanged();
320 }
321
322 void VymView::toggleSlideEditor()
323 {
324     if (slideEditorDE->isVisible()) {
325         slideEditorDE->hide();
326         settings.setLocalValue(model->getFilePath(), "/slideEditor/visible",
327                                "false");
328     }
329     else {
330         slideEditorDE->show();
331         settings.setLocalValue(model->getFilePath(), "/slideEditor/visible",
332                                "true");
333     }
334 }
335
336 void VymView::setFocusMapEditor() { mapEditor->setFocus(); }