Skip to content
Permalink
Browse files

[needs-docs] Show recently used fonts in submenu in font button

  • Loading branch information
nyalldawson committed Jul 6, 2017
1 parent e95b65e commit bacad8cea631e95a73f64b1905c0eab4d965df8d
Showing with 142 additions and 31 deletions.
  1. +15 −0 python/core/qgsfontutils.sip
  2. +29 −0 src/core/qgsfontutils.cpp
  3. +14 −0 src/core/qgsfontutils.h
  4. +49 −28 src/gui/qgsfontbutton.cpp
  5. +35 −3 tests/src/python/test_qgsfontutils.py
@@ -187,6 +187,21 @@ class QgsFontUtils
.. versionadded:: 2.16
:rtype: str
%End

static void addRecentFontFamily( const QString &family );
%Docstring
Adds a font ``family`` to the list of recently used font families.
.. versionadded:: 3.0
.. seealso:: recentFontFamilies()
%End

static QStringList recentFontFamilies();
%Docstring
Returns a list of recently used font families.
.. seealso:: addRecentFontFamily()
.. versionadded:: 3.0
:rtype: list of str
%End
};

/************************************************************************
@@ -17,6 +17,7 @@

#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgssettings.h"

#include <QApplication>
#include <QFile>
@@ -506,3 +507,31 @@ QString QgsFontUtils::asCSS( const QFont &font, double pointToPixelScale )

return css;
}

void QgsFontUtils::addRecentFontFamily( const QString &family )
{
if ( family.isEmpty() )
{
return;
}

QgsSettings settings;
QStringList recentFamilies = settings.value( QStringLiteral( "fonts/recent" ) ).toStringList();

//remove matching families
recentFamilies.removeAll( family );

//then add to start of list
recentFamilies.prepend( family );

//trim to 10 fonts
recentFamilies = recentFamilies.mid( 0, 10 );

settings.setValue( QStringLiteral( "fonts/recent" ), recentFamilies );
}

QStringList QgsFontUtils::recentFontFamilies()
{
QgsSettings settings;
return settings.value( QStringLiteral( "fonts/recent" ) ).toStringList();
}
@@ -165,6 +165,20 @@ class CORE_EXPORT QgsFontUtils
* \since QGIS 2.16
*/
static QString asCSS( const QFont &font, double pointToPixelMultiplier = 1.0 );

/**
* Adds a font \a family to the list of recently used font families.
* \since QGIS 3.0
* \see recentFontFamilies()
*/
static void addRecentFontFamily( const QString &family );

/**
* Returns a list of recently used font families.
* \see addRecentFontFamily()
* \since QGIS 3.0
*/
static QStringList recentFontFamilies();
};

#endif // QGSFONTUTILS_H
@@ -70,6 +70,7 @@ void QgsFontButton::showSettingsDialog()
if ( dialog.exec() )
{
setTextFormat( dialog.format() );
QgsFontUtils::addRecentFontFamily( mFormat.font().family() );
}
break;
}
@@ -80,6 +81,7 @@ void QgsFontButton::showSettingsDialog()
QFont newFont = QgsGuiUtils::getFont( ok, mFont, mDialogTitle );
if ( ok )
{
QgsFontUtils::addRecentFontFamily( newFont.family() );
setCurrentFont( newFont );
}
break;
@@ -141,9 +143,11 @@ void QgsFontButton::pasteFormat()
if ( mMode == ModeTextRenderer && formatFromMimeData( QApplication::clipboard()->mimeData(), tempFormat ) )
{
setTextFormat( tempFormat );
QgsFontUtils::addRecentFontFamily( mFormat.font().family() );
}
else if ( mMode == ModeQFont && fontFromMimeData( QApplication::clipboard()->mimeData(), font ) )
{
QgsFontUtils::addRecentFontFamily( font.family() );
setCurrentFont( font );
}
}
@@ -280,10 +284,12 @@ void QgsFontButton::dropEvent( QDropEvent *e )
if ( mMode == ModeTextRenderer && formatFromMimeData( e->mimeData(), format ) )
{
setTextFormat( format );
QgsFontUtils::addRecentFontFamily( mFormat.font().family() );
return;
}
else if ( mMode == ModeQFont && fontFromMimeData( e->mimeData(), font ) )
{
QgsFontUtils::addRecentFontFamily( font.family() );
setCurrentFont( font );
return;
}
@@ -463,34 +469,6 @@ void QgsFontButton::prepareMenu()
//menu is opened, otherwise color schemes like the recent color scheme grid are meaningless
mMenu->clear();

#if 0 // too slow if many fonts...
QMenu *fontMenu = new QMenu( mFormat.font().family(), mMenu );
QFontDatabase db;
Q_FOREACH ( const QString &family, db.families() )
{
QAction *fontAction = new QAction( family, fontMenu );
QFont f = fontAction->font();
f.setFamily( family );
fontAction->setFont( f );
fontAction->setToolTip( family );
fontMenu->addAction( fontAction );
if ( family == mFormat.font().family() )
{
fontAction->setCheckable( true );
fontAction->setChecked( true );
}
auto setFont = [this, family]
{
QFont f = mFormat.font();
f.setFamily( family );
mFormat.setFont( f );
updatePreview();
emit changed();
};
connect( fontAction, &QAction::triggered, this, setFont );
}
mMenu->addMenu( fontMenu );
#endif

QWidgetAction *sizeAction = new QWidgetAction( mMenu );
QWidget *sizeWidget = new QWidget();
@@ -545,6 +523,49 @@ void QgsFontButton::prepareMenu()
sizeWidget->setFocusPolicy( Qt::StrongFocus );
mMenu->addAction( sizeAction );

QMenu *recentFontMenu = new QMenu( tr( "Recent fonts" ), mMenu );
Q_FOREACH ( const QString &family, QgsFontUtils::recentFontFamilies() )
{
QAction *fontAction = new QAction( family, recentFontMenu );
QFont f = fontAction->font();
f.setFamily( family );
fontAction->setFont( f );
fontAction->setToolTip( family );
recentFontMenu->addAction( fontAction );
if ( ( mMode == ModeTextRenderer && family == mFormat.font().family() )
|| ( mMode == ModeQFont && family == mFont.family() ) )
{
fontAction->setCheckable( true );
fontAction->setChecked( true );
}
auto setFont = [this, family]
{
switch ( mMode )
{
case ModeTextRenderer:
{
QgsTextFormat newFormat = mFormat;
QFont f = newFormat.font();
f.setFamily( family );
newFormat.setFont( f );
setTextFormat( newFormat );
QgsFontUtils::addRecentFontFamily( mFormat.font().family() );
break;
}
case ModeQFont:
{
QFont font = mFont;
font.setFamily( family );
setCurrentFont( font );
QgsFontUtils::addRecentFontFamily( family );
break;
}
}
};
connect( fontAction, &QAction::triggered, this, setFont );
}
mMenu->addMenu( recentFontMenu );

QAction *configureAction = new QAction( tr( "Configure format..." ), this );
mMenu->addAction( configureAction );
connect( configureAction, &QAction::triggered, this, &QgsFontButton::showSettingsDialog );
@@ -14,23 +14,29 @@
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

from qgis.core import QgsFontUtils
from qgis.core import QgsFontUtils, QgsSettings
from qgis.testing import (
start_app,
unittest
)
from qgis.PyQt.QtCore import QCoreApplication
from utilities import (
getTestFontFamily,
loadTestFonts
)

start_app()


class TestQgsFontUtils(unittest.TestCase):

@classmethod
def setUpClass(cls):
QCoreApplication.setOrganizationName("QGIS_Test")
QCoreApplication.setOrganizationDomain("QGIS_TestPyQgsFontUtils.com")
QCoreApplication.setApplicationName("QGIS_TestPyQgsFontUtils")
QgsSettings().clear()

start_app()

cls._family = getTestFontFamily()
cls._has_style = QgsFontUtils.fontFamilyHasStyle

@@ -88,6 +94,32 @@ def testToFromMimeData(self):
msg = self._family + ' test font Bold Oblique at 14 pt not retrieved from mime data'
self.assertTrue(res, msg)

def testRecentFonts(self):
"""
Test adding and retrieving recent fonts
"""

# test empty list
self.assertFalse(QgsFontUtils.recentFontFamilies())
QgsFontUtils.addRecentFontFamily('Comic Sans FTW, suckers')
self.assertEqual(QgsFontUtils.recentFontFamilies(), ['Comic Sans FTW, suckers'])
QgsFontUtils.addRecentFontFamily('Arial')
self.assertEqual(QgsFontUtils.recentFontFamilies(), ['Arial', 'Comic Sans FTW, suckers'])
QgsFontUtils.addRecentFontFamily('Arial2')
QgsFontUtils.addRecentFontFamily('Arial3')
QgsFontUtils.addRecentFontFamily('Arial4')
QgsFontUtils.addRecentFontFamily('Arial5')
QgsFontUtils.addRecentFontFamily('Arial6')
QgsFontUtils.addRecentFontFamily('Arial7')
QgsFontUtils.addRecentFontFamily('Arial8')
QgsFontUtils.addRecentFontFamily('Arial9')
QgsFontUtils.addRecentFontFamily('Arial10')
self.assertEqual(QgsFontUtils.recentFontFamilies(), ['Arial10', 'Arial9', 'Arial8', 'Arial7', 'Arial6', 'Arial5', 'Arial4', 'Arial3', 'Arial2', 'Arial'])
QgsFontUtils.addRecentFontFamily('Arial9')
self.assertEqual(QgsFontUtils.recentFontFamilies(), ['Arial9', 'Arial10', 'Arial8', 'Arial7', 'Arial6', 'Arial5', 'Arial4', 'Arial3', 'Arial2', 'Arial'])
QgsFontUtils.addRecentFontFamily('Comic Sans FTW, suckers')
self.assertEqual(QgsFontUtils.recentFontFamilies(), ['Comic Sans FTW, suckers', 'Arial9', 'Arial10', 'Arial8', 'Arial7', 'Arial6', 'Arial5', 'Arial4', 'Arial3', 'Arial2'])


if __name__ == '__main__':
unittest.main()

0 comments on commit bacad8c

Please sign in to comment.
You can’t perform that action at this time.