11/*
22 * Copyright 2012, 2013 Thomas Schöps
33 * Copyright 2012-2018, 2021, 2024 Kai Pastor
4+ * Copyright 2024 Matthias Kühlewein
45 *
56 * This file is part of OpenOrienteering.
67 *
2122
2223#include " color_list_widget.h"
2324
25+ #include < vector>
26+
2427#include < Qt>
2528#include < QtGlobal>
2629#include < QAbstractButton>
2730#include < QAbstractItemView>
2831#include < QAction>
2932#include < QApplication>
33+ #include < QChar>
3034#include < QColor>
3135#include < QDialog>
3236#include < QFlags>
4852#include < QTableWidget>
4953#include < QTableWidgetItem>
5054#include < QToolButton>
51- #include < QVBoxLayout>
5255#include < QVariant>
56+ #include < QVBoxLayout>
5357
5458#include " core/map.h"
5559#include " core/map_color.h"
@@ -123,6 +127,9 @@ ColorListWidget::ColorListWidget(Map* map, MainWindow* window, QWidget* parent)
123127 edit_button = createToolButton (QIcon (QString::fromLatin1 (" :/images/settings.png" )), QApplication::translate (" OpenOrienteering::MapEditorController" , " &Edit" ).remove (QLatin1Char (' &' )));
124128 edit_button->setToolButtonStyle (Qt::ToolButtonTextBesideIcon);
125129
130+ auto cleanup_button = createToolButton (QIcon (QString::fromLatin1 (" :/images/delete.png" )), tr (" Cleanup" ));
131+ cleanup_button->setToolButtonStyle (Qt::ToolButtonTextBesideIcon);
132+
126133 auto help_button = createToolButton (QIcon (QString::fromLatin1 (" :/images/help.png" )), tr (" Help" ));
127134 help_button->setAutoRaise (true );
128135
@@ -132,6 +139,7 @@ ColorListWidget::ColorListWidget(Map* map, MainWindow* window, QWidget* parent)
132139 buttons_group_layout->addLayout (up_down_layout);
133140 buttons_group_layout->addWidget (edit_button);
134141 buttons_group_layout->addWidget (new QLabel (QString::fromLatin1 (" " )), 1 );
142+ buttons_group_layout->addWidget (cleanup_button);
135143 buttons_group_layout->addWidget (help_button);
136144
137145 // The layout of all components below the table
@@ -184,6 +192,7 @@ ColorListWidget::ColorListWidget(Map* map, MainWindow* window, QWidget* parent)
184192 connect (move_up_button, &QAbstractButton::clicked, this , &ColorListWidget::moveColorUp);
185193 connect (move_down_button, &QAbstractButton::clicked, this , &ColorListWidget::moveColorDown);
186194 connect (edit_button, &QAbstractButton::clicked, this , &ColorListWidget::editCurrentColor);
195+ connect (cleanup_button, &QAbstractButton::clicked, this , &ColorListWidget::removeUnusedColors);
187196 connect (help_button, &QAbstractButton::clicked, this , &ColorListWidget::showHelp);
188197
189198 connect (map, &Map::colorAdded, this , &ColorListWidget::colorAdded);
@@ -223,9 +232,10 @@ void ColorListWidget::newColor()
223232 editCurrentColor ();
224233}
225234
226- bool ColorListWidget::confirmColorDeletion (const MapColor* color_to_be_removed) const
235+ std::pair<QString, bool > ColorListWidget::determineColorUsage (const MapColor* color_to_be_removed) const
227236{
228237 QString detailed_text;
238+ bool color_used_by_symbols = false ;
229239
230240 std::vector<const Symbol*> remaining_symbols;
231241 remaining_symbols.reserve (std::size_t (map->getNumSymbols ()));
@@ -246,6 +256,7 @@ bool ColorListWidget::confirmColorDeletion(const MapColor* color_to_be_removed)
246256 {
247257 detailed_text += tr (" This color is used by the following symbols:" ) + QChar::LineFeed
248258 + direct_usage + QChar::LineFeed;
259+ color_used_by_symbols = true ;
249260 }
250261 }
251262
@@ -286,18 +297,25 @@ bool ColorListWidget::confirmColorDeletion(const MapColor* color_to_be_removed)
286297 {
287298 detailed_text += tr (" This spot color is used by the following symbols:" ) + QChar::LineFeed
288299 + transitive_usage;
300+ color_used_by_symbols = true ;
289301 }
290302 }
291303 }
292-
293- if (detailed_text.isEmpty ())
304+
305+ return std::make_pair (detailed_text, color_used_by_symbols);
306+ }
307+
308+ bool ColorListWidget::confirmColorDeletion (const MapColor* color_to_be_removed) const
309+ {
310+ const auto result = determineColorUsage (color_to_be_removed);
311+ if (result.first .isEmpty ())
294312 return true ;
295313
296314 QMessageBox msgBox;
297315 msgBox.setWindowTitle (tr (" Confirmation" ));
298316 msgBox.setIcon (QMessageBox::Warning);
299317 msgBox.setText (tr (" Color \" %1\" is used by other elements. Removing the color will change the appearance of these elements. Do you really want to remove it?" ).arg (color_to_be_removed->getName ()));
300- msgBox.setDetailedText (detailed_text );
318+ msgBox.setDetailedText (result. first );
301319 msgBox.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
302320 return msgBox.exec () == QMessageBox::Yes;
303321}
@@ -393,6 +411,44 @@ void ColorListWidget::editCurrentColor()
393411 }
394412}
395413
414+ void ColorListWidget::removeUnusedColors ()
415+ {
416+ QString unused_color_names;
417+ std::vector<int > unused_colors;
418+ unused_colors.reserve (std::size_t (map->getNumColors ()));
419+ for (auto row = color_table->rowCount () - 1 ; row >= 0 ; --row)
420+ {
421+ const auto color = map->getMapColor (row);
422+ const auto result = determineColorUsage (color);
423+ if (!result.second )
424+ {
425+ unused_colors.push_back (row);
426+ unused_color_names = color->getName () + QChar::LineFeed + unused_color_names;
427+ }
428+ }
429+ if (unused_colors.empty ())
430+ {
431+ QMessageBox::information (this , tr (" Information" ), tr (" There are no unused colors to be removed." ), QMessageBox::Ok);
432+ }
433+ else
434+ {
435+ QMessageBox msgBox;
436+ msgBox.setWindowTitle (tr (" Confirmation" ));
437+ msgBox.setIcon (QMessageBox::Question);
438+ msgBox.setText (tr (" Do you want to remove %n unused color(s) from the map?" , nullptr , unused_colors.size ()));
439+ msgBox.setDetailedText (unused_color_names);
440+ msgBox.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
441+ if (msgBox.exec () == QMessageBox::No)
442+ return ;
443+
444+ for (auto i : unused_colors)
445+ map->deleteColor (i);
446+
447+ map->setColorsDirty ();
448+ map->updateAllObjects ();
449+ }
450+ }
451+
396452void ColorListWidget::showHelp () const
397453{
398454 Util::showHelp (window, " color_dock_widget.html" );
0 commit comments