Thu, 22 Feb 2018 11:41:58 +0200
Converted magic wand mode and other selection stuff to mvc
--- a/CMakeLists.txt Thu Feb 15 14:59:04 2018 +0200 +++ b/CMakeLists.txt Thu Feb 22 11:41:58 2018 +0200 @@ -70,6 +70,7 @@ src/editmodes/magicWandMode.cpp src/editmodes/rectangleMode.cpp src/editmodes/selectMode.cpp + src/geometry/linesegment.cpp src/linetypes/comment.cpp src/linetypes/conditionaledge.cpp src/linetypes/edgeline.cpp @@ -136,6 +137,7 @@ src/editmodes/rectangleMode.h src/editmodes/selectMode.h src/generics/reverse.h + src/geometry/linesegment.h src/linetypes/comment.h src/linetypes/conditionaledge.h src/linetypes/edgeline.h
--- a/src/editmodes/abstractEditMode.cpp Thu Feb 15 14:59:04 2018 +0200 +++ b/src/editmodes/abstractEditMode.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -76,8 +76,7 @@ { canvas->setContextMenuPolicy(Qt::NoContextMenu); // We need the right mouse button for removing vertices canvas->setCursor(Qt::CrossCursor); - m_window->currentDocument()->clearSelection(); - m_window->updateSelection(); + canvas->selectionModel()->clear(); m_drawedVerts.clear(); }
--- a/src/editmodes/magicWandMode.cpp Thu Feb 15 14:59:04 2018 +0200 +++ b/src/editmodes/magicWandMode.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -22,17 +22,36 @@ #include "../mainwindow.h" #include "../canvas.h" -MagicWandMode::MagicWandMode (Canvas* canvas) : - Super (canvas) +MagicWandMode::MagicWandMode(Canvas* canvas) : + Super {canvas} { + QSet<LineSegment> boundarySegments; + // Get vertex<->object data - for (LDObject* obj : currentDocument()->objects()) + for (const QModelIndex& index : currentDocument()->indices()) { // Note: this deliberately only takes vertex-objects into account. // The magic wand does not process subparts. - for (int i = 0; i < obj->numVertices(); ++i) - m_vertices[obj->vertex (i)] << obj; + LDObject* object = currentDocument()->lookup(index); + + for (int i = 0; i < object->numVertices(); ++i) + { + LineSegment segment { + object->vertex(i), + object->vertex((i + 1) % object->numVertices()) + }; + m_vertices[object->vertex(i)].insert(index); + + if (object->type() == LDObjectType::EdgeLine) + boundarySegments.insert(segment); + else + this->segments[segment].insert(index); + } } + + // Remove all edge lines from the set of available segments because they get in the way. + for (const LineSegment& boundarySegment : boundarySegments) + this->segments.remove(boundarySegment); } EditModeType MagicWandMode::type() const @@ -40,157 +59,82 @@ return EditModeType::MagicWand; } -void MagicWandMode::fillBoundaries (LDObject* obj, QVector<BoundaryType>& boundaries, QSet<LDObject*>& candidates) -{ - // All boundaries obviously share vertices with the object, therefore they're all in the list - // of candidates. - for (LDObject* candidate : candidates) +void MagicWandMode::edgeFill( + QModelIndex index, + QItemSelection& selection, + QSet<QModelIndex>& processed +) const { + QItemSelection result; + processed.insert(index); + result.select(index, index); + QSet<QPersistentModelIndex> candidates; + LDObject* object = currentDocument()->lookup(index); + + // Get the list of objects that touch this object, i.e. share a vertex with it. + for (int i = 0; i < object->numVertices(); ++i) + candidates |= m_vertices[object->vertex(i)]; + + candidates.remove(index); + + for (const QModelIndex& candidate : candidates) { - if (not isOneOf(candidate->type(), LDObjectType::EdgeLine, LDObjectType::ConditionalEdge) - or candidate->vertex (0) == candidate->vertex (1)) - { - continue; - } + LDObject* candidateObject = currentDocument()->lookup(candidate); - int matches = 0; + if (candidateObject->type() == LDObjectType::EdgeLine + and candidateObject->color() == object->color() + ) { + selection.select(candidate, candidate); - for (int i = 0; i < obj->numVertices(); ++i) + if (not processed.contains(candidate)) + edgeFill(candidate, selection, processed); + } + } +} + +void MagicWandMode::surfaceFill( + QModelIndex index, + QItemSelection& selection, + QSet<QModelIndex>& processed +) const { + LDObject* object = currentDocument()->lookup(index); + selection.select(index, index); + processed.insert(index); + + for (int i = 0; i < object->numVertices(); i += 1) + { + Vertex v_1 = object->vertex(i); + Vertex v_2 = object->vertex((i + 1) % object->numVertices()); + LineSegment segment {v_1, v_2}; + + for (const QModelIndex& candidate : this->segments[segment]) { - if (not isOneOf (obj->vertex (i), candidate->vertex (0), candidate->vertex (1))) - continue; - - if (++matches == 2) + if (currentDocument()->lookup(candidate)->color() == object->color()) { - // Boundary found. If it's an edgeline, add it to the boundaries list, if a - // conditional line, select it. - if (candidate->type() == LDObjectType::ConditionalEdge) - m_selection << candidate; - else - boundaries.append (std::make_tuple (candidate->vertex (0), candidate->vertex (1))); + selection.select(candidate, candidate); - break; + if (not processed.contains(candidate)) + surfaceFill(candidate, selection, processed); } } } } -void MagicWandMode::doMagic (LDObject* obj, MagicWandMode::MagicType type) +QItemSelection MagicWandMode::doMagic(const QModelIndex& index) const { - if (obj == nullptr) - { - if (type == Set) - currentDocument()->clearSelection(); + QItemSelection selection; + LDObject* object = currentDocument()->lookup(index); - return; - } - - int matchesneeded = 0; - QVector<BoundaryType> boundaries; - LDObjectType objtype = obj->type(); - - if (type != InternalRecursion) + if (object) { - m_selection.clear(); - m_selection.append (obj); - } + QSet<QModelIndex> processed; - switch (obj->type()) - { - case LDObjectType::EdgeLine: - case LDObjectType::ConditionalEdge: - matchesneeded = 1; - break; - - case LDObjectType::Triangle: - case LDObjectType::Quadrilateral: - matchesneeded = 2; - break; - - default: - return; + if (object->type() == LDObjectType::EdgeLine) + edgeFill(index, selection, processed); + else if (object->numPolygonVertices() >= 3) + surfaceFill(index, selection, processed); } - QSet<LDObject*> candidates; - - // Get the list of objects that touch this object, i.e. share a vertex - // with this. - for (int i = 0; i < obj->numVertices(); ++i) - candidates += m_vertices[obj->vertex (i)]; - - // If we're dealing with surfaces, get a list of boundaries. - if (matchesneeded > 1) - fillBoundaries (obj, boundaries, candidates); - - for (LDObject* candidate : candidates) - { - try - { - // If we're doing this on lines, we need exact type match. Surface types (quads and - // triangles) can be mixed. Also don't consider self a candidate, and don't consider - // objects we have already processed. - if ((candidate == obj) or - (candidate->color() != obj->color()) or - (m_selection.contains (candidate)) or - (matchesneeded == 1 and (candidate->type() != objtype)) or - ((candidate->numVertices() > 2) ^ (matchesneeded == 2))) - { - throw 0; - } - - // Now ensure the two objects share enough vertices. - QVector<Vertex> matches; - - for (int i = 0; i < obj->numVertices(); ++i) - { - for (int j = 0; j < candidate->numVertices(); ++j) - { - if (obj->vertex(i) == candidate->vertex(j)) - { - matches << obj->vertex(i); - break; - } - } - } - - if (countof(matches) < matchesneeded) - throw 0; // Not enough matches. - - // Check if a boundary gets in between the objects. - for (auto boundary : boundaries) - { - if (isOneOf (matches[0], std::get<0> (boundary), std::get<1> (boundary)) and - isOneOf (matches[1], std::get<0> (boundary), std::get<1> (boundary))) - { - throw 0; - } - } - - m_selection.append (candidate); - doMagic (candidate, InternalRecursion); - } - catch (int&) - { - continue; - } - } - - switch (type) - { - case Set: - currentDocument()->clearSelection(); - case Additive: - for (LDObject* obj : m_selection) - currentDocument()->addToSelection(obj); - break; - - case Subtractive: - for (LDObject* obj : m_selection) - currentDocument()->removeFromSelection(obj); - break; - - case InternalRecursion: - break; - } + return selection; } bool MagicWandMode::mouseReleased (MouseEventData const& data) @@ -200,14 +144,15 @@ if (data.releasedButtons & Qt::LeftButton and not data.mouseMoved) { - MagicType wandtype = MagicWandMode::Set; + QItemSelection selection = this->doMagic(renderer()->pick(data.ev->x(), data.ev->y())); + QItemSelectionModel::SelectionFlags command = QItemSelectionModel::ClearAndSelect; if (data.keymods & Qt::ShiftModifier) - wandtype = MagicWandMode::Additive; + command = QItemSelectionModel::Select; else if (data.keymods & Qt::ControlModifier) - wandtype = MagicWandMode::Subtractive; + command = QItemSelectionModel::Deselect; - doMagic (renderer()->pick (data.ev->x(), data.ev->y()), wandtype); + renderer()->selectionModel()->select(selection, command); return true; }
--- a/src/editmodes/magicWandMode.h Thu Feb 15 14:59:04 2018 +0200 +++ b/src/editmodes/magicWandMode.h Thu Feb 22 11:41:58 2018 +0200 @@ -19,31 +19,32 @@ #pragma once #include "abstractEditMode.h" #include "../basics.h" +#include "../geometry/linesegment.h" #include <QMap> #include <QVector> class MagicWandMode : public AbstractSelectMode { - QMap<Vertex, QSet<LDObject*>> m_vertices; - QVector<LDObject*> m_selection; + QMap<Vertex, QSet<QPersistentModelIndex>> m_vertices; + QMap<LineSegment, QSet<QPersistentModelIndex>> segments; + QItemSelection m_selection; DEFINE_CLASS (MagicWandMode, AbstractSelectMode) public: - using BoundaryType = std::tuple<Vertex, Vertex>; - enum MagicType - { - Set, - Additive, - Subtractive, - InternalRecursion - }; + MagicWandMode(Canvas* canvas); - MagicWandMode (Canvas* canvas); - void doMagic (LDObject* obj, MagicType type); + QItemSelection doMagic(const QModelIndex& index) const; virtual EditModeType type() const override; - virtual bool mouseReleased (MouseEventData const& data) override; + virtual bool mouseReleased(MouseEventData const& data) override; private: - void fillBoundaries (LDObject* obj, QVector<BoundaryType>& boundaries, QSet<LDObject *> &candidates); + void edgeFill( + QModelIndex index, + QItemSelection& selection, + QSet<QModelIndex>& processed) const; + void surfaceFill( + QModelIndex index, + QItemSelection& selection, + QSet<QModelIndex>& processed) const; };
--- a/src/editmodes/selectMode.cpp Thu Feb 15 14:59:04 2018 +0200 +++ b/src/editmodes/selectMode.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -94,25 +94,15 @@ void SelectMode::doSelection(const QRect& area) { - QSet<LDObject*> priorSelection = selectedObjects(); - QSet<LDObject*> newSelection = renderer()->pick(area); - - // If we're doing an additive pick, use a symmetric difference to keep the existing ones, and filter out objects that were selected - // once over again. - if (m_addpick) - newSelection = (newSelection - priorSelection) | (priorSelection - newSelection); - - newSelection.unite(renderer()->pick(area)); + QItemSelectionModel* model = renderer()->selectionModel(); + QItemSelectionModel::SelectionFlags mode; - // Select all objects that we now have selected that were not selected before. - for (LDObject* object : newSelection - priorSelection) - currentDocument()->addToSelection(object); + if (m_addpick) + mode = QItemSelectionModel::Toggle; + else + mode = QItemSelectionModel::ClearAndSelect; - // Likewise, deselect whatever was selected that isn't anymore. - for (LDObject* object : priorSelection - newSelection) - currentDocument()->removeFromSelection(object); - - m_window->updateSelection(); + model->select(renderer()->pick(area), mode); } bool SelectMode::mousePressed (QMouseEvent* ev) @@ -140,9 +130,9 @@ if (ev->buttons() & Qt::LeftButton) { currentDocument()->clearSelection(); - LDObject* obj = renderer()->pick (ev->x(), ev->y()); + QModelIndex index = renderer()->pick(ev->x(), ev->y()); - if (obj) + if (index.isValid()) { // TODO: m_window->endAction();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/geometry/linesegment.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -0,0 +1,65 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2017 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "linesegment.h" + +/* + * Returns the vertices of this line segment as a QPair. + */ +QPair<Vertex, Vertex> LineSegment::toPair() const +{ + return {this->v_1, this->v_2}; +} + +/* + * Possibly swaps the vertices of given line segment so that equivalent line segments become equal. + */ +LineSegment normalized(const LineSegment& segment) +{ + LineSegment result = segment; + + if (result.v_2 < result.v_1) + qSwap(result.v_1, result.v_2); + + return result; +} + +/* + * Overload of qHash for line segments. + */ +unsigned int qHash(const LineSegment& segment) +{ + return qHash(normalized(segment).toPair()); +} + +/* + * Comparison operator definition to allow line segments to be used in QSets. + */ +bool operator<(const LineSegment& one, const LineSegment& other) +{ + return normalized(one).toPair() < normalized(other).toPair(); +} + +/* + * Checks whether two line segments are equal. + */ +bool operator==(const LineSegment& one, const LineSegment& other) +{ + return (one.v_1 == other.v_1 and one.v_2 == other.v_2) + or (one.v_2 == other.v_1 and one.v_1 == other.v_2); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/geometry/linesegment.h Thu Feb 22 11:41:58 2018 +0200 @@ -0,0 +1,36 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 - 2017 Teemu Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once +#include "../basics.h" + +/* + * Models a 3D line segment. + */ +struct LineSegment +{ + Vertex v_1; + Vertex v_2; + + QPair<Vertex, Vertex> toPair() const; +}; + +LineSegment normalized(const LineSegment& segment); +unsigned int qHash(const LineSegment& segment); +bool operator==(const LineSegment& one, const LineSegment& other); +bool operator<(const LineSegment& one, const LineSegment& other);
--- a/src/glcompiler.cpp Thu Feb 15 14:59:04 2018 +0200 +++ b/src/glcompiler.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -209,7 +209,7 @@ // We may wish to apply blending on the color to indicate selection or highlight. double blendAlpha = 0.0; - if (this->selectionModel and this->selectionModel->isSelected(polygonOwnerIndex)) + if (this->_selectionModel and this->_selectionModel->isSelected(polygonOwnerIndex)) blendAlpha = 1.0; else if (polygonOwnerIndex == m_renderer->objectAtCursor()) blendAlpha = 0.5; @@ -538,23 +538,28 @@ m_renderer->update(); } +QItemSelectionModel* GLCompiler::selectionModel() const +{ + return _selectionModel; +} + void GLCompiler::setSelectionModel(QItemSelectionModel* selectionModel) { - if (this->selectionModel) - disconnect(this->selectionModel, 0, 0, 0); + if (this->_selectionModel) + disconnect(this->_selectionModel, 0, 0, 0); - this->selectionModel = selectionModel; + this->_selectionModel = selectionModel; - if (this->selectionModel) + if (this->_selectionModel) { connect( - this->selectionModel, + this->_selectionModel, SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(selectionChanged(const QItemSelection&, const QItemSelection&)) ); connect( - this->selectionModel, + this->_selectionModel, SIGNAL(destroyed(QObject*)), this, SLOT(clearSelectionModel())
--- a/src/glcompiler.h Thu Feb 15 14:59:04 2018 +0200 +++ b/src/glcompiler.h Thu Feb 22 11:41:58 2018 +0200 @@ -38,7 +38,8 @@ void prepareVBO (int vbonum); GLuint vbo (int vbonum) const; int vboSize (int vbonum) const; - void setSelectionModel(QItemSelectionModel* selectionModel); + QItemSelectionModel* selectionModel() const; + void setSelectionModel(QItemSelectionModel* _selectionModel); static int vboNumber (VboClass surface, VboSubclass complement); @@ -77,7 +78,7 @@ bool m_vboChanged[NumVbos] = {true}; int m_vboSizes[NumVbos] = {0}; GLRenderer* m_renderer; - QItemSelectionModel* selectionModel = nullptr; + QItemSelectionModel* _selectionModel = nullptr; private slots: void handleRowInsertion(const QModelIndex&, int first, int last);
--- a/src/glrenderer.cpp Thu Feb 15 14:59:04 2018 +0200 +++ b/src/glrenderer.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -703,10 +703,10 @@ /* * Returns the set of objects found in the specified pixel area. */ -QSet<LDObject*> GLRenderer::pick(const QRect& range) +QItemSelection GLRenderer::pick(const QRect& range) { makeCurrent(); - QSet<LDObject*> newSelection; + QItemSelection result; // Paint the picking scene setPicking(true); @@ -733,46 +733,46 @@ // Read pixels from the color buffer. glReadPixels(x0, height() - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data()); - QSet<qint32> indices; + QSet<qint32> ids; // Go through each pixel read and add them to the selection. // Each pixel maps to an LDObject index injectively. // Note: black is background, those indices are skipped. for (unsigned char *pixelCursor = pixelData.begin(); pixelCursor < pixelData.end(); pixelCursor += 4) { - qint32 index = pixelCursor[0] * 0x10000 + pixelCursor[1] * 0x100 + pixelCursor[2] * 0x1; - if (index != 0) - indices.insert(index); + qint32 id = pixelCursor[0] * 0x10000 + pixelCursor[1] * 0x100 + pixelCursor[2] * 0x1; + if (id != 0) + ids.insert(id); } // For each index read, resolve the LDObject behind it and add it to the selection. - for (qint32 index : indices) + for (qint32 id : ids) { - LDObject* object = LDObject::fromID(index); + QModelIndex index = m_model->indexFromId(id); - if (object != nullptr) - newSelection.insert(object); + if (index.isValid()) + result.select(index, index); } setPicking(false); repaint(); - return newSelection; + return result; } /* * Simpler version of GLRenderer::pick which simply picks whatever object on the cursor */ -LDObject* GLRenderer::pick(int mouseX, int mouseY) +QModelIndex GLRenderer::pick(int mouseX, int mouseY) { - unsigned char pixel[4]; makeCurrent(); setPicking(true); drawGLScene(); + unsigned char pixel[4]; glReadPixels(mouseX, height() - mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); - LDObject* object = LDObject::fromID(pixel[0] * 0x10000 + pixel[1] * 0x100 + pixel[2]); + QModelIndex result = m_model->indexFromId(pixel[0] * 0x10000 + pixel[1] * 0x100 + pixel[2]); setPicking(false); repaint(); - return object; + return result; } // ============================================================================= @@ -1018,6 +1018,11 @@ */ void GLRenderer::drawFixedCameraBackdrop() {} +QItemSelectionModel* GLRenderer::selectionModel() const +{ + return m_compiler->selectionModel(); +} + void GLRenderer::setSelectionModel(QItemSelectionModel* selectionModel) { this->m_compiler->setSelectionModel(selectionModel);
--- a/src/glrenderer.h Thu Feb 15 14:59:04 2018 +0200 +++ b/src/glrenderer.h Thu Feb 22 11:41:58 2018 +0200 @@ -64,14 +64,15 @@ QPoint const& mousePosition() const; QPointF const& mousePositionF() const; QPersistentModelIndex objectAtCursor() const; - QSet<LDObject*> pick(const QRect& range); - LDObject* pick(int mouseX, int mouseY); + QItemSelection pick(const QRect& range); + QModelIndex pick(int mouseX, int mouseY); void resetAllAngles(); void resetAngles(); QImage screenCapture(); void setBackground(); void setCamera(Camera cam); QPen textPen() const; + QItemSelectionModel* selectionModel() const; void setSelectionModel(QItemSelectionModel* selectionModel); static const QPen thinBorderPen;
--- a/src/hierarchyelement.cpp Thu Feb 15 14:59:04 2018 +0200 +++ b/src/hierarchyelement.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -52,13 +52,13 @@ } -LDDocument* HierarchyElement::currentDocument() +LDDocument* HierarchyElement::currentDocument() const { return m_window->currentDocument(); } -const QSet<LDObject*>& HierarchyElement::selectedObjects() +QSet<LDObject*> HierarchyElement::selectedObjects() { return m_window->selectedObjects(); }
--- a/src/hierarchyelement.h Thu Feb 15 14:59:04 2018 +0200 +++ b/src/hierarchyelement.h Thu Feb 22 11:41:58 2018 +0200 @@ -40,8 +40,8 @@ public: HierarchyElement (QObject* parent); - const QSet<LDObject*>& selectedObjects(); - LDDocument* currentDocument(); + QSet<LDObject *> selectedObjects(); + LDDocument* currentDocument() const; GuiUtilities* guiUtilities() const; PrimitiveManager* primitives(); Grid* grid() const;
--- a/src/linetypes/conditionaledge.h Thu Feb 15 14:59:04 2018 +0200 +++ b/src/linetypes/conditionaledge.h Thu Feb 22 11:41:58 2018 +0200 @@ -35,6 +35,7 @@ virtual QString asText() const override; virtual void invert() override; int numVertices() const override { return 4; } + int numPolygonVertices() const override { return 2; } LDColor defaultColor() const override { return EdgeColor; } QString typeName() const override { return "condline"; }
--- a/src/linetypes/modelobject.cpp Thu Feb 15 14:59:04 2018 +0200 +++ b/src/linetypes/modelobject.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -135,6 +135,11 @@ return 0; } +int LDObject::numPolygonVertices() const +{ + return this->numVertices(); +} + // ============================================================================= // LDBezierCurve::LDBezierCurve(const Vertex& v0, const Vertex& v1, const Vertex& v2, const Vertex& v3, Model* model) :
--- a/src/linetypes/modelobject.h Thu Feb 15 14:59:04 2018 +0200 +++ b/src/linetypes/modelobject.h Thu Feb 22 11:41:58 2018 +0200 @@ -76,6 +76,7 @@ void move (Vertex vect); LDObject* next() const; virtual int numVertices() const; + virtual int numPolygonVertices() const; virtual QString objectListText() const; LDObject* previous() const; QColor randomColor() const;
--- a/src/mainwindow.cpp Thu Feb 15 14:59:04 2018 +0200 +++ b/src/mainwindow.cpp Thu Feb 22 11:41:58 2018 +0200 @@ -404,13 +404,6 @@ // --------------------------------------------------------------------------------------------------------------------- // -void MainWindow::updateSelection() -{ -#warning stub method -} - -// --------------------------------------------------------------------------------------------------------------------- -// // Returns the uniform selected color (i.e. 4 if everything selected is red), -1 if there is no such consensus. // LDColor MainWindow::getUniformSelectedColor()
--- a/src/mainwindow.h Thu Feb 15 14:59:04 2018 +0200 +++ b/src/mainwindow.h Thu Feb 22 11:41:58 2018 +0200 @@ -111,7 +111,6 @@ void updateEditModeActions(); void updateGridToolBar(); void updateRecentFilesMenu(); - void updateSelection(); void updateTitle(); static QPixmap getIcon(QString iconName);