11/* 
22 *    Copyright 2012, 2013 Thomas Schöps 
33 *    Copyright 2012-2018, 2021, 2024 Kai Pastor 
4+  *    Copyright 2025 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:" 
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:" 
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." 
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