View Issue Details

IDProjectCategoryView StatusLast Update
0014810ScribusFontspublic2025-04-17 06:30
Reporterale Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
Status newResolutionopen 
Product Version1.5.3 
Summary0014810: [PATCH] add filters and batch actions in the preference's fonts list
Descriptionmain features:

- filter by name
- batch activate / deactivate the listed fonts

possible features

- filter by path
- other batch actions
- ...
Tags#easyhack
PatchYes

Relationships

related to 0014412 new Add an option to exclude font directories from being available in Scribus via the Prefs 

Activities

djfun

2017-05-22 13:44

reporter   ~0043921

I recently experimented with select all/deselect all buttons and selection of multiple rows to change their state with one click (I commented a video of this in https://bugs.scribus.net/view.php?id=9990#c43918)
Does this seem useful to this feature request? Or would it be better to just have the possibility to filter and activate/deactivate all visible items.

ale

2017-05-22 16:32

manager   ~0043922

https://giphy.com/gifs/3oKIPpYKwhgqKZlL9K/fullscreen is an interesting approach.

having a "conventional" filter looks a bit more straight forward to me (easier to discover and trigger) but being able to check/uncheck a bunch of selected items would also have been a fit.

all in all: if it's used in multiple places, @djfun method could be a non intrusive way of triggering action on list of items.

do you see other places in scribus where this approach could be used?

djfun

2017-05-22 19:59

reporter   ~0043924

are there any other really long lists in scribus?
to make the feature more discoverable and therefore useful, we could have the option to select multiple elements in the list and then buttons to activate selected, deactivate selected, activate all, deactivate all.
after a quick look through my most used software and a google search I have found no example of software that uses a "activate all visible elements" approach. Maybe you have an example? We would only need 2 buttons for this method, but if no other software is doing it this way, it may be more difficult for the users.

ale

2017-05-23 12:51

manager   ~0043931

if i understood correctly, mantis (this bug tracker!) is such a software.
scroll down to the end of the list of the tickets to find the button...

you then have a button for batch actions and a drop down to select the action you want to perform on the selection.
having the actions at the end is -- of course -- not really a good idea...

djfun

2017-05-23 13:26

reporter   ~0043932

mh, I am not sure if that is the same type of behavior. As there is no shift/mouse multiple selection possibility in html tables, the "select all" does help here with dealing with many list elements. But more importantly it only selects them. The action to perform (which would be the activation of the fonts) on the selected elements is separate from the selecting method. So no matter how you selected your elements you only perform the "permanent" action on the selected elements and not on all visible ones.
Maybe I am putting too much thought into such a minor functionality, but this is what I would expect from such a list/table widget.

ale

2017-05-23 14:14

manager   ~0043933

yes, with your workflow it's on the selected, with a filter on all visible...

ale

2025-04-16 20:31

manager   ~0052453

Last edited: 2025-04-16 20:41

indirectly inspired by how the fontmanager in fedora works,

https://app.filen.io/#/d/73c775f8-80bf-4930-88e0-11a2ea688de7#5g8KktsEwuzenHSWh4NJsi7k7tAbRsPI

here is a patch that allows activating, deactivating, subsetting and not subsetting the selected rows with a context menu.
fonts-multiple-activate.diff (4,308 bytes)   
From 4501dc34292961b32a467a5daf66decda3e7825f Mon Sep 17 00:00:00 2001
From: ale rimoldi <ale@graphicslab.org>
Date: Wed, 16 Apr 2025 22:29:36 +0200
Subject: allow de/activating multiple fonts at once


diff --git a/scribus/ui/fontlistview.cpp b/scribus/ui/fontlistview.cpp
index fe0cb683a..d9cf23419 100644
--- a/scribus/ui/fontlistview.cpp
+++ b/scribus/ui/fontlistview.cpp
@@ -7,17 +7,38 @@ for which a new license (GPL+exception) is in place.
 #include "fontlistview.h"
 #include "fontlistmodel.h"
 
+#include <QMenu>
+#include <QModelIndex>
+#include <QPoint>
 
 FontListView::FontListView(QWidget * parent)
-	: QTableView(parent)
+	: QTableView(parent),
+	contextMenu(new QMenu(this)),
+	activateAction(new QAction("Activate", this)),
+	deactivateAction(new QAction("Deactivate", this)),
+	subsetAction(new QAction("Subset", this)),
+	notSubsetAction(new QAction("Do not subset", this))
 {
-	setSelectionMode(QAbstractItemView::SingleSelection);
+	setSelectionMode(QAbstractItemView::ExtendedSelection);
 	setSelectionBehavior(QAbstractItemView::SelectRows);
 	sortByColumn(FontListModel::SortIndex, Qt::AscendingOrder);
 	// do not show default sorting to user
 	hideColumn(FontListModel::SortIndex);
 	setSortingEnabled(false);
 	setAlternatingRowColors(true);
+	setContextMenuPolicy(Qt::CustomContextMenu);
+
+	contextMenu->addAction(activateAction);
+	contextMenu->addAction(deactivateAction);
+	contextMenu->addAction(subsetAction);
+	contextMenu->addAction(notSubsetAction);
+
+	connect(activateAction, &QAction::triggered, this, &FontListView::activateSelection);
+	connect(deactivateAction, &QAction::triggered, this, &FontListView::deactivateSelection);
+	connect(subsetAction, &QAction::triggered, this, &FontListView::subsetSelection);
+	connect(notSubsetAction, &QAction::triggered, this, &FontListView::notSubsetSelection);
+
+	connect(this, &QTableView::customContextMenuRequested, this, &FontListView::customContextMenuRequested);
 }
 
 void FontListView::setModel(QAbstractItemModel * model)
@@ -58,3 +79,43 @@ bool FontListView::isFontSubsetted(int i)
 	return (checkState == Qt::Checked);
 }
 
+void FontListView::customContextMenuRequested(QPoint pos)
+{
+    contextMenu->popup(viewport()->mapToGlobal(pos));
+}
+
+void FontListView::activateSelection()
+{
+	FontListModel* fontModel = qobject_cast<FontListModel*>(model());
+	for (const auto& selectedRow: selectionModel()->selectedRows())
+	{
+		fontModel->setData(selectedRow, Qt::Checked, Qt::CheckStateRole);
+	}
+}
+
+void FontListView::deactivateSelection()
+{
+	FontListModel* fontModel = qobject_cast<FontListModel*>(model());
+	for (const auto& selectedRow: selectionModel()->selectedRows())
+	{
+		fontModel->setData(selectedRow, Qt::Unchecked, Qt::CheckStateRole);
+	}
+}
+
+void FontListView::subsetSelection()
+{
+	FontListModel* fontModel = qobject_cast<FontListModel*>(model());
+	for (const auto& selectedRow: selectionModel()->selectedRows())
+	{
+		fontModel->setData(fontModel->index(selectedRow.row(), FontListModel::FontSubset), Qt::Checked, Qt::CheckStateRole);
+	}
+}
+
+void FontListView::notSubsetSelection()
+{
+	FontListModel* fontModel = qobject_cast<FontListModel*>(model());
+	for (const auto& selectedRow: selectionModel()->selectedRows())
+	{
+		fontModel->setData(fontModel->index(selectedRow.row(), FontListModel::FontSubset), Qt::Unchecked, Qt::CheckStateRole);
+	}
+}
diff --git a/scribus/ui/fontlistview.h b/scribus/ui/fontlistview.h
index 10ed47b70..bbf0dc744 100644
--- a/scribus/ui/fontlistview.h
+++ b/scribus/ui/fontlistview.h
@@ -8,6 +8,7 @@ for which a new license (GPL+exception) is in place.
 #define FONTLISTVIEW_H
 
 #include <QTableView>
+#include <QWheelEvent>
 
 #include "scfonts.h"
 
@@ -26,10 +27,21 @@ class SCRIBUS_API FontListView : public QTableView
 
 		void setModel(QAbstractItemModel * model);
 		void setFonts(const SCFonts& f);
-
 		QString fontName(int i);
 		bool    isFontUsable(int i);
 		bool    isFontSubsetted(int i);
+	public slots:
+		void customContextMenuRequested(QPoint pos);
+	private:
+		QMenu* contextMenu;
+		QAction* activateAction;
+		QAction* deactivateAction;
+		QAction* subsetAction;
+		QAction* notSubsetAction;
+		void activateSelection();
+		void deactivateSelection();
+		void subsetSelection();
+		void notSubsetSelection();
 };
 
 #endif
fonts-multiple-activate.diff (4,308 bytes)   

ale

2025-04-17 06:30

manager   ~0052454

forgot the tr(), and now also added some accelerators...
fonts-multiple-activate-2.diff (4,328 bytes)   
From 4501dc34292961b32a467a5daf66decda3e7825f Mon Sep 17 00:00:00 2001
From: ale rimoldi <ale@graphicslab.org>
Date: Wed, 16 Apr 2025 22:29:36 +0200
Subject: allow de/activating multiple fonts at once


diff --git a/scribus/ui/fontlistview.cpp b/scribus/ui/fontlistview.cpp
index fe0cb683a..d9cf23419 100644
--- a/scribus/ui/fontlistview.cpp
+++ b/scribus/ui/fontlistview.cpp
@@ -7,17 +7,38 @@ for which a new license (GPL+exception) is in place.
 #include "fontlistview.h"
 #include "fontlistmodel.h"
 
+#include <QMenu>
+#include <QModelIndex>
+#include <QPoint>
 
 FontListView::FontListView(QWidget * parent)
-	: QTableView(parent)
+	: QTableView(parent),
+	contextMenu(new QMenu(this)),
+	activateAction(new QAction(tr("&Activate"), this)),
+	deactivateAction(new QAction(tr("&Deactivate"), this)),
+	subsetAction(new QAction(tr("&Subset"), this)),
+	notSubsetAction(new QAction(tr("Do &not subset"), this))
 {
-	setSelectionMode(QAbstractItemView::SingleSelection);
+	setSelectionMode(QAbstractItemView::ExtendedSelection);
 	setSelectionBehavior(QAbstractItemView::SelectRows);
 	sortByColumn(FontListModel::SortIndex, Qt::AscendingOrder);
 	// do not show default sorting to user
 	hideColumn(FontListModel::SortIndex);
 	setSortingEnabled(false);
 	setAlternatingRowColors(true);
+	setContextMenuPolicy(Qt::CustomContextMenu);
+
+	contextMenu->addAction(activateAction);
+	contextMenu->addAction(deactivateAction);
+	contextMenu->addAction(subsetAction);
+	contextMenu->addAction(notSubsetAction);
+
+	connect(activateAction, &QAction::triggered, this, &FontListView::activateSelection);
+	connect(deactivateAction, &QAction::triggered, this, &FontListView::deactivateSelection);
+	connect(subsetAction, &QAction::triggered, this, &FontListView::subsetSelection);
+	connect(notSubsetAction, &QAction::triggered, this, &FontListView::notSubsetSelection);
+
+	connect(this, &QTableView::customContextMenuRequested, this, &FontListView::customContextMenuRequested);
 }
 
 void FontListView::setModel(QAbstractItemModel * model)
@@ -58,3 +79,43 @@ bool FontListView::isFontSubsetted(int i)
 	return (checkState == Qt::Checked);
 }
 
+void FontListView::customContextMenuRequested(QPoint pos)
+{
+    contextMenu->popup(viewport()->mapToGlobal(pos));
+}
+
+void FontListView::activateSelection()
+{
+	FontListModel* fontModel = qobject_cast<FontListModel*>(model());
+	for (const auto& selectedRow: selectionModel()->selectedRows())
+	{
+		fontModel->setData(selectedRow, Qt::Checked, Qt::CheckStateRole);
+	}
+}
+
+void FontListView::deactivateSelection()
+{
+	FontListModel* fontModel = qobject_cast<FontListModel*>(model());
+	for (const auto& selectedRow: selectionModel()->selectedRows())
+	{
+		fontModel->setData(selectedRow, Qt::Unchecked, Qt::CheckStateRole);
+	}
+}
+
+void FontListView::subsetSelection()
+{
+	FontListModel* fontModel = qobject_cast<FontListModel*>(model());
+	for (const auto& selectedRow: selectionModel()->selectedRows())
+	{
+		fontModel->setData(fontModel->index(selectedRow.row(), FontListModel::FontSubset), Qt::Checked, Qt::CheckStateRole);
+	}
+}
+
+void FontListView::notSubsetSelection()
+{
+	FontListModel* fontModel = qobject_cast<FontListModel*>(model());
+	for (const auto& selectedRow: selectionModel()->selectedRows())
+	{
+		fontModel->setData(fontModel->index(selectedRow.row(), FontListModel::FontSubset), Qt::Unchecked, Qt::CheckStateRole);
+	}
+}
diff --git a/scribus/ui/fontlistview.h b/scribus/ui/fontlistview.h
index 10ed47b70..bbf0dc744 100644
--- a/scribus/ui/fontlistview.h
+++ b/scribus/ui/fontlistview.h
@@ -8,6 +8,7 @@ for which a new license (GPL+exception) is in place.
 #define FONTLISTVIEW_H
 
 #include <QTableView>
+#include <QWheelEvent>
 
 #include "scfonts.h"
 
@@ -26,10 +27,21 @@ class SCRIBUS_API FontListView : public QTableView
 
 		void setModel(QAbstractItemModel * model);
 		void setFonts(const SCFonts& f);
-
 		QString fontName(int i);
 		bool    isFontUsable(int i);
 		bool    isFontSubsetted(int i);
+	public slots:
+		void customContextMenuRequested(QPoint pos);
+	private:
+		QMenu* contextMenu;
+		QAction* activateAction;
+		QAction* deactivateAction;
+		QAction* subsetAction;
+		QAction* notSubsetAction;
+		void activateSelection();
+		void deactivateSelection();
+		void subsetSelection();
+		void notSubsetSelection();
 };
 
 #endif
fonts-multiple-activate-2.diff (4,328 bytes)   

Issue History

Date Modified Username Field Change
2017-05-22 08:30 ale New Issue
2017-05-22 08:30 ale Tag Attached: #easyhack
2017-05-22 08:31 ale Relationship added related to 0014412
2017-05-22 13:44 djfun Note Added: 0043921
2017-05-22 15:22 jghali Category - => Fonts
2017-05-22 16:32 ale Note Added: 0043922
2017-05-22 19:59 djfun Note Added: 0043924
2017-05-23 12:51 ale Note Added: 0043931
2017-05-23 13:26 djfun Note Added: 0043932
2017-05-23 14:14 ale Note Added: 0043933
2025-04-16 20:31 ale Note Added: 0052453
2025-04-16 20:31 ale File Added: font-activate-context-menu-patch.gif
2025-04-16 20:31 ale File Added: fonts-multiple-activate.diff
2025-04-16 20:33 ale Summary add filters and batch actions in the preference's fonts list => [PATCH] add filters and batch actions in the preference's fonts list
2025-04-16 20:33 ale Patch No => Yes
2025-04-16 20:41 ale Note Edited: 0052453
2025-04-17 06:30 ale Note Added: 0052454
2025-04-17 06:30 ale File Added: fonts-multiple-activate-2.diff