Merge branch 'master' into selection-list

This commit is contained in:
Matthias Koefferlein 2022-10-13 09:32:16 +02:00
commit bc06b688ca
6 changed files with 221 additions and 52 deletions

View File

@ -845,7 +845,8 @@ Layout::delete_cells (const std::set<cell_index_type> &cells_to_delete)
if (manager () && manager ()->transacting ()) {
// note the "take" method - this takes out the cell
manager ()->queue (this, new NewRemoveCellOp (*c, cell_name (*c), true /*remove*/, take_cell (*c)));
std::string cn (cell_name (*c));
manager ()->queue (this, new NewRemoveCellOp (*c, cn, true /*remove*/, take_cell (*c)));
} else {
@ -913,7 +914,8 @@ Layout::delete_cell (cell_index_type id)
if (manager () && manager ()->transacting ()) {
// not the "take" method - this takes out the cell
manager ()->queue (this, new NewRemoveCellOp (id, cell_name (id), true /*remove*/, take_cell (id)));
std::string cn (cell_name (id));
manager ()->queue (this, new NewRemoveCellOp (id, cn, true /*remove*/, take_cell (id)));
} else {

View File

@ -11,6 +11,7 @@ HEADERS = \
layClipDialog.h \
layControlWidgetStack.h \
layCrashMessage.h \
layEnhancedTabWidget.h \
layFillDialog.h \
layGSIHelpProvider.h \
layHelpAboutDialog.h \
@ -121,6 +122,7 @@ SOURCES = \
layClipDialog.cc \
layControlWidgetStack.cc \
layCrashMessage.cc \
layEnhancedTabWidget.cc \
layFillDialog.cc \
layGSIHelpProvider.cc \
layHelpAboutDialog.cc \

View File

@ -0,0 +1,102 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2022 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "layEnhancedTabWidget.h"
#include <QAction>
#include <QActionGroup>
#include <QMenu>
#include <QString>
#include <QToolButton>
namespace lay
{
// ---------------------------------------------------------------------------------------------
// EnhancedTabWidget implementation
EnhancedTabWidget::EnhancedTabWidget (QWidget *parent)
: QTabWidget (parent)
{
mp_list_tool_button = new QToolButton (this);
mp_list_tool_button->setAutoRaise (true);
mp_list_tool_button->setIcon (QIcon (QString::fromUtf8 (":/find_16px.png")));
mp_list_tool_button->setIconSize (QSize (20, 20));
mp_list_tool_button->setMenu (new QMenu (this));
mp_list_tool_button->setPopupMode (QToolButton::InstantPopup);
mp_list_tool_button->setToolButtonStyle (Qt::ToolButtonIconOnly);
mp_list_tool_button->setToolTip ( tr ("List of all opened views"));
setCornerWidget (mp_list_tool_button, Qt::TopRightCorner);
connect (mp_list_tool_button->menu (), SIGNAL (aboutToShow()),
this, SLOT (list_tool_button_menu_about_to_show()));
mp_list_action_group = new QActionGroup (this);
mp_list_action_group->setExclusive (true);
connect (mp_list_action_group, SIGNAL (triggered(QAction *)),
this, SLOT (list_action_group_triggered(QAction *)));
}
EnhancedTabWidget::~EnhancedTabWidget () = default;
void EnhancedTabWidget::tabInserted (int index)
{
QTabWidget::tabInserted (index);
update_list_button_visibility ();
}
void EnhancedTabWidget::tabRemoved (int index)
{
QTabWidget::tabRemoved (index);
update_list_button_visibility ();
}
void EnhancedTabWidget::list_action_group_triggered (QAction *action)
{
setCurrentIndex (action->data ().toInt ());
}
void EnhancedTabWidget::list_tool_button_menu_about_to_show ()
{
mp_list_tool_button->menu ()->clear ();
if (count () > 1) {
for (int i = 0; i < count (); ++i) {
QAction *action = mp_list_tool_button->menu ()->addAction (tabText (i));
action->setCheckable (true);
action->setData (QVariant (i));
mp_list_action_group->addAction (action);
}
mp_list_action_group->actions ().at (currentIndex ())->setChecked (true);
}
}
void EnhancedTabWidget::update_list_button_visibility()
{
if (cornerWidget (Qt::TopRightCorner) != nullptr) {
cornerWidget (Qt::TopRightCorner)->setVisible (count () > 1);
}
}
}

View File

@ -0,0 +1,62 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2022 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef HDR_layEnhancedTabWidget
#define HDR_layEnhancedTabWidget
#include <QTabWidget>
class QActionGroup;
class QToolButton;
namespace lay
{
class EnhancedTabWidget
: public QTabWidget
{
Q_OBJECT
public:
EnhancedTabWidget (QWidget *parent);
~EnhancedTabWidget () override;
protected:
void tabInserted (int index) override;
void tabRemoved (int index) override;
private slots:
void list_action_group_triggered (QAction* action);
void list_tool_button_menu_about_to_show ();
private:
QActionGroup *mp_list_action_group;
QToolButton *mp_list_tool_button;
void update_list_button_visibility ();
};
}
#endif

View File

@ -70,6 +70,7 @@
#include "layDialogs.h"
#include "laybasicConfig.h"
#include "layConfig.h"
#include "layEnhancedTabWidget.h"
#include "layMainWindow.h"
#include "layHelpDialog.h"
#include "layNavigator.h"
@ -203,7 +204,7 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled)
init_menu ();
mp_assistant = 0;
m_always_exit_without_saving = false;
mp_pr = new lay::ProgressReporter ();
@ -227,12 +228,12 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled)
vbl->setContentsMargins (0, 0, 0, 0);
vbl->setSpacing (0);
mp_tab_bar = new QTabBar (mp_main_frame);
vbl->addWidget (mp_tab_bar);
connect (mp_tab_bar, SIGNAL (currentChanged (int)), this, SLOT (view_selected (int)));
mp_tab_widget = new EnhancedTabWidget (mp_main_frame);
vbl->addWidget (mp_tab_widget);
connect (mp_tab_widget, SIGNAL (currentChanged (int)), this, SLOT (view_selected (int)));
#if QT_VERSION >= 0x040500
mp_tab_bar->setTabsClosable(true);
connect (mp_tab_bar, SIGNAL (tabCloseRequested (int)), this, SLOT (tab_close_requested (int)));
mp_tab_widget->setTabsClosable(true);
connect (mp_tab_widget, SIGNAL (tabCloseRequested (int)), this, SLOT (tab_close_requested (int)));
#endif
mp_hp_dock_widget = new QDockWidget (QObject::tr ("Cells"), this);
@ -682,8 +683,8 @@ MainWindow::close_all ()
// Clear the tab bar
bool f = m_disable_tab_selected;
m_disable_tab_selected = true;
while (mp_tab_bar->count () > 0) {
mp_tab_bar->removeTab (mp_tab_bar->count () - 1);
while (mp_tab_widget->count () > 0) {
mp_tab_widget->removeTab (mp_tab_widget->count () - 1);
}
m_disable_tab_selected = f;
@ -745,8 +746,8 @@ MainWindow::about_to_exec ()
// TODO: later, each view may get it's own editable flag
if (lay::ApplicationBase::instance () && !lay::ApplicationBase::instance ()->is_editable ()) {
TipDialog td (this,
tl::to_string (QObject::tr ("KLayout has been started in viewer mode. In this mode, editor functions are not available.\n\nTo enable these functions, start KLayout in editor mode by using the \"-e\" command line switch or select it as the default mode in the setup dialog. Choose \"Setup\" in the \"File\" menu and check \"Use editing mode by default\" on the \"Editing Mode\" page in the \"Application\" section.")),
TipDialog td (this,
tl::to_string (QObject::tr ("KLayout has been started in viewer mode. In this mode, editor functions are not available.\n\nTo enable these functions, start KLayout in editor mode by using the \"-e\" command line switch or select it as the default mode in the setup dialog. Choose \"Setup\" in the \"File\" menu and check \"Use editing mode by default\" on the \"Editing Mode\" page in the \"Application\" section.")),
"editor-mode");
if (td.exec_dialog ()) {
// Don't bother the user with more dialogs.
@ -2314,7 +2315,7 @@ MainWindow::view_selected (int index)
// Hint: setting the focus to the tab bar avoids problem with dangling keyboard focus.
// Sometimes, the focus was set to the hierarchy level spin buttons which caught Copy&Paste
// events in effect.
mp_tab_bar->setFocus ();
mp_tab_widget->setFocus ();
if (! m_disable_tab_selected) {
select_view (index);
@ -2335,7 +2336,7 @@ MainWindow::select_view (int index)
tl_assert (index >= 0 && index < int (views ()));
mp_tab_bar->setCurrentIndex (index);
mp_tab_widget->setCurrentIndex (index);
bool box_set = (m_synchronized_views && current_view () != 0);
db::DBox box;
@ -2564,7 +2565,7 @@ MainWindow::clone_current_view ()
bool f = m_disable_tab_selected;
m_disable_tab_selected = true;
int index = mp_tab_bar->insertTab (-1, tl::to_qstring (view->title ()));
int index = mp_tab_widget->insertTab (-1, mp_views.back (), tl::to_qstring (view->title ()));
m_disable_tab_selected = f;
view_created_event (index);
@ -2805,7 +2806,7 @@ MainWindow::close_view (int index)
box = view (index)->viewport ().box ();
}
mp_tab_bar->removeTab (index);
mp_tab_widget->removeTab (index);
mp_view_stack->remove_widget (index);
mp_lp_stack->remove_widget (index);
mp_layer_toolbox_stack->remove_widget (index);
@ -3381,7 +3382,7 @@ MainWindow::create_view ()
bool f = m_disable_tab_selected;
m_disable_tab_selected = true;
int index = mp_tab_bar->insertTab (-1, tl::to_qstring (current_view ()->title ()));
int index = mp_tab_widget->insertTab (-1, mp_views.back (), tl::to_qstring (current_view ()->title ()));
m_disable_tab_selected = f;
view_created_event (index);
@ -3444,7 +3445,7 @@ MainWindow::create_or_load_layout (const std::string *filename, const db::LoadLa
bool f = m_disable_tab_selected;
m_disable_tab_selected = true;
int index = mp_tab_bar->insertTab (-1, QString ());
int index = mp_tab_widget->insertTab (-1, mp_views.back (), QString ());
update_tab_title (index);
m_disable_tab_selected = f;
view_created_event (index);
@ -3484,8 +3485,8 @@ MainWindow::update_tab_title (int i)
title += v->title ();
}
if (tl::to_string (mp_tab_bar->tabText (i)) != title) {
mp_tab_bar->setTabText (i, tl::to_qstring (title));
if (tl::to_string (mp_tab_widget->tabText (i)) != title) {
mp_tab_widget->setTabText (i, tl::to_qstring (title));
}
if (v) {
@ -3500,8 +3501,8 @@ MainWindow::update_tab_title (int i)
files += tl::to_string (tr ("(not saved)"));
}
}
if (tl::to_string (mp_tab_bar->tabToolTip (i)) != files) {
mp_tab_bar->setTabToolTip (i, tl::to_qstring (files));
if (tl::to_string (mp_tab_widget->tabToolTip (i)) != files) {
mp_tab_widget->setTabToolTip (i, tl::to_qstring (files));
}
}
}

View File

@ -51,7 +51,7 @@
#include "tlDeferredExecution.h"
#include "gsi.h"
class QTabBar;
class QTabWidget;
class QToolBar;
class QLabel;
class QAction;
@ -110,7 +110,7 @@ public:
*/
MainWindow (QApplication *app = 0, const char *name = "main_window", bool undo_enabled = true);
/**
/**
* @brief Destructor
*/
~MainWindow ();
@ -137,7 +137,7 @@ public:
void close_all ();
/**
* @brief Create a new view
* @brief Create a new view
*
* @return The index of the newly created view
*/
@ -147,7 +147,7 @@ public:
* @brief Startup behaviour immediately before the application is executed.
*
* This method will be called shortly the before the application is executed.
* It is supposed to perform some startup procedure, i.e. displaying tip-of-the-day
* It is supposed to perform some startup procedure, i.e. displaying tip-of-the-day
* windows.
*/
void about_to_exec ();
@ -167,14 +167,14 @@ public:
*/
void restore_session (const std::string &fn);
/**
/**
* @brief Reload the given cellview into the current view
*
* The cellview is given by index in the current view's cellview list.
*/
void reload_layout (unsigned int cv_index);
/**
/**
* @brief Load a (new) file into the layout
*
* The mode param controls how to open the file:
@ -185,7 +185,7 @@ public:
return load_layout (filename, m_initial_technology, mode);
}
/**
/**
* @brief Load a (new) file into the layout and associate it with the given technology
*
* The mode param controls how to open the file:
@ -196,7 +196,7 @@ public:
return load_layout (filename, db::Technologies::instance ()->technology_by_name (technology)->load_layout_options (), technology, mode);
}
/**
/**
* @brief Load a (new) file into the layout using the given options
*
* The mode param controls how to open the file:
@ -207,7 +207,7 @@ public:
return load_layout (filename, options, m_initial_technology, mode);
}
/**
/**
* @brief Load a (new) file into the layout using the given options and technology
*
* The mode param controls how to open the file:
@ -215,7 +215,7 @@ public:
*/
lay::CellViewRef load_layout (const std::string &filename, const db::LoadLayoutOptions &options, const std::string &technology, int mode = 0);
/**
/**
* @brief Create new, empty layout
*
* The mode param controls how to create the layout
@ -226,7 +226,7 @@ public:
return create_layout (m_initial_technology, mode);
}
/**
/**
* @brief Create new, empty layout and associate it with the given technology
*
* The mode param controls how to create the layout
@ -244,33 +244,33 @@ public:
*
* This version will load the layer properties file "as it is". No mapping of cellview index
* is performed. Only adding of missing layers is supported.
* The file name can be an empty string.
* The file name can be an empty string.
*
* @param fn The name of the .lyp file to load.
* @param fn The name of the .lyp file to load.
* @param all_views Apply the .lyp file to all views. If false, load the layer properties for the current view.
* @param add_default Add the missing layers for each view.
*/
void load_layer_properties (const std::string &fn, bool all_views, bool add_default);
/**
* @brief Load a layer definition file for a specific cv
* @brief Load a layer definition file for a specific cv
*
* This version will load the layer properties file and apply it to the given cv. The cv_index
* parameter will denote the cv index to which to apply the layer properties file. It is assumed
* parameter will denote the cv index to which to apply the layer properties file. It is assumed
* that the .lyp file will contain definitions for a single layout only. This definition is
* mapped to the specified cv_index after all definitions for this layout have been removed
* mapped to the specified cv_index after all definitions for this layout have been removed
* from the layer properties list.
* "cv_index" can be -1. In that case, the layer properties file will be loaded multiple times,
* "cv_index" can be -1. In that case, the layer properties file will be loaded multiple times,
* once for each cv present.
*
* @param fn The name of the .lyp file to load.
* @param fn The name of the .lyp file to load.
* @param cv_index See above
* @param all_views Apply the .lyp file to all views. If false, load the layer properties for the current view.
* @param add_default Add the missing layers for each view.
*/
void load_layer_properties (const std::string &fn, int cv_index, bool all_views, bool add_default);
/**
/**
* @brief Grid accessor: get the grid value
*
* This is the version delivering a double value in micron.
@ -367,12 +367,12 @@ public:
*/
bool show_progress_bar (bool show);
/**
/**
* @brief Implementation of the Plugin interface
*/
bool configure (const std::string &name, const std::string &value);
/**
/**
* @brief Implementation of the Plugin interface
*/
void config_finalize ();
@ -383,7 +383,7 @@ public:
* This method returns true if exit () has been called. This state is never reset.
* The main purpose is to detect "exit ()" calls before the event loop is executed.
*/
bool exited ()
bool exited ()
{
return m_exited;
}
@ -393,9 +393,9 @@ public:
*
* In busy state, the main window will not try to ask for saving changes etc.
* Instead, it will ask whether to shut down the application anyway.
* The intention of the busy state is to implement a special behavior while inside a processEvent
* The intention of the busy state is to implement a special behavior while inside a processEvent
* loop.
*/
*/
void enter_busy_mode (bool bm)
{
m_busy = bm;
@ -485,14 +485,14 @@ public:
* @brief Show the assistant with the given URL
*/
void show_assistant_url (const std::string &url, bool modal = false);
/**
* @brief Show the assistant with the given topic
*/
void show_assistant_topic (const std::string &s, bool modal = false);
/**
* @brief Show the macro editor
* @brief Show the macro editor
*
* The category can be given to specify the category to show. If empty, the current category
* is shown.
@ -522,7 +522,7 @@ public:
* @brief Open a new layout in mode 'mode'
*
* If mode is 2, the layout is opened in the current view in addition to the existing ones.
* If mode is 1, the layout is opened in a new view. If mode is 0, the layout is opened in
* If mode is 1, the layout is opened in a new view. If mode is 0, the layout is opened in
* the current view deleting the existing ones.
*/
void open (int mode);
@ -572,7 +572,7 @@ public:
/**
* @brief Gets the technology used for loading or creating layouts
*/
const std::string &initial_technology ()
const std::string &initial_technology ()
{
return m_initial_technology;
}
@ -615,7 +615,7 @@ public slots:
void message (const std::string &s, int ms);
/**
* @brief Clears the current message
* @brief Clears the current message
*/
void clear_message ();
@ -682,7 +682,7 @@ private:
TextProgressDelegate m_text_progress;
// Main menu
QTabBar *mp_tab_bar;
QTabWidget *mp_tab_widget;
QToolBar *mp_tool_bar;
QDockWidget *mp_navigator_dock_widget;
lay::Navigator *mp_navigator;