mirror of https://github.com/KLayout/klayout.git
Merge remote-tracking branch 'upstream/master' into macos-build
This commit is contained in:
commit
9d9996b91d
|
|
@ -1349,13 +1349,17 @@ get_intersections_per_band_any (std::vector <CutPoints> &cutpoints, std::vector
|
|||
// the cutpoint will be a weak attractor - that is an optional cutpoint.
|
||||
// In that case we can skip the cutpoint because no related edge will move.
|
||||
ip_weak.clear ();
|
||||
size_t n_off_edge = on_edge1 ? 0 : 1;
|
||||
for (std::vector <WorkEdge>::iterator cc = c; cc != f; ++cc) {
|
||||
if ((with_h || cc->dy () != 0) && cc != c1 && cc != c2 && is_point_on_fuzzy (*cc, cp.second)) {
|
||||
ip_weak.push_back (&*cc);
|
||||
if (!is_point_on_exact (*cc, cp.second)) {
|
||||
++n_off_edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (std::vector <WorkEdge *>::iterator icc = ip_weak.begin (); icc != ip_weak.end (); ++icc) {
|
||||
if (ip_weak.size () > 1 || !on_edge1) {
|
||||
if (n_off_edge > 1) {
|
||||
(*icc)->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, true);
|
||||
#ifdef DEBUG_EDGE_PROCESSOR
|
||||
printf ("intersection point %s gives cutpoint in %s.\n", cp.second.to_string ().c_str (), (*icc)->to_string ().c_str ());
|
||||
|
|
@ -1435,13 +1439,23 @@ get_intersections_per_band_any (std::vector <CutPoints> &cutpoints, std::vector
|
|||
// the cutpoint will be a weak attractor - that is an optional cutpoint.
|
||||
// In that case we can skip the cutpoint because no related edge will move.
|
||||
ip_weak.clear ();
|
||||
size_t n_off_edge = 0;
|
||||
if (!on_edge1) {
|
||||
n_off_edge += 1;
|
||||
}
|
||||
if (!on_edge2) {
|
||||
n_off_edge += 1;
|
||||
}
|
||||
for (std::vector <WorkEdge>::iterator cc = c; cc != f; ++cc) {
|
||||
if ((with_h || cc->dy () != 0) && cc != c1 && cc != c2 && is_point_on_fuzzy (*cc, cp.second)) {
|
||||
ip_weak.push_back (&*cc);
|
||||
if (!is_point_on_exact (*cc, cp.second)) {
|
||||
++n_off_edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (std::vector <WorkEdge *>::iterator icc = ip_weak.begin (); icc != ip_weak.end (); ++icc) {
|
||||
if (ip_weak.size () > 1 || !on_edge1 || !on_edge2) {
|
||||
if (n_off_edge > 1) {
|
||||
(*icc)->make_cutpoints (cutpoints)->add (cp.second, &cutpoints, true);
|
||||
#ifdef DEBUG_EDGE_PROCESSOR
|
||||
printf ("intersection point %s gives cutpoint in %s.\n", cp.second.to_string ().c_str (), (*icc)->to_string ().c_str ());
|
||||
|
|
|
|||
|
|
@ -1884,6 +1884,26 @@ Layout::is_pcell_instance (cell_index_type cell_index) const
|
|||
}
|
||||
}
|
||||
|
||||
const Layout::pcell_declaration_type *
|
||||
Layout::pcell_declaration_for_pcell_variant (cell_index_type variant_cell_index) const
|
||||
{
|
||||
const Cell *variant_cell = &cell (variant_cell_index);
|
||||
|
||||
const LibraryProxy *lib_proxy = dynamic_cast<const LibraryProxy *> (variant_cell);
|
||||
if (lib_proxy) {
|
||||
Library *lib = LibraryManager::instance ().lib (lib_proxy->lib_id ());
|
||||
tl_assert (lib != 0);
|
||||
return lib->layout ().pcell_declaration_for_pcell_variant (lib_proxy->library_cell_index ());
|
||||
}
|
||||
|
||||
const PCellVariant *pcell_variant = dynamic_cast<const PCellVariant *> (variant_cell);
|
||||
if (pcell_variant) {
|
||||
return pcell_declaration (pcell_variant->pcell_id ());
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<db::Library *, db::cell_index_type>
|
||||
Layout::defining_library (cell_index_type cell_index) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -881,11 +881,22 @@ public:
|
|||
*/
|
||||
std::pair<db::Library *, db::cell_index_type> defining_library (cell_index_type cell_index) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the PCell declaration object for a PCell instance
|
||||
*
|
||||
* This method determines the PCell declaration object for a given PCell variant cell.
|
||||
* Note, that the declaration may originate from a different layout than this, if the PCell
|
||||
* is imported from a library.
|
||||
*
|
||||
* The cell given cell is not a PCell variant cell, 0 is returned.
|
||||
*/
|
||||
const Layout::pcell_declaration_type *pcell_declaration_for_pcell_variant (cell_index_type cell_index) const;
|
||||
|
||||
/**
|
||||
* @brief Get the PCell parameters of a PCell instance
|
||||
*
|
||||
* For the order of the parameters, ask the PCell declaration (available trough Layout::pcell_declaration
|
||||
* from the PCell id).
|
||||
* from the PCell id or from Layout::pcell_declaration_for_pcell_variant from the cell_index).
|
||||
*
|
||||
* @return A list of parameters in the order they are declared.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ Reader::Reader (tl::InputStream &stream)
|
|||
}
|
||||
|
||||
if (! mp_actual_reader) {
|
||||
throw db::ReaderException (tl::to_string (QObject::tr ("Stream has unknown format")));
|
||||
throw db::ReaderException (tl::to_string (QObject::tr ("Stream has unknown format: ")) + stream.source ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2244,3 +2244,54 @@ TEST(100)
|
|||
db::compare_layouts (_this, lr, au_fn);
|
||||
}
|
||||
|
||||
// #74 (GitHub)
|
||||
TEST(101)
|
||||
{
|
||||
db::EdgeProcessor ep;
|
||||
|
||||
{
|
||||
db::Point pts[] = {
|
||||
db::Point (0, 0),
|
||||
db::Point (0, 10),
|
||||
db::Point (10, 10),
|
||||
db::Point (10, 0)
|
||||
};
|
||||
db::Polygon p;
|
||||
p.assign_hull (&pts[0], &pts[sizeof(pts) / sizeof(pts[0])]);
|
||||
ep.insert (p, 0);
|
||||
}
|
||||
|
||||
{
|
||||
db::Point pts[] = {
|
||||
db::Point (-1, -1),
|
||||
db::Point (-1, 8),
|
||||
db::Point (2, 11),
|
||||
db::Point (2, -1)
|
||||
};
|
||||
db::Polygon p;
|
||||
p.assign_hull (&pts[0], &pts[sizeof(pts) / sizeof(pts[0])]);
|
||||
ep.insert (p, 1);
|
||||
}
|
||||
|
||||
{
|
||||
db::Point pts[] = {
|
||||
db::Point (2, -1),
|
||||
db::Point (2, 11),
|
||||
db::Point (11, 11),
|
||||
db::Point (11, -1)
|
||||
};
|
||||
db::Polygon p;
|
||||
p.assign_hull (&pts[0], &pts[sizeof(pts) / sizeof(pts[0])]);
|
||||
ep.insert (p, 1);
|
||||
}
|
||||
|
||||
std::vector<db::Polygon> out;
|
||||
db::PolygonContainer pc (out);
|
||||
db::PolygonGenerator pg (pc, false, true);
|
||||
db::BooleanOp op (db::BooleanOp::And);
|
||||
|
||||
ep.process (pg, op);
|
||||
|
||||
EXPECT_EQ (out.size (), size_t (1));
|
||||
EXPECT_EQ (out[0].to_string (), "(0,0;0,9;1,10;10,10;10,0)");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1906,12 +1906,10 @@ MainService::cm_change_layer ()
|
|||
// get (common) cellview index of the selected shapes
|
||||
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
|
||||
for (edt::Service::obj_iterator s = (*es)->selection ().begin (); s != (*es)->selection ().end (); ++s) {
|
||||
if (! s->is_cell_inst ()) {
|
||||
if (cv_index >= 0 && cv_index != int (s->cv_index ())) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Selections originate from different layouts - cannot switch layer in this case.")));
|
||||
}
|
||||
cv_index = int (s->cv_index ());
|
||||
if (cv_index >= 0 && cv_index != int (s->cv_index ())) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Selections originate from different layouts - cannot switch layer in this case.")));
|
||||
}
|
||||
cv_index = int (s->cv_index ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1975,17 +1973,58 @@ MainService::cm_change_layer ()
|
|||
// Insert and delete the shape. This exploits the fact, that a shape can be erased multiple times -
|
||||
// this is important since the selection potentially contains the same shape multiple times.
|
||||
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
|
||||
|
||||
for (edt::Service::obj_iterator s = (*es)->selection ().begin (); s != (*es)->selection ().end (); ++s) {
|
||||
|
||||
if (!s->is_cell_inst () && int (s->layer ()) != layer) {
|
||||
|
||||
db::Cell &cell = layout.cell (s->cell_index ());
|
||||
if (cell.shapes (s->layer ()).is_valid (s->shape ())) {
|
||||
cell.shapes (layer).insert (s->shape ());
|
||||
cell.shapes (s->layer ()).erase_shape (s->shape ());
|
||||
}
|
||||
|
||||
} else if (s->is_cell_inst ()) {
|
||||
|
||||
// If the selected object is a PCell instance, and there is exactly one visible, writable layer type parameter, change this one
|
||||
|
||||
db::Instance inst = s->back ().inst_ptr;
|
||||
db::Cell &cell = layout.cell (s->cell_index ());
|
||||
|
||||
if (cell.is_valid (inst)) {
|
||||
|
||||
const db::PCellDeclaration *pcell_decl = layout.pcell_declaration_for_pcell_variant (inst.cell_index ());
|
||||
if (pcell_decl) {
|
||||
|
||||
size_t layer_par_index = 0;
|
||||
int n_layer_par = 0;
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator d = pcell_decl->parameter_declarations ().begin (); d != pcell_decl->parameter_declarations ().end () && n_layer_par < 2; ++d) {
|
||||
if (d->get_type () == db::PCellParameterDeclaration::t_layer && !d->is_hidden () && !d->is_readonly ()) {
|
||||
++n_layer_par;
|
||||
layer_par_index = size_t (d - pcell_decl->parameter_declarations ().begin ());
|
||||
}
|
||||
}
|
||||
|
||||
if (n_layer_par == 1) {
|
||||
std::vector<tl::Variant> parameters = cell.get_pcell_parameters (inst);
|
||||
tl_assert (layer_par_index < parameters.size ());
|
||||
parameters [layer_par_index] = layout.get_properties (layer);
|
||||
cell.change_pcell_parameters (inst, parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remove superfluous proxies
|
||||
layout.cleanup ();
|
||||
|
||||
// The selection is no longer valid
|
||||
view ()->clear_selection ();
|
||||
|
||||
|
|
|
|||
|
|
@ -609,11 +609,6 @@ MainWindow::MainWindow (QApplication *app, const char *name)
|
|||
cp_frame_ly->addWidget (mp_cpy_label);
|
||||
cp_frame_ly->insertSpacing (-1, 6);
|
||||
|
||||
// connect to the menus to provide the dynamic parts
|
||||
QMenu *bookmark_menu = mp_menu->menu ("bookmark_menu");
|
||||
tl_assert (bookmark_menu != 0);
|
||||
connect (bookmark_menu, SIGNAL (aboutToShow ()), this, SLOT (bookmark_menu_show ()));
|
||||
|
||||
// select the default mode
|
||||
select_mode (lay::LayoutView::default_mode ());
|
||||
|
||||
|
|
@ -1798,6 +1793,12 @@ MainWindow::edits_enabled_changed ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::menu_needs_update ()
|
||||
{
|
||||
lay::LayoutView::update_menu (current_view (), *mp_menu);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::libraries_changed ()
|
||||
{
|
||||
|
|
@ -2426,57 +2427,6 @@ MainWindow::cm_redo ()
|
|||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::bookmark_menu_show ()
|
||||
{
|
||||
if (mp_menu->is_valid ("bookmark_menu.goto_bookmark_menu")) {
|
||||
|
||||
Action goto_bookmark_action = mp_menu->action ("bookmark_menu.goto_bookmark_menu");
|
||||
bool has_bookmarks = current_view () && current_view ()->bookmarks ().size () > 0;
|
||||
|
||||
if (has_bookmarks && edits_enabled ()) {
|
||||
|
||||
goto_bookmark_action.set_enabled (true);
|
||||
|
||||
QMenu *goto_bookmark_menu = goto_bookmark_action.qaction ()->menu ();
|
||||
if (goto_bookmark_menu) {
|
||||
|
||||
goto_bookmark_menu->clear ();
|
||||
|
||||
if (current_view ()) {
|
||||
const lay::BookmarkList &bookmarks = current_view ()->bookmarks ();
|
||||
for (size_t i = 0; i < bookmarks.size (); ++i) {
|
||||
QAction *action = goto_bookmark_menu->addAction (tl::to_qstring (bookmarks.name (i)));
|
||||
action->setObjectName (tl::to_qstring (tl::sprintf ("bookmark_%d", i + 1)));
|
||||
gtf::action_connect (action, SIGNAL (triggered ()), this, SLOT (goto_bookmark ()));
|
||||
action->setData (QVariant (int (i)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
goto_bookmark_action.set_enabled (false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::goto_bookmark ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
QAction *action = dynamic_cast <QAction *> (sender ());
|
||||
tl_assert (action);
|
||||
size_t id = size_t (action->data ().toInt ());
|
||||
if (current_view () && current_view ()->bookmarks ().size () > id) {
|
||||
current_view ()->goto_view (current_view ()->bookmarks ().state (id));
|
||||
}
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::cm_goto_position ()
|
||||
{
|
||||
|
|
@ -2580,19 +2530,7 @@ MainWindow::cm_bookmark_view ()
|
|||
BEGIN_PROTECTED
|
||||
|
||||
if (current_view ()) {
|
||||
while (true) {
|
||||
bool ok = false;
|
||||
QString text = QInputDialog::getText (this, QObject::tr ("Enter Bookmark Name"), QObject::tr ("Bookmark name"),
|
||||
QLineEdit::Normal, QString::null, &ok);
|
||||
if (! ok) {
|
||||
break;
|
||||
} else if (text.isEmpty ()) {
|
||||
QMessageBox::critical (this, QObject::tr ("Error"), QObject::tr ("Enter a name for the bookmark"));
|
||||
} else {
|
||||
current_view ()->bookmark_view (tl::to_string (text));
|
||||
break;
|
||||
}
|
||||
}
|
||||
current_view ()->bookmark_current_view ();
|
||||
}
|
||||
|
||||
END_PROTECTED
|
||||
|
|
@ -3359,6 +3297,7 @@ MainWindow::select_view (int index)
|
|||
clear_current_pos ();
|
||||
edits_enabled_changed ();
|
||||
clear_message ();
|
||||
menu_needs_update ();
|
||||
|
||||
m_disable_tab_selected = dis;
|
||||
|
||||
|
|
@ -3738,6 +3677,7 @@ MainWindow::clone_current_view ()
|
|||
connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ()));
|
||||
connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ()));
|
||||
connect (view, SIGNAL (edits_enabled_changed ()), this, SLOT (edits_enabled_changed ()));
|
||||
connect (view, SIGNAL (menu_needs_update ()), this, SLOT (menu_needs_update ()));
|
||||
connect (view, SIGNAL (show_message (const std::string &, int)), this, SLOT (message (const std::string &, int)));
|
||||
connect (view, SIGNAL (current_pos_changed (double, double, bool)), this, SLOT (current_pos (double, double, bool)));
|
||||
connect (view, SIGNAL (clear_current_pos ()), this, SLOT (clear_current_pos ()));
|
||||
|
|
@ -4041,6 +3981,7 @@ MainWindow::close_view (int index)
|
|||
|
||||
clear_current_pos ();
|
||||
edits_enabled_changed ();
|
||||
menu_needs_update ();
|
||||
clear_message ();
|
||||
|
||||
update_dock_widget_state ();
|
||||
|
|
@ -4184,10 +4125,7 @@ MainWindow::do_update_file_menu ()
|
|||
if (m_mru.size () > 0 && edits_enabled ()) {
|
||||
|
||||
// rebuild MRU menu
|
||||
std::vector<std::string> items = mp_menu->items (mru_menu);
|
||||
for (std::vector<std::string>::const_iterator i = items.begin (); i != items.end (); ++i) {
|
||||
mp_menu->delete_item (mru_menu + "." + *i);
|
||||
}
|
||||
mp_menu->clear_menu (mru_menu);
|
||||
|
||||
for (std::vector<std::pair<std::string, std::string> >::iterator mru = m_mru.end (); mru != m_mru.begin (); ) {
|
||||
--mru;
|
||||
|
|
@ -4349,6 +4287,7 @@ MainWindow::do_create_view ()
|
|||
connect (view, SIGNAL (title_changed ()), this, SLOT (view_title_changed ()));
|
||||
connect (view, SIGNAL (dirty_changed ()), this, SLOT (view_title_changed ()));
|
||||
connect (view, SIGNAL (edits_enabled_changed ()), this, SLOT (edits_enabled_changed ()));
|
||||
connect (view, SIGNAL (menu_needs_update ()), this, SLOT (menu_needs_update ()));
|
||||
connect (view, SIGNAL (show_message (const std::string &, int)), this, SLOT (message (const std::string &, int)));
|
||||
connect (view, SIGNAL (current_pos_changed (double, double, bool)), this, SLOT (current_pos (double, double, bool)));
|
||||
connect (view, SIGNAL (clear_current_pos ()), this, SLOT (clear_current_pos ()));
|
||||
|
|
|
|||
|
|
@ -689,7 +689,6 @@ public slots:
|
|||
void tab_close_requested (int);
|
||||
void enable_all ();
|
||||
void disable_all ();
|
||||
void goto_bookmark ();
|
||||
void open_recent ();
|
||||
void view_selected (int index);
|
||||
void view_title_changed ();
|
||||
|
|
@ -858,8 +857,9 @@ public slots:
|
|||
protected slots:
|
||||
void menu_changed ();
|
||||
void message_timer ();
|
||||
void bookmark_menu_show ();
|
||||
void edits_enabled_changed ();
|
||||
void menu_needs_update ();
|
||||
|
||||
void file_changed_timer ();
|
||||
void file_changed (const QString &path);
|
||||
void file_removed (const QString &path);
|
||||
|
|
@ -874,7 +874,6 @@ private:
|
|||
|
||||
// Main menu
|
||||
AbstractMenu *mp_menu;
|
||||
QMenu *mp_goto_bookmark_menu;
|
||||
QTabBar *mp_tab_bar;
|
||||
QToolBar *mp_tool_bar;
|
||||
QDockWidget *mp_navigator_dock_widget;
|
||||
|
|
|
|||
|
|
@ -1354,6 +1354,17 @@ AbstractMenu::insert_menu (const std::string &path, const std::string &name, con
|
|||
insert_menu (path, name, create_action (title));
|
||||
}
|
||||
|
||||
void
|
||||
AbstractMenu::clear_menu (const std::string &p)
|
||||
{
|
||||
typedef std::vector<std::pair<AbstractMenuItem *, std::list<AbstractMenuItem>::iterator > > path_type;
|
||||
path_type path = find_item (p);
|
||||
if (! path.empty () && ! path.back ().second->children.empty ()) {
|
||||
path.back ().second->children.clear ();
|
||||
emit changed ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AbstractMenu::delete_item (const std::string &p)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -784,6 +784,13 @@ public:
|
|||
*/
|
||||
void insert_menu (const std::string &path, const std::string &name, const std::string &title);
|
||||
|
||||
/**
|
||||
* @brief Deletes the children of the item with the given path
|
||||
*
|
||||
* If the item does not exist or is not a menu, this method does nothing.
|
||||
*/
|
||||
void clear_menu (const std::string &path);
|
||||
|
||||
/**
|
||||
* @brief Delete the item given by the path
|
||||
*
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "tlString.h"
|
||||
#include "tlLog.h"
|
||||
#include "tlAssert.h"
|
||||
#include "tlExceptions.h"
|
||||
#include "layLayoutView.h"
|
||||
#include "layViewOp.h"
|
||||
#include "layViewObject.h"
|
||||
|
|
@ -74,6 +75,7 @@
|
|||
#include "rdbMarkerBrowserDialog.h"
|
||||
#include "tlXMLParser.h"
|
||||
#include "gsi.h"
|
||||
#include "gtf.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
|
@ -772,6 +774,37 @@ LayoutView::init_menu (lay::AbstractMenu &menu)
|
|||
lay::HierarchyControlPanel::init_menu (menu);
|
||||
}
|
||||
|
||||
void
|
||||
LayoutView::update_menu (lay::LayoutView *view, lay::AbstractMenu &menu)
|
||||
{
|
||||
std::string bm_menu = "bookmark_menu.goto_bookmark_menu";
|
||||
|
||||
if (menu.is_valid (bm_menu)) {
|
||||
|
||||
menu.clear_menu (bm_menu);
|
||||
|
||||
Action goto_bookmark_action = menu.action (bm_menu);
|
||||
|
||||
if (view && view->bookmarks ().size () > 0) {
|
||||
|
||||
goto_bookmark_action.set_enabled (true);
|
||||
|
||||
const lay::BookmarkList &bookmarks = view->bookmarks ();
|
||||
for (size_t i = 0; i < bookmarks.size (); ++i) {
|
||||
Action action;
|
||||
gtf::action_connect (action.qaction (), SIGNAL (triggered ()), view, SLOT (goto_bookmark ()));
|
||||
action.set_title (bookmarks.name (i));
|
||||
action.qaction ()->setData (QVariant (int (i)));
|
||||
menu.insert_item (bm_menu + ".end", tl::sprintf ("bookmark_%d", i + 1), action);
|
||||
}
|
||||
|
||||
} else {
|
||||
goto_bookmark_action.set_enabled (false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayoutView::set_drawing_workers (int workers)
|
||||
{
|
||||
|
|
@ -3650,6 +3683,24 @@ LayoutView::cancel ()
|
|||
clear_selection ();
|
||||
}
|
||||
|
||||
void
|
||||
LayoutView::bookmark_current_view ()
|
||||
{
|
||||
while (true) {
|
||||
bool ok = false;
|
||||
QString text = QInputDialog::getText (this, QObject::tr ("Enter Bookmark Name"), QObject::tr ("Bookmark name"),
|
||||
QLineEdit::Normal, QString::null, &ok);
|
||||
if (! ok) {
|
||||
break;
|
||||
} else if (text.isEmpty ()) {
|
||||
QMessageBox::critical (this, QObject::tr ("Error"), QObject::tr ("Enter a name for the bookmark"));
|
||||
} else {
|
||||
bookmark_view (tl::to_string (text));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayoutView::manage_bookmarks ()
|
||||
{
|
||||
|
|
@ -3663,6 +3714,7 @@ void
|
|||
LayoutView::bookmarks (const BookmarkList &b)
|
||||
{
|
||||
m_bookmarks = b;
|
||||
emit menu_needs_update ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3670,6 +3722,22 @@ LayoutView::bookmark_view (const std::string &name)
|
|||
{
|
||||
DisplayState state (box (), get_min_hier_levels (), get_max_hier_levels (), m_cellviews);
|
||||
m_bookmarks.add (name, state);
|
||||
emit menu_needs_update ();
|
||||
}
|
||||
|
||||
void
|
||||
LayoutView::goto_bookmark ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
QAction *action = dynamic_cast <QAction *> (sender ());
|
||||
tl_assert (action);
|
||||
size_t id = size_t (action->data ().toInt ());
|
||||
if (bookmarks ().size () > id) {
|
||||
goto_view (bookmarks ().state (id));
|
||||
}
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1557,6 +1557,11 @@ public:
|
|||
*/
|
||||
void bookmark_view (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Asks for a bookmark name and bookmark the current view under this name
|
||||
*/
|
||||
void bookmark_current_view ();
|
||||
|
||||
/**
|
||||
* @brief Show the bookmark management form
|
||||
*/
|
||||
|
|
@ -1603,6 +1608,12 @@ public:
|
|||
*/
|
||||
static void init_menu (lay::AbstractMenu &menu);
|
||||
|
||||
/**
|
||||
* @brief Updates the menu for the given view
|
||||
* If the view is 0, the menu shall be updated to reflect "no view active"
|
||||
*/
|
||||
static void update_menu (lay::LayoutView *view, lay::AbstractMenu &menu);
|
||||
|
||||
/**
|
||||
* @brief Query the default mode
|
||||
*/
|
||||
|
|
@ -2530,6 +2541,7 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void active_cellview_changed (int index);
|
||||
void goto_bookmark ();
|
||||
|
||||
signals:
|
||||
/**
|
||||
|
|
@ -2562,6 +2574,11 @@ signals:
|
|||
*/
|
||||
void edits_enabled_changed ();
|
||||
|
||||
/**
|
||||
* @brief This signal is sent when the view wants to update the menu
|
||||
*/
|
||||
void menu_needs_update ();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Establish the view operations
|
||||
|
|
|
|||
|
|
@ -124,5 +124,14 @@ TEST(1)
|
|||
|
||||
menu.delete_item ("n1.c2");
|
||||
EXPECT_EQ (menu_to_string (menu), "(n2)");
|
||||
}
|
||||
|
||||
menu.clear_menu ("n1");
|
||||
EXPECT_EQ (menu_to_string (menu), "(n2)");
|
||||
|
||||
menu.insert_menu ("end", "n1", lay::Action ("title:n1"));
|
||||
menu.insert_item ("n1.begin", "c1", lay::Action ("title:c1"));
|
||||
menu.insert_item ("n1.end", "c2", lay::Action ("title:c2"));
|
||||
EXPECT_EQ (menu_to_string (menu), "(n2,n1(n1.c1,n1.c2))");
|
||||
menu.clear_menu ("n1");
|
||||
EXPECT_EQ (menu_to_string (menu), "(n2,n1)");
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue