Fixed issue #2221 (restoring 'save' behavior on 'save all')

'save all' now behaves like 'save' on all layouts by respecting
the application-wide writer options.

In addition, a weird feature was fixed: when using 'save' for the
first time, old versions were freezing the writer options and changing the
application-wide options did not have an effect on views after
they were saved the first time.

Now, this behavior only applies to "save as" and a popup is shown
in the top of the layout view indicating that from now on the
special options apply. This way, special options can be picked
in "save as" and they will remain valid during the next "save".
This commit is contained in:
Matthias Koefferlein 2025-11-27 21:57:13 +01:00
parent bbaaa14b2c
commit bc835adf64
5 changed files with 100 additions and 78 deletions

View File

@ -2345,7 +2345,18 @@ MainWindow::do_save (bool as)
}
current_view ()->save_as ((unsigned int) cv_index, fn, om, options, true, m_keep_backups);
add_mru (fn, current_view ()->cellview (cv_index)->tech_name ());
add_mru (fn, cv->tech_name ());
if (as) {
lay::LayoutViewNotification n ("reload", tl::to_string (tr ("The next 'save' operations will use the writer options you have picked, instead of the application-wide ones.")));
current_view ()->add_notification (n);
// freeze writer options in the 'save_as' case, so we can do another "save" and get the
// selected options again
cv->set_save_options (options, true);
}
}
@ -2378,14 +2389,6 @@ MainWindow::cm_save_all ()
tl::OutputStream::OutputStreamMode om = tl::OutputStream::OM_Auto;
// initialize the specific options from the configuration if required
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
const StreamWriterPluginDeclaration *decl = dynamic_cast <const StreamWriterPluginDeclaration *> (&*cls);
if (decl) {
options.set_options (decl->create_specific_options ());
}
}
view (view_index)->save_as (cv_index, fn, om, options, true, m_keep_backups);
add_mru (fn, cv->tech_name ());

View File

@ -305,8 +305,6 @@ LayoutHandle::save_as (const std::string &fn, tl::OutputStream::OutputStreamMode
{
if (update) {
m_save_options = options;
m_save_options_valid = true;
// We must not load with the original options after we have saved the file - hence we reset the
// reader options.
m_load_options = db::LoadLayoutOptions ();

View File

@ -149,6 +149,70 @@ struct LAYBASIC_PUBLIC LayerDisplayProperties
std::string name;
};
/**
* @brief Descriptor for a notification inside the layout view
*
* Notifications are popups added at the top of the view to indicate need for reloading for example.
* Notifications have a name, a title, optional actions (id, title) and a parameter (e.g. file path to reload).
* Actions are mapped to QPushButtons.
*/
class LAYBASIC_PUBLIC LayoutViewNotification
{
public:
LayoutViewNotification (const std::string &name, const std::string &title, const tl::Variant &parameter = tl::Variant ())
: m_name (name), m_title (title), m_parameter (parameter)
{
// .. nothing yet ..
}
void add_action (const std::string &name, const std::string &title)
{
m_actions.push_back (std::make_pair (name, title));
}
const std::vector<std::pair<std::string, std::string> > &actions () const
{
return m_actions;
}
const std::string &name () const
{
return m_name;
}
const std::string &title () const
{
return m_title;
}
const tl::Variant &parameter () const
{
return m_parameter;
}
bool operator<(const LayoutViewNotification &other) const
{
if (m_name != other.name ()) {
return m_name < other.name ();
}
return m_parameter < other.parameter ();
}
bool operator==(const LayoutViewNotification &other) const
{
if (m_name != other.name ()) {
return false;
}
return m_parameter == other.parameter ();
}
private:
std::string m_name;
std::string m_title;
tl::Variant m_parameter;
std::vector<std::pair<std::string, std::string> > m_actions;
};
/**
* @brief The layout view object
*
@ -279,6 +343,14 @@ public:
*/
virtual void cut ();
/**
* @brief Adds a notification
*/
virtual void add_notification (const LayoutViewNotification & /*notification*/)
{
// the base implementation does nothing
}
/**
* @brief Gets the explicit title string of the view
*

View File

@ -453,6 +453,14 @@ LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool edit
LayoutView::set_active_cellview_index (source->active_cellview_index ());
}
void
LayoutView::add_notification (const LayoutViewNotification &notification)
{
if (mp_widget) {
mp_widget->add_notification (notification);
}
}
bool
LayoutView::event_filter (QObject *obj, QEvent *event, bool &taken)
{

View File

@ -1,4 +1,4 @@
#
/*
KLayout Layout Viewer
@ -149,6 +149,11 @@ public:
*/
~LayoutView ();
/**
* @brief Adds a notification
*/
virtual void add_notification (const LayoutViewNotification &notification);
/**
* @brief Gets the widget object that view is embedded in
*/
@ -695,70 +700,6 @@ private:
void activate_editor_option_pages ();
};
/**
* @brief Descriptor for a notification inside the layout view
*
* Notifications are popups added at the top of the view to indicate need for reloading for example.
* Notifications have a name, a title, optional actions (id, title) and a parameter (e.g. file path to reload).
* Actions are mapped to QPushButtons.
*/
class LAYVIEW_PUBLIC LayoutViewNotification
{
public:
LayoutViewNotification (const std::string &name, const std::string &title, const tl::Variant &parameter = tl::Variant ())
: m_name (name), m_title (title), m_parameter (parameter)
{
// .. nothing yet ..
}
void add_action (const std::string &name, const std::string &title)
{
m_actions.push_back (std::make_pair (name, title));
}
const std::vector<std::pair<std::string, std::string> > &actions () const
{
return m_actions;
}
const std::string &name () const
{
return m_name;
}
const std::string &title () const
{
return m_title;
}
const tl::Variant &parameter () const
{
return m_parameter;
}
bool operator<(const LayoutViewNotification &other) const
{
if (m_name != other.name ()) {
return m_name < other.name ();
}
return m_parameter < other.parameter ();
}
bool operator==(const LayoutViewNotification &other) const
{
if (m_name != other.name ()) {
return false;
}
return m_parameter == other.parameter ();
}
private:
std::string m_name;
std::string m_title;
tl::Variant m_parameter;
std::vector<std::pair<std::string, std::string> > m_actions;
};
/**
* @brief A widget representing a notification
*/
@ -810,12 +751,12 @@ public:
/**
* @brief Adds a notification
*/
void add_notification (const LayoutViewNotification &notificaton);
void add_notification (const LayoutViewNotification &notification);
/**
* @brief Removes a notification
*/
void remove_notification (const LayoutViewNotification &notificaton);
void remove_notification (const LayoutViewNotification &notification);
/**
* @brief Gets the LayoutView embedded into this widget