mirror of https://github.com/KLayout/klayout.git
WIP: library browser - basic setup. Not much functionality yet.
This commit is contained in:
parent
5faf762571
commit
0c18171e63
|
|
@ -28,6 +28,7 @@
|
|||
#include "gsiObject.h"
|
||||
#include "dbLayout.h"
|
||||
#include "tlTypeTraits.h"
|
||||
#include "tlObject.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -45,7 +46,7 @@ class Layout;
|
|||
* is provided. To do so, this class must be reimplemented.
|
||||
*/
|
||||
class DB_PUBLIC Library
|
||||
: public gsi::ObjectBase
|
||||
: public gsi::ObjectBase, public tl::Object
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -284,9 +284,22 @@ CellTreeModel::~CellTreeModel ()
|
|||
void
|
||||
CellTreeModel::configure (lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
{
|
||||
bool flat = ((flags & Flat) != 0) && ((flags & TopCells) == 0);
|
||||
db::Layout *layout = & view->cellview (cv_index)->layout ();
|
||||
|
||||
do_configure (layout, view, cv_index, flags, base, sorting);
|
||||
}
|
||||
|
||||
void
|
||||
CellTreeModel::configure (db::Layout *layout, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
{
|
||||
do_configure (layout, 0, -1, flags, base, sorting);
|
||||
}
|
||||
|
||||
void
|
||||
CellTreeModel::do_configure (db::Layout *layout, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
{
|
||||
bool flat = ((flags & Flat) != 0) && ((flags & TopCells) == 0);
|
||||
|
||||
bool need_reset = false;
|
||||
if (flat != m_flat || layout != mp_layout || view != mp_view) {
|
||||
|
||||
|
|
@ -300,13 +313,17 @@ CellTreeModel::configure (lay::LayoutView *view, int cv_index, unsigned int flag
|
|||
|
||||
if (view != mp_view) {
|
||||
|
||||
mp_view->cell_visibility_changed_event.remove (this, &CellTreeModel::signal_data_changed);
|
||||
mp_view->cellview_changed_event.remove (this, &CellTreeModel::signal_data_changed_with_int);
|
||||
if (mp_view) {
|
||||
mp_view->cell_visibility_changed_event.remove (this, &CellTreeModel::signal_data_changed);
|
||||
mp_view->cellview_changed_event.remove (this, &CellTreeModel::signal_data_changed_with_int);
|
||||
}
|
||||
|
||||
mp_view = view;
|
||||
|
||||
mp_view->cell_visibility_changed_event.add (this, &CellTreeModel::signal_data_changed);
|
||||
mp_view->cellview_changed_event.add (this, &CellTreeModel::signal_data_changed_with_int);
|
||||
if (mp_view) {
|
||||
mp_view->cell_visibility_changed_event.add (this, &CellTreeModel::signal_data_changed);
|
||||
mp_view->cellview_changed_event.add (this, &CellTreeModel::signal_data_changed_with_int);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -406,7 +423,7 @@ void
|
|||
CellTreeModel::set_sorting (Sorting s)
|
||||
{
|
||||
if (s != m_sorting) {
|
||||
configure (mp_view, m_cv_index, m_flags, mp_base, s);
|
||||
do_configure (mp_layout, mp_view, m_cv_index, m_flags, mp_base, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,10 +104,15 @@ public:
|
|||
virtual QMimeData *mimeData (const QModelIndexList &indexes) const;
|
||||
|
||||
/**
|
||||
* @brief Reconfigures the model
|
||||
* @brief Reconfigures the model with a LayoutView
|
||||
*/
|
||||
void configure (lay::LayoutView *view, int cv_index, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName);
|
||||
|
||||
/**
|
||||
* @brief Reconfigures the model with a pure Layout view
|
||||
*/
|
||||
void configure (db::Layout *layout, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName);
|
||||
|
||||
/**
|
||||
* @brief Gets the layout this model is connected to
|
||||
*/
|
||||
|
|
@ -219,7 +224,7 @@ private:
|
|||
Sorting m_sorting;
|
||||
QWidget *mp_parent;
|
||||
lay::LayoutView *mp_view;
|
||||
const db::Layout *mp_layout;
|
||||
db::Layout *mp_layout;
|
||||
int m_cv_index;
|
||||
const db::Cell *mp_base;
|
||||
std::vector <CellTreeItem *> m_toplevel;
|
||||
|
|
@ -230,6 +235,7 @@ private:
|
|||
void build_top_level ();
|
||||
void clear_top_level ();
|
||||
void search_children (const tl::GlobPattern &pattern, CellTreeItem *item);
|
||||
void do_configure (db::Layout *layout, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
#include "dbRecursiveShapeIterator.h"
|
||||
#include "dbManager.h"
|
||||
#include "dbEdgeProcessor.h"
|
||||
#include "dbLibrary.h"
|
||||
#include "rdb.h"
|
||||
#include "rdbMarkerBrowserDialog.h"
|
||||
#include "dbLayoutToNetlist.h"
|
||||
|
|
@ -508,8 +509,8 @@ LayoutView::init (db::Manager *mgr, lay::PluginRoot *root, QWidget * /*parent*/)
|
|||
|
||||
#if 0 // @@@
|
||||
connect (mp_libraries_view, SIGNAL (cell_selected (cell_path_type, int)), this, SLOT (select_cell_dispatch (cell_path_type, int)));
|
||||
connect (mp_libraries_view, SIGNAL (active_cellview_changed (int)), this, SLOT (active_cellview_changed (int)));
|
||||
#endif
|
||||
connect (mp_libraries_view, SIGNAL (active_library_changed (int)), this, SLOT (active_library_changed (int)));
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -818,6 +819,7 @@ LayoutView::init_menu (lay::AbstractMenu &menu)
|
|||
{
|
||||
lay::LayerControlPanel::init_menu (menu);
|
||||
lay::HierarchyControlPanel::init_menu (menu);
|
||||
lay::LibrariesView::init_menu (menu);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -979,6 +981,22 @@ LayoutView::configure (const std::string &name, const std::string &value)
|
|||
}
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_split_lib_views) {
|
||||
|
||||
bool f;
|
||||
tl::from_string (value, f);
|
||||
if (mp_libraries_view) {
|
||||
mp_libraries_view->set_split_mode (f);
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_current_lib_view) {
|
||||
|
||||
if (mp_libraries_view) {
|
||||
mp_libraries_view->select_active_lib_by_name (value);
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_cell_list_sorting) {
|
||||
|
||||
if (mp_hierarchy_panel) {
|
||||
|
|
@ -4500,6 +4518,11 @@ LayoutView::background_color (QColor c)
|
|||
mp_hierarchy_panel->set_text_color (contrast);
|
||||
}
|
||||
|
||||
if (mp_libraries_view) {
|
||||
mp_libraries_view->set_background_color (c);
|
||||
mp_libraries_view->set_text_color (contrast);
|
||||
}
|
||||
|
||||
if (mp_selection_service) {
|
||||
mp_selection_service->set_colors (c, contrast);
|
||||
}
|
||||
|
|
@ -4578,6 +4601,19 @@ LayoutView::active_cellview_changed (int index)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
LayoutView::active_library_changed (int /*index*/)
|
||||
{
|
||||
std::string lib_name;
|
||||
if (mp_libraries_view->active_lib ()) {
|
||||
lib_name = mp_libraries_view->active_lib ()->get_name ();
|
||||
}
|
||||
|
||||
// commit the new active library to the other views and persist this state
|
||||
// TODO: could be passed through the LibraryController (like through some LibraryController::active_library)
|
||||
plugin_root ()->config_set (cfg_current_lib_view, lib_name);
|
||||
}
|
||||
|
||||
void
|
||||
LayoutView::cellview_changed (unsigned int index)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2637,6 +2637,7 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void active_cellview_changed (int index);
|
||||
void active_library_changed (int index);
|
||||
void goto_bookmark ();
|
||||
|
||||
signals:
|
||||
|
|
|
|||
|
|
@ -1486,6 +1486,8 @@ public:
|
|||
options.push_back (std::pair<std::string, std::string> (cfg_flat_cell_list, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_split_cell_list, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_cell_list_sorting, "by-name"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_split_lib_views, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_current_lib_view, ""));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_hide_empty_layers, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_min_inst_label_size, "16"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_cell_box_text_font, "0"));
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
|
||||
#include "dbClipboard.h"
|
||||
#include "dbClipboardData.h"
|
||||
#include "dbLibraryManager.h"
|
||||
#include "dbLibrary.h"
|
||||
#include "layLibrariesView.h"
|
||||
#include "layCellTreeModel.h"
|
||||
#include "layLayoutView.h"
|
||||
|
|
@ -200,7 +202,10 @@ void
|
|||
LibrariesView::init_menu (lay::AbstractMenu &menu)
|
||||
{
|
||||
MenuLayoutEntry context_menu [] = {
|
||||
MenuLayoutEntry ("split_mode", tl::to_string (QObject::tr ("Split Mode")), std::make_pair (cfg_split_cell_list, "?")),
|
||||
#if 0
|
||||
// doesn't make sense for many libs
|
||||
MenuLayoutEntry ("split_mode", tl::to_string (QObject::tr ("Split Mode")), std::make_pair (cfg_split_lib_views, "?")),
|
||||
#endif
|
||||
#if 0 // @@@
|
||||
MenuLayoutEntry::separator ("operations_group"),
|
||||
MenuLayoutEntry ("new_cell:edit:edit_mode", tl::to_string (QObject::tr ("New Cell")), SLOT (cm_new_cell ())),
|
||||
|
|
@ -328,10 +333,7 @@ LibrariesView::LibrariesView (lay::LayoutView *view, QWidget *parent, const char
|
|||
sp.setVerticalStretch (0);
|
||||
setSizePolicy (sp);
|
||||
|
||||
#if 0 // @@@ TODO: attach to library controller
|
||||
mp_view->cellviews_changed_event.add (this, &LibrariesView::update_required);
|
||||
mp_view->hier_changed_event.add (this, &LibrariesView::update_required);
|
||||
#endif
|
||||
db::LibraryManager::instance ().changed_event.add (this, &LibrariesView::update_required);
|
||||
|
||||
do_update_content ();
|
||||
}
|
||||
|
|
@ -680,12 +682,17 @@ LibrariesView::set_text_color (QColor c)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0 // @@@
|
||||
void
|
||||
LibrariesView::update_required ()
|
||||
{
|
||||
m_do_full_update_content_dm ();
|
||||
}
|
||||
|
||||
void
|
||||
LibrariesView::do_full_update_content ()
|
||||
{
|
||||
size_t i = 0;
|
||||
for (std::vector <lay::CellView>::const_iterator cv = m_cellviews.begin (); cv != m_cellviews.end (); ++cv, ++i) {
|
||||
for (db::LibraryManager::iterator lib = db::LibraryManager::instance ().begin (); lib != db::LibraryManager::instance ().end (); ++lib, ++i) {
|
||||
if (m_needs_update.size () > i) {
|
||||
m_needs_update [i] = true;
|
||||
}
|
||||
|
|
@ -698,20 +705,213 @@ LibrariesView::do_full_update_content ()
|
|||
}
|
||||
|
||||
void
|
||||
LibrariesView::update_required ()
|
||||
LibrariesView::do_update_content (int lib_index)
|
||||
{
|
||||
m_do_full_update_content_dm ();
|
||||
// close the search box since we will modify the model
|
||||
mp_search_frame->hide ();
|
||||
mp_search_model = 0;
|
||||
|
||||
size_t imin = (lib_index < 0 ? 0 : (size_t) lib_index);
|
||||
size_t imax = (lib_index < 0 ? std::numeric_limits <size_t>::max () : (size_t) lib_index);
|
||||
|
||||
std::vector<db::Library *> libraries;
|
||||
for (db::LibraryManager::iterator lib = db::LibraryManager::instance ().begin (); lib != db::LibraryManager::instance ().end (); ++lib) {
|
||||
libraries.push_back (db::LibraryManager::instance ().lib (lib->second));
|
||||
}
|
||||
|
||||
for (size_t i = imin; i < libraries.size () && i <= imax; ++i) {
|
||||
if (i < m_libraries.size () && ! m_libraries[i].get ()) {
|
||||
tl_assert (i < m_force_close.size ());
|
||||
m_force_close [i] = true;
|
||||
}
|
||||
if (i >= m_force_close.size ()) {
|
||||
m_force_close.push_back (true);
|
||||
}
|
||||
if (i >= m_needs_update.size ()) {
|
||||
m_needs_update.push_back (true);
|
||||
}
|
||||
if (i >= libraries.size ()) {
|
||||
m_force_close [i] = true;
|
||||
m_needs_update [i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
size_t n = std::min (m_libraries.size (), libraries.size ());
|
||||
for (size_t i = imin; i < n && i <= imax; ++i) {
|
||||
|
||||
if (m_libraries [i].get () != libraries [i]) {
|
||||
m_needs_update [i] = true;
|
||||
m_force_close [i] = true;
|
||||
}
|
||||
|
||||
if (m_needs_update [i]) {
|
||||
mp_cell_lists [i]->doItemsLayout (); // triggers a redraw
|
||||
}
|
||||
|
||||
m_libraries [i].reset (libraries [i]);
|
||||
|
||||
}
|
||||
|
||||
if (m_libraries.size () < libraries.size ()) {
|
||||
for (size_t i = n; i < libraries.size (); ++i) {
|
||||
m_libraries.push_back (tl::weak_ptr<db::Library> (libraries [i]));
|
||||
}
|
||||
} else if (m_libraries.size () > libraries.size ()) {
|
||||
m_libraries.erase (m_libraries.begin () + libraries.size (), m_libraries.end ());
|
||||
}
|
||||
|
||||
bool split_mode = m_split_mode;
|
||||
// for more than max_cellviews_in_split_mode cellviews, switch to overlay mode
|
||||
if (int (m_libraries.size ()) > max_cellviews_in_split_mode) {
|
||||
split_mode = false;
|
||||
}
|
||||
|
||||
while (mp_cell_lists.size () < m_libraries.size ()) {
|
||||
|
||||
size_t i = mp_cell_lists.size ();
|
||||
|
||||
QPalette pl;
|
||||
|
||||
QFrame *cl_frame = new QFrame (this);
|
||||
cl_frame->setFrameShape (QFrame::NoFrame);
|
||||
QVBoxLayout *cl_ly = new QVBoxLayout (cl_frame);
|
||||
cl_ly->setSpacing (0);
|
||||
cl_ly->setContentsMargins (0, 0, 0, 0);
|
||||
|
||||
QToolButton *header = new QToolButton (cl_frame);
|
||||
connect (header, SIGNAL (clicked ()), this, SLOT (header_clicked ()));
|
||||
header->setText (tl::to_qstring (display_string (int (i))));
|
||||
header->setFocusPolicy (Qt::NoFocus);
|
||||
header->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
header->setCheckable (true);
|
||||
header->setAutoRaise (true);
|
||||
header->setAutoFillBackground (true);
|
||||
header->setVisible (split_mode);
|
||||
cl_ly->addWidget (header);
|
||||
|
||||
LibraryTreeWidget *cell_list = new LibraryTreeWidget (cl_frame, "tree", mp_view->view_object_widget ());
|
||||
cl_ly->addWidget (cell_list);
|
||||
cell_list->setModel (new CellTreeModel (cell_list, &m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells, 0));
|
||||
cell_list->setUniformRowHeights (true);
|
||||
|
||||
pl = cell_list->palette ();
|
||||
if (m_text_color.isValid ()) {
|
||||
pl.setColor (QPalette::Text, m_text_color);
|
||||
}
|
||||
if (m_background_color.isValid ()) {
|
||||
pl.setColor (QPalette::Base, m_background_color);
|
||||
}
|
||||
cell_list->setPalette (pl);
|
||||
|
||||
cell_list->header ()->hide ();
|
||||
cell_list->setSelectionMode (QTreeView::ExtendedSelection);
|
||||
cell_list->setRootIsDecorated (false);
|
||||
cell_list->setContextMenuPolicy (Qt::CustomContextMenu);
|
||||
|
||||
connect (cell_list, SIGNAL (customContextMenuRequested (const QPoint &)), this, SLOT (context_menu (const QPoint &)));
|
||||
#if 0 // @@@
|
||||
connect (cell_list, SIGNAL (cell_clicked (const QModelIndex &)), this, SLOT (clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (cell_double_clicked (const QModelIndex &)), this, SLOT (double_clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (cell_middle_clicked (const QModelIndex &)), this, SLOT (middle_clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (search_triggered (const QString &)), this, SLOT (search_triggered (const QString &)));
|
||||
#endif
|
||||
|
||||
mp_cell_lists.push_back (cell_list);
|
||||
mp_cell_list_frames.push_back (cl_frame);
|
||||
mp_cell_list_headers.push_back (header);
|
||||
|
||||
mp_splitter->addWidget (cl_frame);
|
||||
|
||||
}
|
||||
|
||||
while (mp_cell_lists.size () > m_libraries.size ()) {
|
||||
delete mp_cell_list_frames.back ();
|
||||
mp_cell_list_frames.pop_back ();
|
||||
mp_cell_list_headers.pop_back ();
|
||||
mp_cell_lists.pop_back ();
|
||||
}
|
||||
|
||||
for (unsigned int i = imin; i < m_libraries.size () && i < (unsigned int) mp_selector->count () && i <= imax; ++i) {
|
||||
mp_selector->setItemText (i, tl::to_qstring (display_string (i)));
|
||||
}
|
||||
while (mp_selector->count () < int (m_libraries.size ())) {
|
||||
mp_selector->addItem (tl::to_qstring (display_string (mp_selector->count ())));
|
||||
}
|
||||
while (mp_selector->count () > int (m_libraries.size ())) {
|
||||
mp_selector->removeItem (mp_selector->count () - 1);
|
||||
}
|
||||
|
||||
if (m_active_index >= int (m_libraries.size ())) {
|
||||
m_active_index = int (m_libraries.size ()) - 1;
|
||||
} else if (m_active_index < 0 && ! m_libraries.empty ()) {
|
||||
m_active_index = 0;
|
||||
}
|
||||
mp_selector->setCurrentIndex (m_active_index);
|
||||
mp_selector->setVisible (mp_cell_lists.size () > 1 && ! split_mode);
|
||||
|
||||
for (unsigned int i = imin; i < m_libraries.size () && i <= imax; ++i) {
|
||||
|
||||
if (m_needs_update [i]) {
|
||||
|
||||
mp_cell_list_headers [i]->setText (tl::to_qstring (display_string (i)));
|
||||
|
||||
// draw the cells in the level of the current cell,
|
||||
// add an "above" entry if there is a level above.
|
||||
// highlight the current entry. If the index is
|
||||
// invalid, just clear the list.
|
||||
|
||||
if (m_force_close [i]) {
|
||||
|
||||
m_force_close [i] = false;
|
||||
|
||||
CellTreeModel *model = dynamic_cast <CellTreeModel *> (mp_cell_lists [i]->model ());
|
||||
if (model) {
|
||||
model->configure (& m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_needs_update [i] = false;
|
||||
|
||||
}
|
||||
|
||||
mp_cell_list_headers [i]->setVisible (split_mode && m_libraries.size () > 1);
|
||||
mp_cell_list_headers [i]->setChecked (int (i) == m_active_index);
|
||||
|
||||
mp_cell_list_frames [i]->setVisible (int (i) == m_active_index || split_mode);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibrariesView::select_active (int cellview_index)
|
||||
LibrariesView::select_active_lib_by_name (const std::string &name)
|
||||
{
|
||||
if (cellview_index != m_active_index) {
|
||||
mp_selector->setCurrentIndex (cellview_index);
|
||||
selection_changed (cellview_index);
|
||||
for (std::vector<tl::weak_ptr<db::Library> >::const_iterator i = m_libraries.begin (); i != m_libraries.end (); ++i) {
|
||||
if (i->get () && (*i)->get_name () == name) {
|
||||
select_active (int (i - m_libraries.begin ()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibrariesView::select_active (int lib_index)
|
||||
{
|
||||
if (lib_index != m_active_index) {
|
||||
mp_selector->setCurrentIndex (lib_index);
|
||||
selection_changed (lib_index);
|
||||
}
|
||||
}
|
||||
|
||||
db::Library *
|
||||
LibrariesView::active_lib ()
|
||||
{
|
||||
if (m_active_index >= 0 && m_active_index < int (m_libraries.size ())) {
|
||||
return m_libraries [m_active_index].get ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
LibrariesView::selection_changed (int index)
|
||||
{
|
||||
|
|
@ -721,7 +921,7 @@ LibrariesView::selection_changed (int index)
|
|||
|
||||
bool split_mode = m_split_mode;
|
||||
// for more than max_cellviews_in_split_mode cellviews, switch to overlay mode
|
||||
if (int (m_cellviews.size ()) > max_cellviews_in_split_mode) {
|
||||
if (int (m_libraries.size ()) > max_cellviews_in_split_mode) {
|
||||
split_mode = false;
|
||||
}
|
||||
|
||||
|
|
@ -735,11 +935,12 @@ LibrariesView::selection_changed (int index)
|
|||
(*f)->setChecked (i == index);
|
||||
}
|
||||
|
||||
emit active_cellview_changed (index);
|
||||
emit active_library_changed (index);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // @@@
|
||||
QModelIndex
|
||||
LibrariesView::index_from_path (const cell_path_type &path, int cv_index)
|
||||
{
|
||||
|
|
@ -798,182 +999,17 @@ LibrariesView::find_child_item (cell_path_type::const_iterator start, cell_path_
|
|||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string
|
||||
LibrariesView::display_string (int n) const
|
||||
{
|
||||
return m_cellviews [n]->name () + " (@" + tl::to_string (n + 1) + ")";
|
||||
}
|
||||
|
||||
void
|
||||
LibrariesView::do_update_content (int cv_index)
|
||||
{
|
||||
// close the search box since we will modify the model
|
||||
mp_search_frame->hide ();
|
||||
mp_search_model = 0;
|
||||
|
||||
unsigned int imin = (cv_index < 0 ? 0 : (unsigned int) cv_index);
|
||||
unsigned int imax = (cv_index < 0 ? std::numeric_limits <unsigned int>::max () : (unsigned int) cv_index);
|
||||
|
||||
for (unsigned int i = imin; i < mp_view->cellviews () && i <= imax; ++i) {
|
||||
if (i >= m_force_close.size ()) {
|
||||
m_force_close.push_back (true);
|
||||
}
|
||||
if (i >= m_needs_update.size ()) {
|
||||
m_needs_update.push_back (true);
|
||||
}
|
||||
if (i >= m_cellviews.size ()) {
|
||||
m_force_close [i] = true;
|
||||
m_needs_update [i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int n = std::min ((unsigned int) m_cellviews.size (), mp_view->cellviews ());
|
||||
for (unsigned int i = imin; i < n && i <= imax; ++i) {
|
||||
|
||||
if (&m_cellviews [i]->layout () != &mp_view->cellview (i)->layout ()) {
|
||||
m_needs_update [i] = true;
|
||||
m_force_close [i] = true;
|
||||
} else if (m_cellviews [i].combined_unspecific_path () != mp_view->cellview (i).combined_unspecific_path ()) {
|
||||
m_needs_update [i] = true;
|
||||
}
|
||||
|
||||
if (m_needs_update [i]) {
|
||||
mp_cell_lists [i]->doItemsLayout (); // this schedules a redraw
|
||||
}
|
||||
|
||||
m_cellviews [i] = mp_view->cellview (i);
|
||||
|
||||
}
|
||||
|
||||
if (m_cellviews.size () < mp_view->cellviews ()) {
|
||||
for (unsigned int i = n; i < mp_view->cellviews (); ++i) {
|
||||
m_cellviews.push_back (mp_view->cellview (i));
|
||||
}
|
||||
} else if (m_cellviews.size () > mp_view->cellviews ()) {
|
||||
m_cellviews.erase (m_cellviews.begin () + mp_view->cellviews (), m_cellviews.end ());
|
||||
}
|
||||
|
||||
bool split_mode = m_split_mode;
|
||||
// for more than max_cellviews_in_split_mode cellviews, switch to overlay mode
|
||||
if (int (m_cellviews.size ()) > max_cellviews_in_split_mode) {
|
||||
split_mode = false;
|
||||
}
|
||||
|
||||
while (mp_cell_lists.size () < m_cellviews.size ()) {
|
||||
|
||||
QPalette pl;
|
||||
|
||||
int cv_index = int (mp_cell_lists.size ());
|
||||
|
||||
QFrame *cl_frame = new QFrame (this);
|
||||
cl_frame->setFrameShape (QFrame::NoFrame);
|
||||
QVBoxLayout *cl_ly = new QVBoxLayout (cl_frame);
|
||||
cl_ly->setSpacing (0);
|
||||
cl_ly->setContentsMargins (0, 0, 0, 0);
|
||||
|
||||
QToolButton *header = new QToolButton (cl_frame);
|
||||
connect (header, SIGNAL (clicked ()), this, SLOT (header_clicked ()));
|
||||
header->setText (tl::to_qstring (display_string (cv_index)));
|
||||
header->setFocusPolicy (Qt::NoFocus);
|
||||
header->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
header->setCheckable (true);
|
||||
header->setAutoRaise (true);
|
||||
header->setAutoFillBackground (true);
|
||||
header->setVisible (split_mode);
|
||||
cl_ly->addWidget (header);
|
||||
|
||||
LibraryTreeWidget *cell_list = new LibraryTreeWidget (cl_frame, "tree", mp_view->view_object_widget ());
|
||||
cl_ly->addWidget (cell_list);
|
||||
cell_list->setModel (new CellTreeModel (cell_list, mp_view, cv_index, m_flat ? CellTreeModel::Flat : 0, 0, m_sorting));
|
||||
cell_list->setUniformRowHeights (true);
|
||||
|
||||
pl = cell_list->palette ();
|
||||
if (m_text_color.isValid ()) {
|
||||
pl.setColor (QPalette::Text, m_text_color);
|
||||
}
|
||||
if (m_background_color.isValid ()) {
|
||||
pl.setColor (QPalette::Base, m_background_color);
|
||||
}
|
||||
cell_list->setPalette (pl);
|
||||
|
||||
cell_list->header ()->hide ();
|
||||
cell_list->setSelectionMode (QTreeView::ExtendedSelection);
|
||||
cell_list->setRootIsDecorated (true);
|
||||
cell_list->setIndentation (14);
|
||||
cell_list->setContextMenuPolicy (Qt::CustomContextMenu);
|
||||
|
||||
connect (cell_list, SIGNAL (customContextMenuRequested (const QPoint &)), this, SLOT (context_menu (const QPoint &)));
|
||||
connect (cell_list, SIGNAL (cell_clicked (const QModelIndex &)), this, SLOT (clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (cell_double_clicked (const QModelIndex &)), this, SLOT (double_clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (cell_middle_clicked (const QModelIndex &)), this, SLOT (middle_clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (search_triggered (const QString &)), this, SLOT (search_triggered (const QString &)));
|
||||
|
||||
mp_cell_lists.push_back (cell_list);
|
||||
mp_cell_list_frames.push_back (cl_frame);
|
||||
mp_cell_list_headers.push_back (header);
|
||||
|
||||
mp_splitter->addWidget (cl_frame);
|
||||
|
||||
}
|
||||
|
||||
while (mp_cell_lists.size () > m_cellviews.size ()) {
|
||||
delete mp_cell_list_frames.back ();
|
||||
mp_cell_list_frames.pop_back ();
|
||||
mp_cell_list_headers.pop_back ();
|
||||
mp_cell_lists.pop_back ();
|
||||
}
|
||||
|
||||
for (unsigned int i = imin; i < m_cellviews.size () && i < (unsigned int) mp_selector->count () && i <= imax; ++i) {
|
||||
mp_selector->setItemText (i, tl::to_qstring (display_string (i)));
|
||||
}
|
||||
while (mp_selector->count () < int (m_cellviews.size ())) {
|
||||
mp_selector->addItem (tl::to_qstring (display_string (mp_selector->count ())));
|
||||
}
|
||||
while (mp_selector->count () > int (m_cellviews.size ())) {
|
||||
mp_selector->removeItem (mp_selector->count () - 1);
|
||||
}
|
||||
|
||||
if (m_active_index >= int (m_cellviews.size ())) {
|
||||
m_active_index = int (m_cellviews.size ()) - 1;
|
||||
} else if (m_active_index < 0 && ! m_cellviews.empty ()) {
|
||||
m_active_index = 0;
|
||||
}
|
||||
mp_selector->setCurrentIndex (m_active_index);
|
||||
mp_selector->setVisible (mp_cell_lists.size () > 1 && ! split_mode);
|
||||
|
||||
for (unsigned int i = imin; i < m_cellviews.size () && i <= imax; ++i) {
|
||||
|
||||
if (m_needs_update [i]) {
|
||||
|
||||
mp_cell_list_headers [i]->setText (tl::to_qstring (display_string (i)));
|
||||
|
||||
// draw the cells in the level of the current cell,
|
||||
// add an "above" entry if there is a level above.
|
||||
// highlight the current entry. If the index is
|
||||
// invalid, just clear the list.
|
||||
|
||||
if (m_force_close [i]) {
|
||||
|
||||
m_force_close [i] = false;
|
||||
|
||||
CellTreeModel *model = dynamic_cast <CellTreeModel *> (mp_cell_lists [i]->model ());
|
||||
if (model) {
|
||||
model->configure (mp_view, i, m_flat ? CellTreeModel::Flat : 0, 0, m_sorting);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_needs_update [i] = false;
|
||||
|
||||
}
|
||||
|
||||
mp_cell_list_headers [i]->setVisible (split_mode && m_cellviews.size () > 1);
|
||||
mp_cell_list_headers [i]->setChecked (int (i) == m_active_index);
|
||||
|
||||
mp_cell_list_frames [i]->setVisible (int (i) == m_active_index || split_mode);
|
||||
|
||||
const db::Library *lib = m_libraries [n].get ();
|
||||
std::string text = lib->get_name ();
|
||||
if (! lib->get_description ().empty ()) {
|
||||
text += " - " + lib->get_description ();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
CellTreeItem *
|
||||
|
|
@ -988,19 +1024,6 @@ LibrariesView::current_item () const
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
LibrariesView::do_update_content ()
|
||||
{
|
||||
// @@@
|
||||
}
|
||||
|
||||
void
|
||||
LibrariesView::do_full_update_content ()
|
||||
{
|
||||
// @@@
|
||||
}
|
||||
|
||||
bool
|
||||
LibrariesView::has_focus () const
|
||||
|
|
|
|||
|
|
@ -134,14 +134,18 @@ public:
|
|||
*/
|
||||
void set_text_color (QColor c);
|
||||
|
||||
#if 0 // @@@
|
||||
/**
|
||||
* @brief Sets the active library by name
|
||||
*/
|
||||
void select_active_lib_by_name (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Select the active cellview
|
||||
*
|
||||
* selects the active cellview by index. The index must be
|
||||
* a valid index within the context of the layout view.
|
||||
*/
|
||||
void select_active (int cellview_index);
|
||||
void select_active (int lib_index);
|
||||
|
||||
/**
|
||||
* @brief Get the active cellview
|
||||
|
|
@ -153,6 +157,12 @@ public:
|
|||
return m_active_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the active library or 0 if there is no active library
|
||||
*/
|
||||
db::Library *active_lib ();
|
||||
|
||||
#if 0 // @@@
|
||||
/**
|
||||
* @brief Returns the paths of the selected cells
|
||||
*/
|
||||
|
|
@ -172,6 +182,7 @@ public:
|
|||
* can be obtained with the "active" method.
|
||||
*/
|
||||
void set_current_cell (int cv_index, const cell_path_type &path);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Update the contents if necessary
|
||||
|
|
@ -191,7 +202,6 @@ public:
|
|||
{
|
||||
do_update_content (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Event handler
|
||||
|
|
@ -228,18 +238,18 @@ public:
|
|||
return mp_view;
|
||||
}
|
||||
|
||||
#if 0
|
||||
signals:
|
||||
#if 0 // @@@
|
||||
void cell_selected (cell_path_type path, int cellview_index);
|
||||
void active_cellview_changed (int cellview_index);
|
||||
#endif
|
||||
void active_library_changed (int cellview_index);
|
||||
|
||||
public slots:
|
||||
void clicked (const QModelIndex &index);
|
||||
void header_clicked ();
|
||||
void double_clicked (const QModelIndex &index);
|
||||
void middle_clicked (const QModelIndex &index);
|
||||
// @@@ void selection_changed (int index);
|
||||
void selection_changed (int index);
|
||||
void context_menu (const QPoint &pt);
|
||||
void search_triggered (const QString &t);
|
||||
void search_edited ();
|
||||
|
|
@ -272,24 +282,24 @@ private:
|
|||
tl::DeferredMethod<LibrariesView> m_do_update_content_dm;
|
||||
tl::DeferredMethod<LibrariesView> m_do_full_update_content_dm;
|
||||
std::auto_ptr<QStyle> mp_tree_style;
|
||||
|
||||
#if 0 // @@@
|
||||
// locate the CellTreeItem in the tree corresponding to a partial path starting from p.
|
||||
CellTreeItem *find_child_item (cell_path_type::const_iterator start, cell_path_type::const_iterator end, CellTreeItem *p);
|
||||
|
||||
// get the current item
|
||||
CellTreeItem *current_item () const;
|
||||
std::vector<tl::weak_ptr<db::Library> > m_libraries;
|
||||
|
||||
// event listener for changes in the cellview and layout
|
||||
void update_required ();
|
||||
|
||||
#if 0 // @@@
|
||||
// locate the CellTreeItem in the tree corresponding to a partial path starting from p.
|
||||
CellTreeItem *find_child_item (cell_path_type::const_iterator start, cell_path_type::const_iterator end, CellTreeItem *p);
|
||||
#endif
|
||||
|
||||
// get the current item
|
||||
CellTreeItem *current_item () const;
|
||||
|
||||
#if 0 // @@@
|
||||
// path from index and item from path ..
|
||||
void path_from_index (const QModelIndex &index, int cv_index, cell_path_type &path) const;
|
||||
QModelIndex index_from_path (const cell_path_type &path, int cv_index);
|
||||
|
||||
// display string of nth cellview
|
||||
std::string display_string (int n) const;
|
||||
|
||||
// select active cellview from sender (sender must be a cell tree)
|
||||
void set_active_celltree_from_sender ();
|
||||
|
||||
|
|
@ -297,11 +307,11 @@ private:
|
|||
void clear_all ();
|
||||
#endif
|
||||
|
||||
// display string of nth cellview
|
||||
std::string display_string (int n) const;
|
||||
|
||||
// forces a complete update
|
||||
void do_full_update_content ();
|
||||
|
||||
// updates the contents if necessary
|
||||
void do_update_content ();
|
||||
};
|
||||
|
||||
} // namespace lay
|
||||
|
|
|
|||
|
|
@ -124,6 +124,9 @@ static const std::string cfg_flat_cell_list ("flat-cell-list");
|
|||
static const std::string cfg_split_cell_list ("split-cell-list");
|
||||
static const std::string cfg_cell_list_sorting ("cell-list-sorting");
|
||||
|
||||
static const std::string cfg_split_lib_views ("split-lib-views");
|
||||
static const std::string cfg_current_lib_view ("current-lib-view");
|
||||
|
||||
static const std::string cfg_pan_distance ("pan-distance");
|
||||
static const std::string cfg_paste_display_mode ("paste-display-mode");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue