QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsmaplayerstyleguiutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaplayerstyleguiutils.cpp
3  --------------------------------------
4  Date : January 2015
5  Copyright : (C) 2015 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include <QAction>
19 #include <QInputDialog>
20 #include <QMenu>
21 
22 #include "qgslogger.h"
23 #include "qgsmapcanvas.h"
24 #include "qgsmaplayer.h"
26 
27 
29 {
30  static QgsMapLayerStyleGuiUtils sInstance;
31  return &sInstance;
32 }
33 
34 QAction *QgsMapLayerStyleGuiUtils::actionAddStyle( QgsMapLayer *layer, QObject *parent )
35 {
36  QAction *a = new QAction( tr( "Add…" ), parent );
37  a->setData( QVariant::fromValue<QObject *>( layer ) );
38  connect( a, &QAction::triggered, this, &QgsMapLayerStyleGuiUtils::addStyle );
39  return a;
40 }
41 
42 QAction *QgsMapLayerStyleGuiUtils::actionRemoveStyle( QgsMapLayer *layer, QObject *parent )
43 {
44  QAction *a = new QAction( tr( "Remove Current" ), parent );
45  connect( a, &QAction::triggered, this, &QgsMapLayerStyleGuiUtils::removeStyle );
46  a->setData( QVariant::fromValue<QObject *>( layer ) );
47  a->setEnabled( layer->styleManager()->styles().count() > 1 );
48  return a;
49 }
50 
51 QAction *QgsMapLayerStyleGuiUtils::actionRenameStyle( QgsMapLayer *layer, QObject *parent )
52 {
53  QAction *a = new QAction( tr( "Rename Current…" ), parent );
54  connect( a, &QAction::triggered, this, &QgsMapLayerStyleGuiUtils::renameStyle );
55  a->setData( QVariant::fromValue<QObject *>( layer ) );
56  return a;
57 }
58 
59 QList<QAction *> QgsMapLayerStyleGuiUtils::actionsUseStyle( QgsMapLayer *layer, QObject *parent )
60 {
61  QgsMapLayerStyleManager *mgr = layer->styleManager();
62  bool onlyOneStyle = mgr->styles().count() == 1;
63 
64  QList<QAction *> actions;
65  QActionGroup *styleGroup = new QActionGroup( parent );
66  const auto constStyles = mgr->styles();
67  for ( const QString &name : constStyles )
68  {
69  bool active = name == mgr->currentStyle();
70  QAction *actionUse = new QAction( name, styleGroup );
71  connect( actionUse, &QAction::triggered, this, &QgsMapLayerStyleGuiUtils::useStyle );
72  actionUse->setCheckable( true );
73  actionUse->setChecked( active );
74  actionUse->setEnabled( !onlyOneStyle );
75 
76  actionUse->setData( QVariant::fromValue<QObject *>( layer ) );
77  actions << actionUse;
78  }
79  return actions;
80 }
81 
83 {
84  if ( ! layer )
85  return;
86 
87  m->addAction( actionAddStyle( layer, m ) );
88  if ( layer->styleManager()->styles().count() > 1 )
89  m->addAction( actionRemoveStyle( layer, m ) );
90  m->addAction( actionRenameStyle( layer, m ) );
91  m->addSeparator();
92  const auto actions {actionsUseStyle( layer, m )};
93  for ( QAction *a : actions )
94  m->addAction( a );
95 }
96 
98 {
99  if ( !m )
100  return;
101 
102  // Get rid of previously added style manager actions (they are dynamic)
103  bool gotFirstSeparator = false;
104  QList<QAction *> actions = m->actions();
105  for ( int i = 0; i < actions.count(); ++i )
106  {
107  if ( actions[i]->isSeparator() )
108  {
109  if ( gotFirstSeparator )
110  {
111  // remove all actions after second separator (including it)
112  while ( actions.count() != i )
113  delete actions.takeAt( i );
114  break;
115  }
116  else
117  gotFirstSeparator = true;
118  }
119  }
120 
121 }
122 
123 void QgsMapLayerStyleGuiUtils::addStyle()
124 {
125  QAction *a = qobject_cast<QAction *>( sender() );
126  if ( !a )
127  return;
128  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( a->data().value<QObject *>() );
129  if ( !layer )
130  return;
131 
132  bool ok;
133  QString text = QInputDialog::getText( nullptr, tr( "New Style" ),
134  tr( "Style name:" ), QLineEdit::Normal,
135  QStringLiteral( "new style" ), &ok );
136  if ( !ok || text.isEmpty() )
137  return;
138 
139  bool res = layer->styleManager()->addStyleFromLayer( text );
140 
141  if ( res ) // make it active!
142  {
143  layer->styleManager()->setCurrentStyle( text );
144  }
145  else
146  {
147  QgsDebugMsg( "Failed to add style: " + text );
148  }
149 }
150 
151 void QgsMapLayerStyleGuiUtils::useStyle()
152 {
153  QAction *a = qobject_cast<QAction *>( sender() );
154  if ( !a )
155  return;
156  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( a->data().value<QObject *>() );
157  if ( !layer )
158  return;
159  QString name = a->text();
160 
161  bool res = layer->styleManager()->setCurrentStyle( name );
162  if ( !res )
163  {
164  QgsDebugMsg( "Failed to set current style: " + name );
165  }
166 }
167 
168 
169 void QgsMapLayerStyleGuiUtils::removeStyle()
170 {
171  QAction *a = qobject_cast<QAction *>( sender() );
172  if ( !a )
173  return;
174  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( a->data().value<QObject *>() );
175  if ( !layer )
176  return;
177 
178  bool res = layer->styleManager()->removeStyle( layer->styleManager()->currentStyle() );
179  if ( !res )
180  {
181  QgsDebugMsg( QStringLiteral( "Failed to remove current style" ) );
182  }
183 }
184 
185 
186 void QgsMapLayerStyleGuiUtils::renameStyle()
187 {
188  QAction *a = qobject_cast<QAction *>( sender() );
189  if ( !a )
190  return;
191  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( a->data().value<QObject *>() );
192  if ( !layer )
193  return;
194 
195  QString name = layer->styleManager()->currentStyle();
196 
197  bool ok;
198  QString text = QInputDialog::getText( nullptr, tr( "Rename Style" ),
199  tr( "Style name:" ), QLineEdit::Normal,
200  name, &ok );
201  if ( !ok )
202  return;
203 
204  bool res = layer->styleManager()->renameStyle( name, text );
205  if ( !res )
206  {
207  QgsDebugMsg( "Failed to rename style: " + name );
208  }
209 }
Various GUI utility functions for dealing with map layer's style manager.
void removesExtraMenuSeparators(QMenu *m)
removes extra separators from the menu
void addStyleManagerActions(QMenu *m, QgsMapLayer *layer)
adds actions to the menu in accordance to the layer
static QgsMapLayerStyleGuiUtils * instance()
returns a singleton instance of this class
Management of styles for use with one map layer.
QString currentStyle() const
Returns name of the current style.
bool removeStyle(const QString &name)
Remove a stored style.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
bool addStyleFromLayer(const QString &name)
Add style by cloning the current one.
bool renameStyle(const QString &name, const QString &newName)
Rename a stored style to a different name.
Base class for all map layer types.
Definition: qgsmaplayer.h:70
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38