25#include <QApplication>
28#include <QImageWriter>
32#include <QRegularExpression>
36using namespace Qt::StringLiterals;
41 bool GUI_EXPORT
openFilesRememberingFilter( QString
const &filterName, QString
const &filters, QStringList &selectedFiles, QString &enc, QString &title,
bool cancelAll )
46 QString lastUsedFilter = settings.
value(
"/UI/" + filterName,
"" ).toString();
47 const QString lastUsedDir = settings.
value(
"/UI/" + filterName +
"Dir", QDir::homePath() ).toString();
52 selectedFiles = QFileDialog::getOpenFileNames(
nullptr, title, lastUsedDir, filters, &lastUsedFilter );
59 openFileDialog->setFileMode( QFileDialog::ExistingFiles );
61 if ( !lastUsedFilter.isEmpty() )
63 openFileDialog->selectNameFilter( lastUsedFilter );
66 if ( openFileDialog->exec() == QDialog::Accepted )
68 selectedFiles = openFileDialog->selectedFiles();
80 if ( !selectedFiles.isEmpty() )
85 const QString firstFileName = selectedFiles.first();
86 const QFileInfo fi( firstFileName );
87 const QString path = fi.path();
91 settings.
setValue(
"/UI/" + filterName, lastUsedFilter );
92 settings.
setValue(
"/UI/" + filterName +
"Dir", path );
97 QPair<QString, QString> GUI_EXPORT
getSaveAsImageName( QWidget *parent,
const QString &message,
const QString &defaultFilename )
100 QMap<QString, QString> filterMap;
101 const auto supportedImageFormats { QImageWriter::supportedImageFormats() };
102 QStringList imageFormats;
104 imageFormats << u
"*.png *.PNG"_s;
105 for (
const QByteArray &format : supportedImageFormats )
108 if ( format ==
"svg" )
115 if ( format !=
"png" )
117 imageFormats << u
"*.%1 *.%2"_s.arg( format, QString( format ).toUpper() );
120 const QString formatByExtension = u
"%1 (%2)"_s.arg( QObject::tr(
"Format by Extension" ), imageFormats.join(
' '_L1 ) );
124 for ( QMap<QString, QString>::iterator it = filterMap.begin(); it != filterMap.end(); ++it )
131 const QString lastUsedDir = settings.
value( u
"UI/lastSaveAsImageDir"_s, QDir::homePath() ).toString();
133 QString selectedFilter = settings.
value( u
"UI/lastSaveAsImageFilter"_s, QString() ).toString();
134 if ( selectedFilter.isEmpty() )
136 selectedFilter = formatByExtension;
140 if ( defaultFilename.isNull() )
143 initialPath = lastUsedDir;
148 initialPath = QDir( lastUsedDir ).filePath( defaultFilename );
151 QString outputFileName;
153#if defined( Q_OS_WIN ) || defined( Q_OS_MAC ) || defined( Q_OS_LINUX )
154 outputFileName = QFileDialog::getSaveFileName( parent, message, initialPath, formatByExtension + u
";;"_s +
qgsMapJoinKeys( filterMap, u
";;"_s ), &selectedFilter );
157 auto fileDialog = std::make_unique<QFileDialog>( parent, message, initialPath, formatByExtension + u
";;"_s +
qgsMapJoinKeys( filterMap, u
";;"_s ) );
160 fileDialog->setFileMode( QFileDialog::AnyFile );
161 fileDialog->setAcceptMode( QFileDialog::AcceptSave );
162 fileDialog->setOption( QFileDialog::DontConfirmOverwrite,
false );
164 if ( !selectedFilter.isEmpty() )
166 fileDialog->selectNameFilter( selectedFilter );
170 if ( fileDialog->exec() == QDialog::Accepted )
172 outputFileName = fileDialog->selectedFiles().first();
176 if ( !outputFileName.isNull() )
178 if ( selectedFilter == formatByExtension )
180 settings.
setValue( u
"UI/lastSaveAsImageFilter"_s, QString() );
181 ext = QFileInfo( outputFileName ).suffix();
183 auto match = std::find_if( filterMap.begin(), filterMap.end(), [&ext](
const QString &filter ) { return filter == ext; } );
184 if ( match == filterMap.end() )
194 ext = filterMap.value( selectedFilter, QString() );
195 if ( !ext.isEmpty() )
198 settings.
setValue( u
"UI/lastSaveAsImageFilter"_s, selectedFilter );
201 settings.
setValue( u
"UI/lastSaveAsImageDir"_s, QFileInfo( outputFileName ).absolutePath() );
204 return qMakePair( outputFileName, ext );
209 return u
"%1 (%2 %3)"_s.arg( longName, glob.toLower(), glob.toUpper() );
214 const QString longName = format.toUpper() +
" format";
215 const QString glob =
"*." + format;
219 QFont
getFont(
bool &ok,
const QFont &initial,
const QString &title )
224#if defined( Q_OS_MAC )
229 return QFontDialog::getFont( &ok, initial,
nullptr, title, QFontDialog::DontUseNativeDialog );
231 return QFontDialog::getFont( &ok, initial,
nullptr, title );
239 settings.
setValue( key, widget->saveGeometry() );
246 return widget->restoreGeometry( settings.
value( key ).toByteArray() );
252 if ( !keyName.isEmpty() )
256 else if ( widget->objectName().isEmpty() )
258 subKey = QString( widget->metaObject()->className() );
262 subKey = widget->objectName();
264 QString key = u
"Windows/%1/geometry"_s.arg( subKey );
275 int adjustedSize = 16;
276 if ( size.width() > 32 )
278 adjustedSize = size.width() - 16;
280 else if ( size.width() == 32 )
284 return QSize( adjustedSize, adjustedSize );
290 QString result { QLocale().toString( value,
'f', precision ) };
291 if ( !displayTrailingZeroes )
293 const QRegularExpression zeroesRe { QStringLiteral( R
"raw(\%1\d*?(0+$))raw" ).arg( QLocale().decimalPoint() ) };
294 if ( zeroesRe.match( result ).hasMatch() )
296 result.truncate( zeroesRe.match( result ).capturedStart( 1 ) );
297 if ( result.endsWith( QLocale().decimalPoint() ) )
308 switch ( rasterDataType )
326 return std::numeric_limits<float>::digits10 + 1;
331 return std::numeric_limits<double>::digits10 + 1;
335 return std::numeric_limits<double>::digits10 + 1;
353 *isNonStandard = nonStandard;
366 return QMessageBox::question(
370 "PolyhedralSurface, TIN and Triangle are non-standard GeoPackage geometry types "
371 "and may not be recognized by other software.\n\n"
372 "Do you want to continue?"
374 QMessageBox::Yes | QMessageBox::No,
380 void addDockWidget( QMainWindow *window, Qt::DockWidgetArea area, QDockWidget *dockwidget )
382 window->addDockWidget( area, dockwidget );
385 window->setCorner( Qt::TopLeftCorner, Qt::LeftDockWidgetArea );
386 window->setCorner( Qt::BottomLeftCorner, Qt::LeftDockWidgetArea );
387 window->setCorner( Qt::TopRightCorner, Qt::RightDockWidgetArea );
388 window->setCorner( Qt::BottomRightCorner, Qt::RightDockWidgetArea );
390 if (
auto menu = window->findChild< QMenu * >( u
"mPanelMenu"_s ) )
392 menu->addAction( dockwidget->toggleViewAction() );
398 void addTabifiedDockWidget( QMainWindow *window, Qt::DockWidgetArea area, QDockWidget *dockWidget,
const QStringList &tabifyWith,
bool raiseTab )
400 QList<QDockWidget *> dockWidgetsInArea;
401 const QList<QDockWidget *> allDockWidgets = window->findChildren<QDockWidget *>();
402 for ( QDockWidget *w : allDockWidgets )
404 if ( w->isVisible() && window->dockWidgetArea( w ) == area )
406 dockWidgetsInArea << w;
411 if ( dockWidgetsInArea.empty() )
415 QDockWidget *tabifyWithDockWidget =
nullptr;
416 for (
const QString &targetName : tabifyWith )
418 auto it = std::find_if( dockWidgetsInArea.begin(), dockWidgetsInArea.end(), [&targetName]( QDockWidget *cw ) {
419 return cw->objectName() == targetName || cw->property(
"dock_uuid" ).toString() == targetName;
422 if ( it != dockWidgetsInArea.end() )
424 tabifyWithDockWidget = *it;
429 if ( !tabifyWithDockWidget )
432 tabifyWithDockWidget = dockWidgetsInArea.at( 0 );
434 if ( tabifyWithDockWidget == dockWidget )
438 QTabBar *existingTabBar =
nullptr;
439 int currentTabIndex = -1;
440 if ( !raiseTab && dockWidgetsInArea.length() > 1 )
444 const QList<QTabBar *> tabBars = window->findChildren<QTabBar *>( QString(), Qt::FindDirectChildrenOnly );
445 bool tabBarFound =
false;
446 for ( QTabBar *tabBar : tabBars )
448 for (
int i = 0; i < tabBar->count(); i++ )
450 if ( tabBar->tabText( i ) == tabifyWithDockWidget->windowTitle() )
452 existingTabBar = tabBar;
453 currentTabIndex = tabBar->currentIndex();
466 window->tabifyDockWidget( tabifyWithDockWidget, dockWidget );
471 if ( existingTabBar )
473 existingTabBar->setCurrentIndex( currentTabIndex );
477 tabifyWithDockWidget->raise();
490 QApplication::setOverrideCursor( cursor );
496 QApplication::restoreOverrideCursor();
504 mHasOverride =
false;
505 QApplication::restoreOverrideCursor();
515 while ( QApplication::overrideCursor() )
517 mCursors.emplace_back( QCursor( *QApplication::overrideCursor() ) );
518 QApplication::restoreOverrideCursor();
529 for (
auto it = mCursors.rbegin(); it != mCursors.rend(); ++it )
531 QApplication::setOverrideCursor( *it );
543 mWidget->setUpdatesEnabled(
false );
551 mWidget->setUpdatesEnabled(
true );
DataType
Raster data types.
@ Float32
Thirty two bit floating point (float).
@ CFloat64
Complex Float64.
@ Int16
Sixteen bit signed integer (qint16).
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Int8
Eight bit signed integer (qint8) (added in QGIS 3.30).
@ UInt16
Sixteen bit unsigned integer (quint16).
@ Byte
Eight bit unsigned integer (quint8).
@ UnknownDataType
Unknown or unspecified type.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
@ Int32
Thirty two bit signed integer (qint32).
@ Float64
Sixty four bit floating point (double).
@ CFloat32
Complex Float32.
@ UInt32
Thirty two bit unsigned integer (quint32).
WkbType
The WKB type describes the number of dimensions a geometry has.
@ PolyhedralSurface
PolyhedralSurface.
static int scaleIconSize(int standardSize, bool applyDevicePixelRatio=false)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
A file dialog which lets the user select the preferred encoding type for a data provider.
void addCancelAll()
Adds a 'Cancel All' button for the user to click.
bool cancelAll() const
Returns true if the user clicked 'Cancel All'.
static QString addExtensionFromFilter(const QString &fileName, const QString &filter)
Ensures that a fileName ends with an extension from the specified filter string.
Stores settings for use within QGIS.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QgsTemporaryCursorOverride(const QCursor &cursor)
Constructor for QgsTemporaryCursorOverride.
~QgsTemporaryCursorOverride()
void release()
Releases the cursor override early (i.e.
QgsTemporaryCursorRestoreOverride()
Constructor for QgsTemporaryCursorRestoreOverride.
void restore()
Restores the cursor override early (i.e.
~QgsTemporaryCursorRestoreOverride()
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
The QgsGuiUtils namespace contains constants and helper functions used throughout the QGIS GUI.
void addDockWidget(QMainWindow *window, Qt::DockWidgetArea area, QDockWidget *dockwidget)
Add a dock widget to a main window.
void addTabifiedDockWidget(QMainWindow *window, Qt::DockWidgetArea area, QDockWidget *dockWidget, const QStringList &tabifyWith, bool raiseTab)
Add a dock widget to the given area and tabify it (if other dock widgets exist in the same area).
bool restoreGeometry(QWidget *widget, const QString &keyName)
Restore the wigget geometry from settings.
QString createWidgetKey(QWidget *widget, const QString &keyName)
Creates a key for the given widget that can be used to store related data in settings.
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.
bool isNonStandardGeoPackageGeometryType(Qgis::WkbType wkbType)
Returns true if the given wkbType is a non-standard GeoPackage geometry type (PolyhedralSurface,...
bool warnAboutNonStandardGeoPackageGeometryType(Qgis::WkbType wkbType, QWidget *parent, const QString &dialogTitle, bool showDialog, bool *isNonStandard)
Checks if the given wkbType is a non-standard GeoPackage geometry type (PolyhedralSurface,...
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
int significantDigits(const Qgis::DataType rasterDataType)
Returns the maximum number of significant digits a for the given rasterDataType.
void saveGeometry(QWidget *widget, const QString &keyName)
Save the wigget geometry into settings.
QFont getFont(bool &ok, const QFont &initial, const QString &title)
Show font selection dialog.
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,...
QString createFileFilter_(QString const &longName, QString const &glob)
Convenience function for readily creating file filters.
QSize panelIconSize(QSize size)
Returns dockable panel toolbar icon width based on the provided window toolbar width.
QString displayValueWithMaximumDecimals(const Qgis::DataType dataType, const double value, bool displayTrailingZeroes)
Returns a localized string representation of the value with the appropriate number of decimals suppor...
QString qgsMapJoinKeys(const QMap< Key, Value > &map, const QString &separator)
Joins all the map keys into a single string with each element separated by the given separator.
#define QgsDebugMsgLevel(str, level)