mirror of https://github.com/KLayout/klayout.git
Add default extension to file names unless one is given
This commit is contained in:
parent
2ed27ff937
commit
67436d81a5
|
|
@ -26,6 +26,7 @@
|
|||
#include "gsiDeclBasic.h"
|
||||
#include "layBrowserDialog.h"
|
||||
#include "layBrowserPanel.h"
|
||||
#include "layFileDialog.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
|
|
@ -926,11 +927,30 @@ static tl::Variant ask_open_file_name (const std::string &title, const std::stri
|
|||
|
||||
static tl::Variant ask_save_file_name (const std::string &title, const std::string &dir, const std::string &filter)
|
||||
{
|
||||
QString f = QFileDialog::getSaveFileName (QApplication::activeWindow (), tl::to_qstring (title), tl::to_qstring (dir), tl::to_qstring (filter));
|
||||
QString selected_filter;
|
||||
|
||||
QString f = QFileDialog::getSaveFileName (QApplication::activeWindow (), tl::to_qstring (title), tl::to_qstring (dir), tl::to_qstring (filter), &selected_filter);
|
||||
if (f.isEmpty ()) {
|
||||
return tl::Variant ();
|
||||
} else {
|
||||
return tl::Variant (tl::to_string (f));
|
||||
return tl::Variant (lay::FileDialog::add_default_extension (tl::to_string (f), selected_filter));
|
||||
}
|
||||
}
|
||||
|
||||
static tl::Variant ask_save_file_name2 (const std::string &title, const std::string &dir, const std::string &filter)
|
||||
{
|
||||
QString selected_filter;
|
||||
QString qfilter = tl::to_qstring (filter);
|
||||
|
||||
QString f = QFileDialog::getSaveFileName (QApplication::activeWindow (), tl::to_qstring (title), tl::to_qstring (dir), qfilter, &selected_filter);
|
||||
if (f.isEmpty ()) {
|
||||
return tl::Variant ();
|
||||
} else {
|
||||
tl::Variant v;
|
||||
v.set_list ();
|
||||
v.push (lay::FileDialog::add_default_extension (tl::to_string (f), selected_filter));
|
||||
v.push (lay::FileDialog::find_selected_filter (qfilter, selected_filter));
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1012,6 +1032,16 @@ Class<FileDialog> decl_FileDialog ("lay", "FileDialog",
|
|||
"@return The path of the file chosen or \"nil\" if \"Cancel\" was pressed\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.23. It is somewhat easier to use than the get_... equivalent.\n"
|
||||
) +
|
||||
gsi::method ("ask_save_file_name_with_filter", &ask_save_file_name2, gsi::arg ("title"), gsi::arg ("dir"), gsi::arg ("filter"),
|
||||
"@brief Select one file for writing\n"
|
||||
"\n"
|
||||
"@param title The title of the dialog\n"
|
||||
"@param dir The directory selected initially\n"
|
||||
"@param filter The filters available, for example \"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)\"\n"
|
||||
"@return \"nil\" if \"Cancel\" was pressed, otherwise a pair: The path of the file chosen and the index selected file type (-1 if no specific type was selected)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.28.11.\n"
|
||||
),
|
||||
"@brief Various methods to request a file name\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include "layFileDialog.h"
|
||||
#include "tlInternational.h"
|
||||
#include "tlString.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -60,32 +62,53 @@ FileDialog::~FileDialog ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
// not used if standard dialogs are used (disabled to avoid compiler warning):
|
||||
#if 0
|
||||
static void
|
||||
split_filters (const QString &filters, QStringList &slist)
|
||||
int
|
||||
FileDialog::find_selected_filter (const QString &fs, const QString &selected_filter)
|
||||
{
|
||||
QString s;
|
||||
for (const char *cp = filters.ascii (); *cp; ++cp) {
|
||||
if (cp[0] == ';' && cp[1] == ';') {
|
||||
slist << s;
|
||||
++cp;
|
||||
s = "";
|
||||
} else {
|
||||
s += *cp;
|
||||
QStringList filters = fs.split (tl::to_qstring (";;"));
|
||||
|
||||
for (auto f = filters.begin (); f != filters.end (); ++f) {
|
||||
if (*f == selected_filter) {
|
||||
return int (f - filters.begin ());
|
||||
}
|
||||
}
|
||||
|
||||
if (s != "") {
|
||||
slist << s;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string
|
||||
FileDialog::add_default_extension (const std::string &path, const QString &selected_filter)
|
||||
{
|
||||
if (tl::extension (path).empty ()) {
|
||||
|
||||
std::string sf = tl::to_string (selected_filter);
|
||||
|
||||
auto star = sf.find ("*.");
|
||||
if (star != std::string::npos) {
|
||||
|
||||
tl::Extractor ex (sf.c_str () + star + 2);
|
||||
std::string ext;
|
||||
|
||||
if (ex.try_read_word (ext)) {
|
||||
return path + "." + ext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
int
|
||||
FileDialog::selected_filter () const
|
||||
{
|
||||
return find_selected_filter (m_filters, m_sel_filter);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
FileDialog::get_open (std::string &fp, const std::string &title)
|
||||
{
|
||||
#if 1
|
||||
// Use the standard (system) dialogs:
|
||||
|
||||
QString file_name;
|
||||
|
|
@ -107,54 +130,11 @@ FileDialog::get_open (std::string &fp, const std::string &title)
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
QString file_name;
|
||||
if (! fp.empty ()) {
|
||||
QFileInfo fi (fp.c_str ());
|
||||
m_dir = fi.absoluteDir ();
|
||||
file_name = fi.fileName ();
|
||||
}
|
||||
|
||||
QFileDialog fdia (QApplication::activeWindow ());
|
||||
|
||||
fdia.setDirectory (m_dir);
|
||||
if (m_def_suffix != "") {
|
||||
fdia.setDefaultSuffix (m_def_suffix);
|
||||
}
|
||||
|
||||
QStringList types;
|
||||
split_filters (m_filters, types);
|
||||
fdia.setFilters (types);
|
||||
|
||||
fdia.setReadOnly (true);
|
||||
fdia.setViewMode (QFileDialog::Detail);
|
||||
fdia.setFileMode (QFileDialog::ExistingFile);
|
||||
fdia.setAcceptMode (QFileDialog::AcceptOpen);
|
||||
fdia.setConfirmOverwrite (true);
|
||||
fdia.setCaption (QString (tl::to_string (QObject::tr ("Open ")).c_str ()) + (title.empty () ? m_title : tl::to_qstring (title)));
|
||||
if (! file_name.isEmpty ()) {
|
||||
fdia.selectFile (file_name);
|
||||
}
|
||||
|
||||
QStringList files;
|
||||
if (fdia.exec ()) {
|
||||
files = fdia.selectedFiles();
|
||||
if (files.size () > 0) {
|
||||
fp = tl::to_string (files [0]);
|
||||
QFileInfo fi (files [0]);
|
||||
m_dir = fi.absoluteDir ();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
FileDialog::get_open (std::vector<std::string> &fp, const std::string &dir, const std::string &title)
|
||||
{
|
||||
#if 1
|
||||
// Use the standard (system) dialogs:
|
||||
|
||||
if (! dir.empty ()) {
|
||||
|
|
@ -175,68 +155,11 @@ FileDialog::get_open (std::vector<std::string> &fp, const std::string &dir, cons
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (! dir.empty ()) {
|
||||
QDir fi (dir.c_str ());
|
||||
m_dir = fi.absolutePath ();
|
||||
}
|
||||
|
||||
QStringList file_names;
|
||||
for (std::vector<std::string>::const_iterator f = fp.begin (); f != fp.end (); ++f) {
|
||||
QFileInfo fi (f->c_str ());
|
||||
m_dir = fi.absoluteDir ();
|
||||
file_names << QString (f->c_str ());
|
||||
}
|
||||
|
||||
QFileDialog fdia (QApplication::activeWindow ());
|
||||
|
||||
fdia.setDirectory (m_dir);
|
||||
if (m_def_suffix != "") {
|
||||
fdia.setDefaultSuffix (m_def_suffix);
|
||||
}
|
||||
|
||||
QStringList types;
|
||||
split_filters (m_filters, types);
|
||||
fdia.setFilters (types);
|
||||
|
||||
fdia.setReadOnly (true);
|
||||
fdia.setViewMode (QFileDialog::Detail);
|
||||
fdia.setFileMode (QFileDialog::ExistingFiles);
|
||||
fdia.setAcceptMode (QFileDialog::AcceptOpen);
|
||||
fdia.setConfirmOverwrite (true);
|
||||
fdia.setCaption (QString (tl::to_string (QObject::tr ("Open ")).c_str ()) + (title.empty () ? m_title : tl::to_qstring (title)));
|
||||
|
||||
for (QStringList::iterator f = file_names.begin (); f != file_names.end (); ++f) {
|
||||
fdia.selectFile (*f);
|
||||
}
|
||||
|
||||
QStringList files;
|
||||
if (fdia.exec ()) {
|
||||
|
||||
files = fdia.selectedFiles();
|
||||
if (! files.isEmpty ()) {
|
||||
|
||||
fp.clear ();
|
||||
for (QStringList::iterator f = files.begin (); f != files.end (); ++f) {
|
||||
fp.push_back (tl::to_string (*f));
|
||||
QFileInfo fi (*f);
|
||||
m_dir = fi.absoluteDir ();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
FileDialog::get_save (std::string &fp, const std::string &title)
|
||||
{
|
||||
#if 1
|
||||
// Use the standard (system) dialogs:
|
||||
|
||||
QString file_name;
|
||||
|
|
@ -251,55 +174,16 @@ FileDialog::get_save (std::string &fp, const std::string &title)
|
|||
QString f = QFileDialog::getSaveFileName (QApplication::activeWindow (), (title.empty () ? m_title : tl::to_qstring (title)), file_name, m_filters, &m_sel_filter);
|
||||
|
||||
if (! f.isEmpty ()) {
|
||||
fp = tl::to_string (f);
|
||||
|
||||
fp = add_default_extension (tl::to_string (f), m_sel_filter);
|
||||
|
||||
QFileInfo fi (f);
|
||||
m_dir = fi.absoluteDir ();
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
QString file_name;
|
||||
if (! fp.empty ()) {
|
||||
QFileInfo fi (fp.c_str ());
|
||||
m_dir = fi.absoluteDir ();
|
||||
file_name = fi.fileName ();
|
||||
}
|
||||
|
||||
QFileDialog fdia (QApplication::activeWindow ());
|
||||
|
||||
fdia.setDirectory (m_dir);
|
||||
if (m_def_suffix != "") {
|
||||
fdia.setDefaultSuffix (m_def_suffix);
|
||||
}
|
||||
|
||||
QStringList types;
|
||||
split_filters (m_filters, types);
|
||||
fdia.setFilters (types);
|
||||
|
||||
fdia.setReadOnly (false);
|
||||
fdia.setViewMode (QFileDialog::Detail);
|
||||
fdia.setFileMode (QFileDialog::AnyFile);
|
||||
fdia.setAcceptMode (QFileDialog::AcceptSave);
|
||||
fdia.setConfirmOverwrite (true);
|
||||
fdia.setCaption (QString (tl::to_string (QObject::tr ("Save ")).c_str ()) + (title.empty () ? m_title : tl::to_qstring (title)));
|
||||
if (! file_name.isEmpty ()) {
|
||||
fdia.selectFile (file_name);
|
||||
}
|
||||
|
||||
QStringList files;
|
||||
if (fdia.exec ()) {
|
||||
files = fdia.selectedFiles();
|
||||
if (files.size () > 0) {
|
||||
fp = tl::to_string (files [0]);
|
||||
QFileInfo fi (files [0]);
|
||||
m_dir = fi.absoluteDir ();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace lay
|
||||
|
|
|
|||
|
|
@ -65,20 +65,27 @@ public:
|
|||
~FileDialog ();
|
||||
|
||||
/**
|
||||
* @brief Get a file name to read
|
||||
* @brief Gets a file name to read
|
||||
*/
|
||||
bool get_open (std::string &file_name, const std::string &title = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Read multiple files names
|
||||
* @brief Reads multiple files names
|
||||
*/
|
||||
bool get_open (std::vector<std::string> &file_names, const std::string &dir = std::string (), const std::string &title = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Get a file name to save
|
||||
* @brief Gets a file name to save
|
||||
*/
|
||||
bool get_save (std::string &file_name, const std::string &title = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Gets the selected filter or -1 if no specific filter was selected
|
||||
*
|
||||
* This value is only set after get_open or get_save returned true
|
||||
*/
|
||||
int selected_filter () const;
|
||||
|
||||
/**
|
||||
* @brief Make the file names use UTF8 encoding
|
||||
*
|
||||
|
|
@ -87,6 +94,16 @@ public:
|
|||
*/
|
||||
static void set_utf8 (bool utf);
|
||||
|
||||
/**
|
||||
* @brief Gets the index of the selected filter from the filter list
|
||||
*/
|
||||
static int find_selected_filter (const QString &filters, const QString &selected_filter);
|
||||
|
||||
/**
|
||||
* @brief Adds the default extension unless there is one already
|
||||
*/
|
||||
static std::string add_default_extension (const std::string &path, const QString &selected_filter);
|
||||
|
||||
private:
|
||||
QDir m_dir;
|
||||
QString m_title;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
virtual std::string format_name () const { return "CIF"; }
|
||||
virtual std::string format_desc () const { return "CIF"; }
|
||||
virtual std::string format_title () const { return "CIF (Caltech interchange format)"; }
|
||||
virtual std::string file_format () const { return "CIF files (*.CIF *.cif *.cif.gz *.CIF.gz)"; }
|
||||
virtual std::string file_format () const { return "CIF files (*.cif *.CIF *.cif.gz *.CIF.gz)"; }
|
||||
|
||||
static tl::Extractor &skip_blanks (tl::Extractor &ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
virtual std::string format_name () const { return "DXF"; }
|
||||
virtual std::string format_desc () const { return "DXF"; }
|
||||
virtual std::string format_title () const { return "DXF (AutoCAD)"; }
|
||||
virtual std::string file_format () const { return "DXF files (*.DXF *.dxf *.dxf.gz *.DXF.gz)"; }
|
||||
virtual std::string file_format () const { return "DXF files (*.dxf *.DXF *.dxf.gz *.DXF.gz)"; }
|
||||
|
||||
virtual bool detect (tl::InputStream &s) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class GDS2FormatDeclaration
|
|||
virtual std::string format_name () const { return "GDS2"; }
|
||||
virtual std::string format_desc () const { return "GDS2"; }
|
||||
virtual std::string format_title () const { return "GDS2"; }
|
||||
virtual std::string file_format () const { return "GDS2 files (*.GDS *.gds *.gds.gz *.GDS.gz *.GDS2 *.gds2 *.gds2.gz *.GDS2.gz)"; }
|
||||
virtual std::string file_format () const { return "GDS2 files (*.gds *.GDS *.gds.gz *.GDS.gz *.GDS2 *.gds2 *.gds2.gz *.GDS2.gz)"; }
|
||||
|
||||
virtual bool detect (tl::InputStream &stream) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
virtual std::string format_name () const { return "MAG"; }
|
||||
virtual std::string format_desc () const { return "Magic"; }
|
||||
virtual std::string format_title () const { return "MAG (Magic layout format)"; }
|
||||
virtual std::string file_format () const { return "Magic files (*.MAG *.mag *.mag.gz *.MAG.gz)"; }
|
||||
virtual std::string file_format () const { return "Magic files (*.mag *.MAG *.mag.gz *.MAG.gz)"; }
|
||||
|
||||
virtual bool detect (tl::InputStream &s) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ public:
|
|||
virtual std::string format_name () const { return "OASIS"; }
|
||||
virtual std::string format_desc () const { return "OASIS"; }
|
||||
virtual std::string format_title () const { return "OASIS"; }
|
||||
virtual std::string file_format () const { return "OASIS files (*.OAS *.oas *.oas.gz *.OAS.gz)"; }
|
||||
virtual std::string file_format () const { return "OASIS files (*.oas *.OAS *.oas.gz *.OAS.gz)"; }
|
||||
|
||||
virtual bool detect (tl::InputStream &stream) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1168,7 +1168,7 @@ class GerberFormatDeclaration
|
|||
virtual std::string format_name () const { return "GerberPCB"; }
|
||||
virtual std::string format_desc () const { return "Gerber PCB"; }
|
||||
virtual std::string format_title () const { return "Gerber PCB (project files)"; }
|
||||
virtual std::string file_format () const { return "Gerber PCB project files (*.pcb)"; }
|
||||
virtual std::string file_format () const { return "Gerber PCB project files (*.pcb *.PCB)"; }
|
||||
|
||||
virtual bool detect (tl::InputStream &stream) const
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue