QGIS API Documentation  3.2.0-Bonn (bc43194)
qgsguiutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsguiutils.cpp - Constants used throughout the QGIS GUI.
3  --------------------------------------
4  Date : 11-Jan-2006
5  Copyright : (C) 2006 by Tom Elwertowski
6  Email : telwertowski at users dot sourceforge dot net
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 #include "qgsguiutils.h"
16 
17 #include "qgssettings.h"
18 #include "qgsencodingfiledialog.h"
19 #include "qgslogger.h"
20 #include "qgis_gui.h"
21 
22 #include <QImageWriter>
23 #include <QFontDialog>
24 #include <QApplication>
25 
26 
27 namespace QgsGuiUtils
28 {
29 
30  bool GUI_EXPORT openFilesRememberingFilter( QString const &filterName,
31  QString const &filters, QStringList &selectedFiles, QString &enc, QString &title,
32  bool cancelAll )
33  {
34  Q_UNUSED( enc );
35 
36  QgsSettings settings;
37  QString lastUsedFilter = settings.value( "/UI/" + filterName, "" ).toString();
38  QString lastUsedDir = settings.value( "/UI/" + filterName + "Dir", QDir::homePath() ).toString();
39 
40  QgsDebugMsg( "Opening file dialog with filters: " + filters );
41  if ( !cancelAll )
42  {
43  selectedFiles = QFileDialog::getOpenFileNames( nullptr, title, lastUsedDir, filters, &lastUsedFilter );
44  }
45  else //we have to use non-native dialog to add cancel all button
46  {
47  QgsEncodingFileDialog *openFileDialog = new QgsEncodingFileDialog( nullptr, title, lastUsedDir, filters, QString() );
48 
49  // allow for selection of more than one file
50  openFileDialog->setFileMode( QFileDialog::ExistingFiles );
51 
52  if ( !lastUsedFilter.isEmpty() )
53  {
54  openFileDialog->selectNameFilter( lastUsedFilter );
55  }
56  openFileDialog->addCancelAll();
57  if ( openFileDialog->exec() == QDialog::Accepted )
58  {
59  selectedFiles = openFileDialog->selectedFiles();
60  }
61  else
62  {
63  //cancel or cancel all?
64  if ( openFileDialog->cancelAll() )
65  {
66  return true;
67  }
68  }
69  }
70 
71  if ( !selectedFiles.isEmpty() )
72  {
73  // Fix by Tim - getting the dirPath from the dialog
74  // directly truncates the last node in the dir path.
75  // This is a workaround for that
76  QString firstFileName = selectedFiles.first();
77  QFileInfo fi( firstFileName );
78  QString path = fi.path();
79 
80  QgsDebugMsg( "Writing last used dir: " + path );
81 
82  settings.setValue( "/UI/" + filterName, lastUsedFilter );
83  settings.setValue( "/UI/" + filterName + "Dir", path );
84  }
85  return false;
86  }
87 
88  QPair<QString, QString> GUI_EXPORT getSaveAsImageName( QWidget *parent, const QString &message, const QString &defaultFilename )
89  {
90  // get a list of supported output image types
91  QMap<QString, QString> filterMap;
92  Q_FOREACH ( const QByteArray &format, QImageWriter::supportedImageFormats() )
93  {
94  //svg doesn't work so skip it
95  if ( format == "svg" )
96  continue;
97 
98  filterMap.insert( createFileFilter_( format ), format );
99  }
100 
101 #ifdef QGISDEBUG
102  QgsDebugMsg( "Available Filters Map: " );
103  for ( QMap<QString, QString>::iterator it = filterMap.begin(); it != filterMap.end(); ++it )
104  {
105  QgsDebugMsg( it.key() + " : " + it.value() );
106  }
107 #endif
108 
109  QgsSettings settings; // where we keep last used filter in persistent state
110  QString lastUsedDir = settings.value( QStringLiteral( "UI/lastSaveAsImageDir" ), QDir::homePath() ).toString();
111 
112  // Prefer "png" format unless the user previously chose a different format
113  QString pngExtension = QStringLiteral( "png" );
114  QString pngFilter = createFileFilter_( pngExtension );
115  QString selectedFilter = settings.value( QStringLiteral( "UI/lastSaveAsImageFilter" ), pngFilter ).toString();
116 
117  QString initialPath;
118  if ( defaultFilename.isNull() )
119  {
120  //no default filename provided, just use last directory
121  initialPath = lastUsedDir;
122  }
123  else
124  {
125  //a default filename was provided, so use it to build the initial path
126  initialPath = QDir( lastUsedDir ).filePath( defaultFilename );
127  }
128 
129  QString outputFileName;
130  QString ext;
131 #if defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_LINUX)
132  outputFileName = QFileDialog::getSaveFileName( parent, message, initialPath, QStringList( filterMap.keys() ).join( QStringLiteral( ";;" ) ), &selectedFilter );
133 
134  if ( !outputFileName.isNull() )
135  {
136  ext = filterMap.value( selectedFilter, QString() );
137  if ( !ext.isNull() )
138  settings.setValue( QStringLiteral( "UI/lastSaveAsImageFilter" ), selectedFilter );
139  settings.setValue( QStringLiteral( "UI/lastSaveAsImageDir" ), QFileInfo( outputFileName ).absolutePath() );
140  }
141 #else
142 
143  //create a file dialog using the filter list generated above
144  std::unique_ptr<QFileDialog> fileDialog( new QFileDialog( parent, message, initialPath, QStringList( filterMap.keys() ).join( ";;" ) ) );
145 
146  // allow for selection of more than one file
147  fileDialog->setFileMode( QFileDialog::AnyFile );
148  fileDialog->setAcceptMode( QFileDialog::AcceptSave );
149  fileDialog->setOption( QFileDialog::DontConfirmOverwrite, false );
150 
151  if ( !selectedFilter.isEmpty() ) // set the filter to the last one used
152  {
153  fileDialog->selectNameFilter( selectedFilter );
154  }
155 
156  //prompt the user for a fileName
157  if ( fileDialog->exec() == QDialog::Accepted )
158  {
159  outputFileName = fileDialog->selectedFiles().first();
160  }
161 
162  selectedFilter = fileDialog->selectedNameFilter();
163  QgsDebugMsg( "Selected filter: " + selectedFilter );
164  ext = filterMap.value( selectedFilter, QString() );
165 
166  if ( !ext.isNull() )
167  settings.setValue( "/UI/lastSaveAsImageFilter", selectedFilter );
168 
169  settings.setValue( "/UI/lastSaveAsImageDir", fileDialog->directory().absolutePath() );
170 #endif
171 
172  // Add the file type suffix to the fileName if required
173  if ( !ext.isNull() && !outputFileName.endsWith( '.' + ext.toLower(), Qt::CaseInsensitive ) )
174  {
175  outputFileName += '.' + ext;
176  }
177 
178  return qMakePair<QString, QString>( outputFileName, ext );
179  }
180 
181  QString createFileFilter_( QString const &longName, QString const &glob )
182  {
183  return QStringLiteral( "%1 (%2 %3)" ).arg( longName, glob.toLower(), glob.toUpper() );
184  }
185 
186  QString createFileFilter_( QString const &format )
187  {
188  QString longName = format.toUpper() + " format";
189  QString glob = "*." + format;
190  return createFileFilter_( longName, glob );
191  }
192 
193  QFont getFont( bool &ok, const QFont &initial, const QString &title )
194  {
195  // parent is intentionally not set to 'this' as
196  // that would make it follow the style sheet font
197  // see also #12233 and #4937
198 #if defined(Q_OS_MAC) && defined(QT_MAC_USE_COCOA)
199  // Native Mac dialog works only for Qt Carbon
200  return QFontDialog::getFont( &ok, initial, 0, title, QFontDialog::DontUseNativeDialog );
201 #else
202  return QFontDialog::getFont( &ok, initial, nullptr, title );
203 #endif
204  }
205 
206  void saveGeometry( QWidget *widget, const QString &keyName )
207  {
208  QgsSettings settings;
209  QString key = createWidgetKey( widget, keyName );
210  settings.setValue( key, widget->saveGeometry() );
211  }
212 
213  bool restoreGeometry( QWidget *widget, const QString &keyName )
214  {
215  QgsSettings settings;
216  QString key = createWidgetKey( widget, keyName );
217  return widget->restoreGeometry( settings.value( key ).toByteArray() );
218  }
219 
220  QString createWidgetKey( QWidget *widget, const QString &keyName )
221  {
222  QString subKey;
223  if ( !keyName.isEmpty() )
224  {
225  subKey = keyName;
226  }
227  else if ( widget->objectName().isEmpty() )
228  {
229  subKey = QString( widget->metaObject()->className() );
230  }
231  else
232  {
233  subKey = widget->objectName();
234  }
235  QString key = QStringLiteral( "Windows/%1/geometry" ).arg( subKey );
236  return key;
237  }
238 }
239 
240 //
241 // QgsTemporaryCursorOverride
242 //
243 
245 {
246  QApplication::setOverrideCursor( cursor );
247 }
248 
250 {
251  if ( mHasOverride )
252  QApplication::restoreOverrideCursor();
253 }
254 
256 {
257  if ( !mHasOverride )
258  return;
259 
260  mHasOverride = false;
261  QApplication::restoreOverrideCursor();
262 }
A file dialog which lets the user select the preferred encoding type for a data provider.
QString createFileFilter_(QString const &longName, QString const &glob)
Convenience function for readily creating file filters.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QPair< QString, QString > GUI_EXPORT getSaveAsImageName(QWidget *parent, const QString &message, const QString &defaultFilename)
A helper function to get an image name from the user.
Definition: qgsguiutils.cpp:88
void saveGeometry(QWidget *widget, const QString &keyName)
Save the wigget geometry into settings.
bool restoreGeometry(QWidget *widget, const QString &keyName)
Restore the wigget geometry from settings.
The QgsGuiUtils namespace contains constants and helper functions used throughout the QGIS GUI...
Definition: qgsguiutils.cpp:27
void addCancelAll()
Adds a &#39;Cancel All&#39; button for the user to click.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
void release()
Releases the cursor override early (i.e.
bool cancelAll()
Returns true if the user clicked &#39;Cancel All&#39;.
QString createWidgetKey(QWidget *widget, const QString &keyName)
Creates a key for the given widget that can be used to store related data in settings.
QgsTemporaryCursorOverride(const QCursor &cursor)
Constructor for QgsTemporaryCursorOverride.
bool GUI_EXPORT openFilesRememberingFilter(QString const &filterName, QString const &filters, QStringList &selectedFiles, QString &enc, QString &title, bool cancelAll)
Open files, preferring to have the default file selector be the last one used, if any; also...
Definition: qgsguiutils.cpp:30
QFont getFont(bool &ok, const QFont &initial, const QString &title)
Show font selection dialog.