Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 37 additions & 27 deletions src/lay/lay/layMainWindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2277,6 +2277,29 @@ MainWindow::cm_save_as ()
do_save (true);
}

static db::SaveLayoutOptions
get_save_options_from_cv (const lay::CellView &cv)
{
db::SaveLayoutOptions options = cv->save_options ();
if (!cv->save_options_valid () && cv->technology ()) {
options = cv->technology ()->save_layout_options ();
options.set_format (cv->save_options ().format ());
}

// preconfigure options with current values

options.set_dbu (cv->layout ().dbu ());

if (cv->layout ().has_meta_info ("libname")) {
tl::Variant libname = cv->layout ().meta_info ("libname").value;
if (libname.is_a_string ()) {
options.set_libname (libname.to_stdstring ());
}
}

return options;
}

void
MainWindow::do_save (bool as)
{
Expand Down Expand Up @@ -2309,22 +2332,7 @@ MainWindow::do_save (bool as)
// - if the layout's save options are valid we take the options from there, otherwise we take the options from the technology
// - on "save as" we let the user edit the options

db::SaveLayoutOptions options = cv->save_options ();
if (!cv->save_options_valid () && cv->technology ()) {
options = cv->technology ()->save_layout_options ();
options.set_format (cv->save_options ().format ());
}

// preconfigure options with current values

options.set_dbu (cv->layout ().dbu ());

if (cv->layout ().has_meta_info ("libname")) {
tl::Variant libname = cv->layout ().meta_info ("libname").value;
if (libname.is_a_string ()) {
options.set_libname (libname.to_stdstring ());
}
}
db::SaveLayoutOptions options = get_save_options_from_cv (cv);

if (as || options.format ().empty ()) {
options.set_format_from_filename (fn);
Expand All @@ -2337,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);

}

}

Expand All @@ -2362,23 +2381,14 @@ MainWindow::cm_save_all ()

if (! fn.empty () || mp_layout_fdia->get_save (fn, tl::to_string (tr ("Save Layout '%1'").arg (tl::to_qstring (cv->name ()))))) {

db::SaveLayoutOptions options (cv->save_options ());
options.set_dbu (cv->layout ().dbu ());
db::SaveLayoutOptions options = get_save_options_from_cv (cv);

if (options.format ().empty ()) {
options.set_format_from_filename (fn);
}

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 ());

Expand Down
28 changes: 0 additions & 28 deletions src/laybasic/laybasic/layCellView.cc
Original file line number Diff line number Diff line change
Expand Up @@ -300,39 +300,11 @@ LayoutHandle::set_save_options (const db::SaveLayoutOptions &options, bool valid
m_save_options_valid = valid;
}

void
LayoutHandle::update_save_options (db::SaveLayoutOptions &options)
{
#if defined(HAVE_QT)
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {

const lay::StreamWriterPluginDeclaration *decl = dynamic_cast <const lay::StreamWriterPluginDeclaration *> (&*cls);
if (! decl || decl->options_alias ()) {
continue;
}

std::unique_ptr<db::FormatSpecificWriterOptions> specific_options;
if (options.get_options (decl->format_name ())) {
specific_options.reset (options.get_options (decl->format_name ())->clone ());
} else {
specific_options.reset (decl->create_specific_options ());
}

if (specific_options.get ()) {
options.set_options (specific_options.release ());
}

}
#endif
}

void
LayoutHandle::save_as (const std::string &fn, tl::OutputStream::OutputStreamMode om, const db::SaveLayoutOptions &options, bool update, int keep_backups)
{
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 ();
Expand Down
9 changes: 0 additions & 9 deletions src/laybasic/laybasic/layCellView.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,6 @@ class LAYBASIC_PUBLIC LayoutHandle
return m_save_options;
}

/**
* @brief Updates the given save options with attributes from this cell view
*
* Some formats will initialize attributes from the cell view and the layout's
* metadata (example: libname of GDS2). This method will update the options
* if the layout provides attributes for initializing the latter.
*/
void update_save_options (db::SaveLayoutOptions &options);

/**
* @brief Gets a flag indicating whether the save options are valid
*
Expand Down
72 changes: 72 additions & 0 deletions src/laybasic/laybasic/layLayoutViewBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -279,6 +343,14 @@ class LAYBASIC_PUBLIC LayoutViewBase :
*/
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
*
Expand Down
8 changes: 8 additions & 0 deletions src/layview/layview/layLayoutView_qt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
75 changes: 8 additions & 67 deletions src/layview/layview/layLayoutView_qt.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

#
/*

KLayout Layout Viewer
Expand Down Expand Up @@ -149,6 +149,11 @@ class LAYVIEW_PUBLIC LayoutView
*/
~LayoutView ();

/**
* @brief Adds a notification
*/
virtual void add_notification (const LayoutViewNotification &notification);

/**
* @brief Gets the widget object that view is embedded in
*/
Expand Down Expand Up @@ -695,70 +700,6 @@ class LAYVIEW_PUBLIC LayoutView
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
*/
Expand Down Expand Up @@ -810,12 +751,12 @@ Q_OBJECT
/**
* @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
Expand Down
Loading