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