QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 #include <QActionGroup>
22 
23 #include "qgslogger.h"
24 #include "qgsmapcanvas.h"
25 #include "qgsmaplayer.h"
27 
28 
30 {
31  static QgsMapLayerStyleGuiUtils sInstance;
32  return &sInstance;
33 }
34 
35 QAction *QgsMapLayerStyleGuiUtils::actionAddStyle( QgsMapLayer *layer, QObject *parent )
36 {
37  QAction *a = new QAction( tr( "Add…" ), parent );
38  a->setData( QVariant::fromValue<QObject *>( layer ) );
39  connect( a, &QAction::triggered, this, &QgsMapLayerStyleGuiUtils::addStyle );
40  return a;
41 }
42 
43 QAction *QgsMapLayerStyleGuiUtils::actionRemoveStyle( QgsMapLayer *layer, QObject *parent )
44 {
45  QAction *a = new QAction( tr( "Remove Current" ), parent );
46  connect( a, &QAction::triggered, this, &QgsMapLayerStyleGuiUtils::removeStyle );
47  a->setData( QVariant::fromValue<QObject *>( layer ) );
48  a->setEnabled( layer->styleManager()->styles().count() > 1 );
49  return a;
50 }
51 
52 QAction *QgsMapLayerStyleGuiUtils::actionRenameStyle( QgsMapLayer *layer, QObject *parent )
53 {
54  QAction *a = new QAction( tr( "Rename Current…" ), parent );
55  connect( a, &QAction::triggered, this, &QgsMapLayerStyleGuiUtils::renameStyle );
56  a->setData( QVariant::fromValue<QObject *>( layer ) );
57  return a;
58 }
59 
60 QList<QAction *> QgsMapLayerStyleGuiUtils::actionsUseStyle( QgsMapLayer *layer, QObject *parent )
61 {
62  QgsMapLayerStyleManager *mgr = layer->styleManager();
63  const bool onlyOneStyle = mgr->styles().count() == 1;
64 
65  QList<QAction *> actions;
66  QActionGroup *styleGroup = new QActionGroup( parent );
67  const auto constStyles = mgr->styles();
68  for ( const QString &name : constStyles )
69  {
70  const bool active = name == mgr->currentStyle();
71  QAction *actionUse = new QAction( name, styleGroup );
72  connect( actionUse, &QAction::triggered, this, &QgsMapLayerStyleGuiUtils::useStyle );
73  actionUse->setCheckable( true );
74  actionUse->setChecked( active );
75  actionUse->setEnabled( !onlyOneStyle );
76 
77  actionUse->setData( QVariant::fromValue<QObject *>( layer ) );
78  actions << actionUse;
79  }
80  return actions;
81 }
82 
84 {
85  if ( ! layer )
86  return;
87 
88  m->addAction( actionAddStyle( layer, m ) );
89  if ( layer->styleManager()->styles().count() > 1 )
90  m->addAction( actionRemoveStyle( layer, m ) );
91  m->addAction( actionRenameStyle( layer, m ) );
92  m->addSeparator();
93  const auto actions {actionsUseStyle( layer, m )};
94  for ( QAction *a : actions )
95  m->addAction( a );
96 }
97 
99 {
100  if ( !m )
101  return;
102 
103  // Get rid of previously added style manager actions (they are dynamic)
104  bool gotFirstSeparator = false;
105  QList<QAction *> actions = m->actions();
106  for ( int i = 0; i < actions.count(); ++i )
107  {
108  if ( actions[i]->isSeparator() )
109  {
110  if ( gotFirstSeparator )
111  {
112  // remove all actions after second separator (including it)
113  while ( actions.count() != i )
114  delete actions.takeAt( i );
115  break;
116  }
117  else
118  gotFirstSeparator = true;
119  }
120  }
121 
122 }
123 
124 void QgsMapLayerStyleGuiUtils::addStyle()
125 {
126  QAction *a = qobject_cast<QAction *>( sender() );
127  if ( !a )
128  return;
129  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( a->data().value<QObject *>() );
130  if ( !layer )
131  return;
132 
133  bool ok;
134  const QString text = QInputDialog::getText( nullptr, tr( "New Style" ),
135  tr( "Style name:" ), QLineEdit::Normal,
136  QStringLiteral( "new style" ), &ok );
137  if ( !ok || text.isEmpty() )
138  return;
139 
140  const bool res = layer->styleManager()->addStyleFromLayer( text );
141 
142  if ( res ) // make it active!
143  {
144  layer->styleManager()->setCurrentStyle( text );
145  }
146  else
147  {
148  QgsDebugMsg( "Failed to add style: " + text );
149  }
150 }
151 
152 void QgsMapLayerStyleGuiUtils::useStyle()
153 {
154  QAction *a = qobject_cast<QAction *>( sender() );
155  if ( !a )
156  return;
157  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( a->data().value<QObject *>() );
158  if ( !layer )
159  return;
160  const QString name = a->text();
161 
162  const bool res = layer->styleManager()->setCurrentStyle( name );
163  if ( !res )
164  {
165  QgsDebugMsg( "Failed to set current style: " + name );
166  }
167 }
168 
169 
170 void QgsMapLayerStyleGuiUtils::removeStyle()
171 {
172  QAction *a = qobject_cast<QAction *>( sender() );
173  if ( !a )
174  return;
175  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( a->data().value<QObject *>() );
176  if ( !layer )
177  return;
178 
179  const bool res = layer->styleManager()->removeStyle( layer->styleManager()->currentStyle() );
180  if ( !res )
181  {
182  QgsDebugMsg( QStringLiteral( "Failed to remove current style" ) );
183  }
184 }
185 
186 
187 void QgsMapLayerStyleGuiUtils::renameStyle()
188 {
189  QAction *a = qobject_cast<QAction *>( sender() );
190  if ( !a )
191  return;
192  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( a->data().value<QObject *>() );
193  if ( !layer )
194  return;
195 
196  const QString name = layer->styleManager()->currentStyle();
197 
198  bool ok;
199  const QString text = QInputDialog::getText( nullptr, tr( "Rename Style" ),
200  tr( "Style name:" ), QLineEdit::Normal,
201  name, &ok );
202  if ( !ok )
203  return;
204 
205  const bool res = layer->styleManager()->renameStyle( name, text );
206  if ( !res )
207  {
208  QgsDebugMsg( "Failed to rename style: " + name );
209  }
210 }
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:73
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38