169 changes: 169 additions & 0 deletions src/app/qgisappstylesheet.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/***************************************************************************
qgisappstylesheet.cpp
----------------------
begin : Jan 18, 2013
copyright : (C) 2013 by Larry Shaffer
email : larrys at dakotacarto dot com
***************************************************************************/

/***************************************************************************
* *
* 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgisappstylesheet.h"
#include "qgsapplication.h"
#include "qgslogger.h"

#include <QFont>
#include <QSettings>

/** @class QgisAppStyleSheet
* @brief Adjustable stylesheet for the Qgis application
*/

QgisAppStyleSheet::QgisAppStyleSheet( QObject *parent )
: QObject( parent )
{
// platforms, specific
#ifdef Q_OS_LINUX
mLinuxOS = true;
#else
mLinuxOS = false;
#endif
#ifdef Q_OS_WIN32
mWinOS = true;
#else
mWinOS = false;
#endif
#ifdef Q_OS_MAC
mMacOS = true;
#else
mMacOS = false;
#endif
#ifdef ANDROID
mAndroidOS = true;
#else
mAndroidOS = false;
#endif

// platforms, general
#ifdef Q_OS_UNIX
mUnix = true;
#else
mUnix = false;
#endif

// window servers
#ifdef Q_WS_X11
mX11WS = true;
#else
mX11WS = false;
#endif
#ifdef Q_WS_WIN
mWinWS = true;
#else
mWinWS = false;
#endif
#ifdef Q_WS_MAC
mMacWS = true;
#else
mMacWS = false;
#endif
}

QgisAppStyleSheet::~QgisAppStyleSheet()
{
}

QMap<QString, QVariant> QgisAppStyleSheet::defaultOptions()
{
QMap<QString, QVariant> opts;
mDefaultFont = qApp->font(); // save before it is changed in any way

// the following default values, before insertion in opts, can be
// configured using the platform(s) and window server(s) defined in the
// constructor to set reasonable non-Qt defaults for the app stylesheet
QSettings settings;
// handle move from old QSettings group (/) to new (/qgis/stylesheet)
// NOTE: don't delete old QSettings keys, in case user is also running older QGIS
QVariant oldFontPointSize = settings.value( "/fontPointSize" );
QVariant oldFontFamily = settings.value( "/fontFamily" );

settings.beginGroup( "qgis/stylesheet" );

int fontSize = mDefaultFont.pointSize();
if ( mAndroidOS )
{
// TODO: find a better default fontsize maybe using DPI detection or so (from Marco Bernasocchi commit)
fontSize = 8;
}
if ( oldFontPointSize.isValid() && !settings.value( "fontPointSize" ).isValid() )
{
fontSize = oldFontPointSize.toInt();
}
QgsDebugMsg( QString( "fontPointSize: %1" ).arg( fontSize ) );
opts.insert( "fontPointSize", settings.value( "fontPointSize", QVariant( fontSize ) ) );

QString fontFamily = mDefaultFont.family();
if ( oldFontFamily.isValid() && !settings.value( "fontFamily" ).isValid() )
{
fontFamily = oldFontFamily.toString();
}
fontFamily = settings.value( "fontFamily", QVariant( fontFamily ) ).toString();
// make sure family exists on system
if ( fontFamily != mDefaultFont.family() )
{
QFont *tempFont = new QFont( fontFamily );
if ( tempFont->family() != fontFamily )
{
// missing from system, drop back to default
fontFamily = mDefaultFont.family();
}
delete tempFont;
}
QgsDebugMsg( QString( "fontFamily: %1" ).arg( fontFamily ) );
opts.insert( "fontFamily", QVariant( fontFamily ) );

settings.endGroup();

return opts;
}

void QgisAppStyleSheet::buildStyleSheet( const QMap<QString, QVariant>& opts )
{
QString ss = QString( "" );

QString fontSize = opts.value( "fontPointSize" ).toString();
QgsDebugMsg( QString( "fontPointSize: %1" ).arg( fontSize ) );
if ( fontSize.isEmpty() ) { return; }

QString fontFamily = opts.value( "fontFamily" ).toString();
QgsDebugMsg( QString( "fontFamily: %1" ).arg( fontFamily ) );
if ( fontFamily.isEmpty() ) { return; }

ss += QString( "* { font: %1pt \"%2\"} " ).arg( fontSize ).arg( fontFamily );

QgsDebugMsg( QString( "Stylesheet built: %1" ).arg( ss ) );

emit appStyleSheetChanged( ss );
}

void QgisAppStyleSheet::saveToSettings( const QMap<QString, QVariant>& opts )
{
QSettings settings;
settings.beginGroup( "qgis/stylesheet" );

QMap<QString, QVariant>::const_iterator opt = opts.constBegin();
while ( opt != opts.constEnd() )
{
settings.setValue( QString( opt.key() ), opt.value() );
++opt;
}
settings.endGroup();
}
76 changes: 76 additions & 0 deletions src/app/qgisappstylesheet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/***************************************************************************
qgisappstylesheet.h
----------------------
begin : Jan 18, 2013
copyright : (C) 2013 by Larry Shaffer
email : larrys at dakotacarto dot com
***************************************************************************/

/***************************************************************************
* *
* 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGISAPPSTYLESHEET_H
#define QGISAPPSTYLESHEET_H

#include <QObject>
#include <QFont>
#include <QMap>

/** @class QgisAppStyleSheet
* @brief Adjustable stylesheet for the Qgis application
*/
class QgisAppStyleSheet: public QObject
{
Q_OBJECT

public:
QgisAppStyleSheet( QObject * parent = 0 );
~QgisAppStyleSheet();

/** Return changeable options built from settings and/or defaults */
QMap<QString, QVariant> defaultOptions();

/** Generate stylesheet
* @param opts generated default option values, or a changed copy of them
* @note on success emits appStyleSheetChanged
*/
void buildStyleSheet( const QMap<QString, QVariant>& opts );

/** Save changed default option keys/values to user settings */
void saveToSettings( const QMap<QString, QVariant>& opts );

/** Get reference font for initial qApp */
QFont defaultFont() { return mDefaultFont; }

signals:
/** Signal the successful stylesheet build results
* @note connect to (app|widget)->setStyleSheet or similar custom slot
*/
void appStyleSheetChanged( const QString& appStyleSheet );

private:
// platforms, specific
bool mLinuxOS;
bool mWinOS;
bool mMacOS;
bool mAndroidOS;

// platforms, general
bool mUnix;

// window servers
bool mX11WS;
bool mWinWS;
bool mMacWS;

// default font saved for reference
QFont mDefaultFont;
};

#endif //QGISAPPSTYLESHEET_H
95 changes: 56 additions & 39 deletions src/app/qgsoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "qgsoptions.h"
#include "qgis.h"
#include "qgisapp.h"
#include "qgisappstylesheet.h"
#include "qgsmapcanvas.h"
#include "qgsmaprenderer.h"
#include "qgsgenericprojectionselector.h"
Expand Down Expand Up @@ -70,6 +71,11 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
{
setupUi( this );

// stylesheet setup
mStyleSheetBuilder = QgisApp::instance()->styleSheetBuilder();
mStyleSheetNewOpts = mStyleSheetBuilder->defaultOptions();
mStyleSheetOldOpts = QMap<QString, QVariant>( mStyleSheetNewOpts );

connect( mOptionsSplitter, SIGNAL( splitterMoved( int, int ) ), this, SLOT( updateVerticalTabs() ) );

connect( cmbTheme, SIGNAL( activated( const QString& ) ), this, SLOT( themeChanged( const QString& ) ) );
Expand All @@ -80,11 +86,6 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
connect( cmbIconSize, SIGNAL( highlighted( const QString& ) ), this, SLOT( iconSizeChanged( const QString& ) ) );
connect( cmbIconSize, SIGNAL( textChanged( const QString& ) ), this, SLOT( iconSizeChanged( const QString& ) ) );

connect( spinFontSize, SIGNAL( valueChanged( const QString& ) ), this, SLOT( updateAppStyleSheet() ) );
connect( mFontFamilyRadioQt, SIGNAL( released() ), this, SLOT( updateAppStyleSheet() ) );
connect( mFontFamilyRadioCustom, SIGNAL( released() ), this, SLOT( updateAppStyleSheet() ) );
connect( mFontFamilyComboBox, SIGNAL( currentFontChanged( const QFont& ) ), this, SLOT( updateAppStyleSheet() ) );

#ifdef Q_WS_X11
connect( chkEnableBackbuffer, SIGNAL( stateChanged( int ) ), this, SLOT( toggleEnableBackbuffer( int ) ) );
#endif
Expand Down Expand Up @@ -449,17 +450,17 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
cmbIconSize->setCurrentIndex( cmbIconSize->findText( settings.value( "/IconSize", QGIS_ICON_SIZE ).toString() ) );

// set font size and family
// TODO: move all stylesheet options blockSignals to separate method when implementing app stylesheet
spinFontSize->blockSignals( true );
mFontFamilyRadioQt->blockSignals( true );
mFontFamilyRadioCustom->blockSignals( true );
mFontFamilyComboBox->blockSignals( true );

spinFontSize->setValue( settings.value( "/fontPointSize", QGIS_DEFAULT_FONTSIZE ).toInt() );
QString fontFamily = settings.value( "/fontFamily", QVariant( "QtDefault" ) ).toString();
bool isQtDefault = ( fontFamily == QString( "QtDefault" ) );
spinFontSize->setValue( mStyleSheetNewOpts.value( "fontPointSize" ).toInt() );
QString fontFamily = mStyleSheetNewOpts.value( "fontFamily" ).toString();
bool isQtDefault = ( fontFamily == mStyleSheetBuilder->defaultFont().family() );
mFontFamilyRadioQt->setChecked( isQtDefault );
mFontFamilyRadioCustom->setChecked( !isQtDefault );
mFontFamilyComboBox->setEnabled( !isQtDefault );
if ( !isQtDefault )
{
QFont *tempFont = new QFont( fontFamily );
Expand All @@ -470,6 +471,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
}
delete tempFont;
}

spinFontSize->blockSignals( false );
mFontFamilyRadioQt->blockSignals( false );
mFontFamilyRadioCustom->blockSignals( false );
Expand Down Expand Up @@ -890,25 +892,6 @@ void QgsOptions::iconSizeChanged( const QString &iconSize )
QgisApp::instance()->setIconSizes( iconSize.toInt() );
}

void QgsOptions::updateAppStyleSheet()
{
int fontSize = spinFontSize->value();

QString family = QString( "" ); // use default Qt font family
if ( mFontFamilyRadioCustom->isChecked() )
{
family = QString( " \"%1\";" ).arg( mFontFamilyComboBox->currentFont().family() );
}

QString stylesheet = QString( "font: %1pt%2" ).arg( fontSize ).arg( family );
QgisApp::instance()->setStyleSheet( stylesheet );

foreach ( QgsComposer* c, QgisApp::instance()->printComposers() )
{
c->setAppStyleSheet();
}
}

void QgsOptions::toggleEnableBackbuffer( int state )
{
#ifdef Q_WS_X11
Expand Down Expand Up @@ -1091,16 +1074,6 @@ void QgsOptions::saveOptions()

settings.setValue( "/IconSize", cmbIconSize->currentText() );

// application stylesheet settings
settings.setValue( "/fontPointSize", spinFontSize->value() );
QString fontFamily = QString( "QtDefault" );
if ( mFontFamilyRadioCustom->isChecked() )
{
fontFamily = mFontFamilyComboBox->currentFont().family();
}
settings.setValue( "/fontFamily", fontFamily );
QgisApp::instance()->setAppStyleSheet();

settings.setValue( "/qgis/messageTimeout", mMessageTimeoutSpnBx->value() );

// rasters settings
Expand Down Expand Up @@ -1255,11 +1228,55 @@ void QgsOptions::saveOptions()
// Gdal skip driver list
if ( mLoadedGdalDriverList )
saveGdalDriverList();

// save app stylesheet last (in case reset becomes necessary)
if ( mStyleSheetNewOpts != mStyleSheetOldOpts )
{
mStyleSheetBuilder->saveToSettings( mStyleSheetNewOpts );
}
}

void QgsOptions::rejectOptions()
{
QgisApp::instance()->setAppStyleSheet();
// don't reset stylesheet if we don't have to
if ( mStyleSheetNewOpts != mStyleSheetOldOpts )
{
mStyleSheetBuilder->buildStyleSheet( mStyleSheetOldOpts );
}
}

void QgsOptions::on_spinFontSize_valueChanged( int fontSize )
{
mStyleSheetNewOpts.insert( "fontPointSize", fontSize );
mStyleSheetBuilder->buildStyleSheet( mStyleSheetNewOpts );
}

void QgsOptions::on_mFontFamilyRadioQt_released()
{
if ( mStyleSheetNewOpts.value( "fontFamily" ).toString() != mStyleSheetBuilder->defaultFont().family() )
{
mStyleSheetNewOpts.insert( "fontFamily", mStyleSheetBuilder->defaultFont().family() );
mStyleSheetBuilder->buildStyleSheet( mStyleSheetNewOpts );
}
}

void QgsOptions::on_mFontFamilyRadioCustom_released()
{
if ( mFontFamilyComboBox->currentFont().family() != mStyleSheetBuilder->defaultFont().family() )
{
mStyleSheetNewOpts.insert( "fontFamily", mFontFamilyComboBox->currentFont().family() );
mStyleSheetBuilder->buildStyleSheet( mStyleSheetNewOpts );
}
}

void QgsOptions::on_mFontFamilyComboBox_currentFontChanged( const QFont& font )
{
if ( mFontFamilyRadioCustom->isChecked()
&& mStyleSheetNewOpts.value( "fontFamily" ).toString() != font.family() )
{
mStyleSheetNewOpts.insert( "fontFamily", font.family() );
mStyleSheetBuilder->buildStyleSheet( mStyleSheetNewOpts );
}
}

void QgsOptions::on_pbnSelectProjection_clicked()
Expand Down
31 changes: 26 additions & 5 deletions src/app/qgsoptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "ui_qgsoptionsbase.h"
#include "qgisgui.h"
#include "qgisapp.h"
#include "qgisappstylesheet.h"
#include "qgscontexthelp.h"

#include <qgscoordinatereferencesystem.h>
Expand Down Expand Up @@ -75,11 +76,6 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
void themeChanged( const QString & );

void iconSizeChanged( const QString &iconSize );
/*!
* Slot to temporarily apply settings to app stylesheet
* @note added in QGIS 2.0
*/
void updateAppStyleSheet();

//! Slot to change backbuffering. This is handled when the user changes
// the value of the checkbox
Expand All @@ -91,6 +87,27 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
* true.
*/
bool newVisible();

/** Slot to select the default font point size for app
* @note added in QGIS 1.9
*/
void on_spinFontSize_valueChanged( int fontSize );

/** Slot to set font family for app to Qt default
* @note added in QGIS 1.9
*/
void on_mFontFamilyRadioQt_released();

/** Slot to set font family for app to custom choice
* @note added in QGIS 1.9
*/
void on_mFontFamilyRadioCustom_released();

/** Slot to select custom font family choice for app
* @note added in QGIS 1.9
*/
void on_mFontFamilyComboBox_currentFontChanged( const QFont& font );

/*!
* Slot to select the default map selection color
*/
Expand Down Expand Up @@ -230,6 +247,10 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
protected:
void showEvent( QShowEvent * e );
void paintEvent( QPaintEvent * e );

QgisAppStyleSheet* mStyleSheetBuilder;
QMap<QString, QVariant> mStyleSheetNewOpts;
QMap<QString, QVariant> mStyleSheetOldOpts;
};

#endif // #ifndef QGSOPTIONS_H
33 changes: 22 additions & 11 deletions src/gui/qgisinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class QgsFeature;
class QgsMessageBar;

#include <QObject>
#include <QFont>
#include <QPair>
#include <map>

Expand Down Expand Up @@ -77,17 +78,6 @@ class GUI_EXPORT QgisInterface : public QObject
public slots: // TODO: do these functions really need to be slots?

/* Exposed functions */
/** Set the app font size
* @param fontSize point size of font
* @note added in 2.0
*/
virtual void setFontSize( int fontSize ) = 0;

/** Set the app font family
* @param fontFamily family of font (not including any style)
* @note added in 2.0
*/
virtual void setFontFamily( QString fontFamily ) = 0;

//! Zoom to full extent of map layers
virtual void zoomFull() = 0;
Expand Down Expand Up @@ -176,6 +166,27 @@ class GUI_EXPORT QgisInterface : public QObject
/**Return mainwindows / composer views of running composer instances (currently only one)*/
virtual QList<QgsComposerView*> activeComposers() = 0;

/** Return changeable options built from settings and/or defaults
* @note (added in 1.9)
*/
virtual QMap<QString, QVariant> defaultStyleSheetOptions() = 0;

/** Generate stylesheet
* @param opts generated default option values, or a changed copy of them
* @note added in 1.9
*/
virtual void buildStyleSheet( const QMap<QString, QVariant>& opts ) = 0;

/** Save changed default option keys/values to user settings
* @note added in 1.9
*/
virtual void saveStyleSheetOptions( const QMap<QString, QVariant>& opts ) = 0;

/** Get reference font for initial qApp (may not be same as QgisApp)
* @note added in 1.9
*/
virtual QFont defaultStyleSheetFont() = 0;

/** Add action to the plugins menu */
virtual void addPluginToMenu( QString name, QAction* action ) = 0;

Expand Down