Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0645008

Browse files
committedMay 8, 2019
GTK: use native file chooser dialog, if available.
This requires GTK 3.24+ and (at least for GTK 3.24) the environment variable GTK_USE_PORTAL to be set to 1.
1 parent e7b75f1 commit 0645008

File tree

4 files changed

+106
-40
lines changed

4 files changed

+106
-40
lines changed
 

‎CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ Other new features:
8181
* The "=" key is bound to "Zoom In", like "+" key.
8282
* The numpad decimal separator key is bound to "." regardless of locale.
8383
* On Windows, full-screen mode is implemented.
84+
* On Linux, native file chooser dialog can be used.
8485

8586
Bugs fixed:
8687
* A point in 3d constrained to any line whose length is free no longer
@@ -98,7 +99,7 @@ Bugs fixed:
9899
* Paste Transformed with a negative scale does not invert arcs.
99100
* The tangent arc now modifies the original entities instead of deleting
100101
them, such that their constraints are retained.
101-
* When linking a sketch file, missing custom styles are now imported from
102+
* When linking a sketch file, missing custom styles are now imported from
102103
the linked file.
103104

104105
2.x

‎src/CMakeLists.txt

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ endif()
1313

1414
set(HAVE_SPACEWARE ${SPACEWARE_FOUND})
1515

16+
if(NOT WIN32 OR APPLE)
17+
if(GTKMM_gtkmm-3.0_VERSION VERSION_LESS "3.24.0")
18+
set(HAVE_GTK_FILECHOOSERNATIVE 0)
19+
else()
20+
set(HAVE_GTK_FILECHOOSERNATIVE 1)
21+
endif()
22+
endif()
23+
1624
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
1725
${CMAKE_CURRENT_BINARY_DIR}/config.h)
1826

‎src/config.h.in

+3
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@
1616
#cmakedefine HAVE_BACKTRACE
1717
#define BACKTRACE_HEADER @BACKTRACE_HEADER@
1818

19+
/* If we use GTK, can we use the native file chooser? */
20+
#cmakedefine HAVE_GTK_FILECHOOSERNATIVE
21+
1922
#endif

‎src/platform/guigtk.cpp

+93-39
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
#include <gtkmm/cssprovider.h>
1616
#include <gtkmm/entry.h>
1717
#include <gtkmm/filechooserdialog.h>
18+
#define HAVE_GTK_FILECHOOSERNATIVE
19+
#if defined(HAVE_GTK_FILECHOOSERNATIVE)
20+
# include <gtkmm/filechoosernative.h>
21+
#endif
1822
#include <gtkmm/fixed.h>
1923
#include <gtkmm/glarea.h>
2024
#include <gtkmm/main.h>
@@ -1187,32 +1191,27 @@ MessageDialogRef CreateMessageDialog(WindowRef parentWindow) {
11871191
// File dialogs
11881192
//-----------------------------------------------------------------------------
11891193

1190-
class FileDialogImplGtk final : public FileDialog {
1194+
class FileDialogImplGtk : public FileDialog {
11911195
public:
1192-
Gtk::FileChooserDialog gtkDialog;
1196+
Gtk::FileChooser *gtkChooser;
11931197
std::vector<std::string> extensions;
11941198

1195-
FileDialogImplGtk(Gtk::FileChooserDialog &&dialog)
1196-
: gtkDialog(std::move(dialog))
1197-
{
1198-
gtkDialog.property_filter().signal_changed().
1199+
void InitFileChooser(Gtk::FileChooser &chooser) {
1200+
gtkChooser = &chooser;
1201+
gtkChooser->property_filter().signal_changed().
11991202
connect(sigc::mem_fun(this, &FileDialogImplGtk::FilterChanged));
12001203
}
12011204

1202-
void SetTitle(std::string title) override {
1203-
gtkDialog.set_title(PrepareTitle(title));
1204-
}
1205-
12061205
void SetCurrentName(std::string name) override {
1207-
gtkDialog.set_current_name(name);
1206+
gtkChooser->set_current_name(name);
12081207
}
12091208

12101209
Platform::Path GetFilename() override {
1211-
return Path::From(gtkDialog.get_filename());
1210+
return Path::From(gtkChooser->get_filename());
12121211
}
12131212

12141213
void SetFilename(Platform::Path path) override {
1215-
gtkDialog.set_filename(path.raw);
1214+
gtkChooser->set_filename(path.raw);
12161215
}
12171216

12181217
void AddFilter(std::string name, std::vector<std::string> extensions) override {
@@ -1233,13 +1232,13 @@ class FileDialogImplGtk final : public FileDialog {
12331232
gtkFilter->set_name(name + " (" + desc + ")");
12341233

12351234
this->extensions.push_back(extensions.front());
1236-
gtkDialog.add_filter(gtkFilter);
1235+
gtkChooser->add_filter(gtkFilter);
12371236
}
12381237

12391238
std::string GetExtension() {
1240-
auto filters = gtkDialog.list_filters();
1239+
auto filters = gtkChooser->list_filters();
12411240
size_t filterIndex =
1242-
std::find(filters.begin(), filters.end(), gtkDialog.get_filter()) -
1241+
std::find(filters.begin(), filters.end(), gtkChooser->get_filter()) -
12431242
filters.begin();
12441243
if(filterIndex < extensions.size()) {
12451244
return extensions[filterIndex];
@@ -1249,14 +1248,14 @@ class FileDialogImplGtk final : public FileDialog {
12491248
}
12501249

12511250
void SetExtension(std::string extension) {
1252-
auto filters = gtkDialog.list_filters();
1251+
auto filters = gtkChooser->list_filters();
12531252
size_t extensionIndex =
12541253
std::find(extensions.begin(), extensions.end(), extension) -
12551254
extensions.begin();
12561255
if(extensionIndex < filters.size()) {
1257-
gtkDialog.set_filter(filters[extensionIndex]);
1256+
gtkChooser->set_filter(filters[extensionIndex]);
12581257
} else {
1259-
gtkDialog.set_filter(filters.front());
1258+
gtkChooser->set_filter(filters.front());
12601259
}
12611260
}
12621261

@@ -1270,21 +1269,46 @@ class FileDialogImplGtk final : public FileDialog {
12701269

12711270
void FreezeChoices(SettingsRef settings, const std::string &key) override {
12721271
settings->FreezeString("Dialog_" + key + "_Folder",
1273-
gtkDialog.get_current_folder());
1272+
gtkChooser->get_current_folder());
12741273
settings->FreezeString("Dialog_" + key + "_Filter", GetExtension());
12751274
}
12761275

12771276
void ThawChoices(SettingsRef settings, const std::string &key) override {
1278-
gtkDialog.set_current_folder(settings->ThawString("Dialog_" + key + "_Folder"));
1277+
gtkChooser->set_current_folder(settings->ThawString("Dialog_" + key + "_Folder"));
12791278
SetExtension(settings->ThawString("Dialog_" + key + "_Filter"));
12801279
}
12811280

1282-
bool RunModal() override {
1283-
if(gtkDialog.get_action() == Gtk::FILE_CHOOSER_ACTION_SAVE &&
1284-
Path::From(gtkDialog.get_current_name()).FileStem().empty()) {
1285-
gtkDialog.set_current_name(std::string(_("untitled")) + "." + GetExtension());
1281+
void CheckForUntitledFile() {
1282+
if(gtkChooser->get_action() == Gtk::FILE_CHOOSER_ACTION_SAVE &&
1283+
Path::From(gtkChooser->get_current_name()).FileStem().empty()) {
1284+
gtkChooser->set_current_name(std::string(_("untitled")) + "." + GetExtension());
12861285
}
1286+
}
1287+
};
12871288

1289+
class FileDialogGtkImplGtk final : public FileDialogImplGtk {
1290+
public:
1291+
Gtk::FileChooserDialog gtkDialog;
1292+
1293+
FileDialogGtkImplGtk(Gtk::Window &gtkParent, bool isSave)
1294+
: gtkDialog(gtkParent,
1295+
isSave ? C_("title", "Save File")
1296+
: C_("title", "Open File"),
1297+
isSave ? Gtk::FILE_CHOOSER_ACTION_SAVE
1298+
: Gtk::FILE_CHOOSER_ACTION_OPEN) {
1299+
gtkDialog.add_button(C_("button", "_Cancel"), Gtk::RESPONSE_CANCEL);
1300+
gtkDialog.add_button(isSave ? C_("button", "_Save")
1301+
: C_("button", "_Open"), Gtk::RESPONSE_OK);
1302+
gtkDialog.set_default_response(Gtk::RESPONSE_OK);
1303+
InitFileChooser(gtkDialog);
1304+
}
1305+
1306+
void SetTitle(std::string title) override {
1307+
gtkDialog.set_title(PrepareTitle(title));
1308+
}
1309+
1310+
bool RunModal() override {
1311+
CheckForUntitledFile();
12881312
if(gtkDialog.run() == Gtk::RESPONSE_OK) {
12891313
return true;
12901314
} else {
@@ -1293,26 +1317,56 @@ class FileDialogImplGtk final : public FileDialog {
12931317
}
12941318
};
12951319

1320+
#if defined(HAVE_GTK_FILECHOOSERNATIVE)
1321+
1322+
class FileDialogNativeImplGtk final : public FileDialogImplGtk {
1323+
public:
1324+
Glib::RefPtr<Gtk::FileChooserNative> gtkNative;
1325+
1326+
FileDialogNativeImplGtk(Gtk::Window &gtkParent, bool isSave) {
1327+
gtkNative = Gtk::FileChooserNative::create(
1328+
isSave ? C_("title", "Save File")
1329+
: C_("title", "Open File"),
1330+
gtkParent,
1331+
isSave ? Gtk::FILE_CHOOSER_ACTION_SAVE
1332+
: Gtk::FILE_CHOOSER_ACTION_OPEN,
1333+
isSave ? C_("button", "_Save")
1334+
: C_("button", "_Open"),
1335+
C_("button", "_Cancel"));
1336+
// Seriously, GTK?!
1337+
InitFileChooser(*gtkNative.operator->());
1338+
}
1339+
1340+
void SetTitle(std::string title) override {
1341+
gtkNative->set_title(PrepareTitle(title));
1342+
}
1343+
1344+
bool RunModal() override {
1345+
CheckForUntitledFile();
1346+
if(gtkNative->run() == Gtk::RESPONSE_OK) {
1347+
return true;
1348+
} else {
1349+
return false;
1350+
}
1351+
}
1352+
};
1353+
1354+
#endif
1355+
1356+
#if defined(HAVE_GTK_FILECHOOSERNATIVE)
1357+
# define FILE_DIALOG_IMPL FileDialogNativeImplGtk
1358+
#else
1359+
# define FILE_DIALOG_IMPL FileDialogGtkImplGtk
1360+
#endif
1361+
12961362
FileDialogRef CreateOpenFileDialog(WindowRef parentWindow) {
12971363
Gtk::Window &gtkParent = std::static_pointer_cast<WindowImplGtk>(parentWindow)->gtkWindow;
1298-
Gtk::FileChooserDialog gtkDialog(gtkParent, C_("title", "Open File"),
1299-
Gtk::FILE_CHOOSER_ACTION_OPEN);
1300-
gtkDialog.add_button(C_("button", "_Cancel"), Gtk::RESPONSE_CANCEL);
1301-
gtkDialog.add_button(C_("button", "_Open"), Gtk::RESPONSE_OK);
1302-
gtkDialog.set_default_response(Gtk::RESPONSE_OK);
1303-
return std::make_shared<FileDialogImplGtk>(std::move(gtkDialog));
1304-
1364+
return std::make_shared<FILE_DIALOG_IMPL>(gtkParent, /*isSave=*/false);
13051365
}
13061366

13071367
FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) {
13081368
Gtk::Window &gtkParent = std::static_pointer_cast<WindowImplGtk>(parentWindow)->gtkWindow;
1309-
Gtk::FileChooserDialog gtkDialog(gtkParent, C_("title", "Save File"),
1310-
Gtk::FILE_CHOOSER_ACTION_SAVE);
1311-
gtkDialog.set_do_overwrite_confirmation(true);
1312-
gtkDialog.add_button(C_("button", "_Cancel"), Gtk::RESPONSE_CANCEL);
1313-
gtkDialog.add_button(C_("button", "_Save"), Gtk::RESPONSE_OK);
1314-
gtkDialog.set_default_response(Gtk::RESPONSE_OK);
1315-
return std::make_shared<FileDialogImplGtk>(std::move(gtkDialog));
1369+
return std::make_shared<FILE_DIALOG_IMPL>(gtkParent, /*isSave=*/true);
13161370
}
13171371

13181372
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)
Please sign in to comment.