klayout/src/laybasic/layHierarchyControlPanel.h

346 lines
8.4 KiB
C++

/*
KLayout Layout Viewer
Copyright (C) 2006-2017 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_layHierarchyControlPanel
#define HDR_layHierarchyControlPanel
#include <vector>
#include <string>
#include <algorithm>
#include <QFrame>
#include <QTreeView>
#include "dbLayout.h"
#include "layCanvasPlane.h"
#include "layViewOp.h"
#include "layLayoutView.h"
#include "layCellTreeModel.h"
#include "layWidgets.h"
#include "tlDeferredExecution.h"
class QModelIndex;
class QComboBox;
class QMenu;
class QSplitter;
class QFrame;
class QToolButton;
class QLineEdit;
class QAction;
class QCheckBox;
namespace lay
{
/**
* @brief A special QTreeView customization
*
* A customized QTreeView that is used to receive middle-mouse-button
* events and processes double clicks by bypassing the standard implementation
* that closes and opens branches.
*/
class HCPCellTreeWidget
: public QTreeView
{
Q_OBJECT
public:
HCPCellTreeWidget (QWidget *parent, const char *name, QWidget *key_event_receiver);
signals:
void cell_clicked (const QModelIndex &);
void cell_double_clicked (const QModelIndex &);
void cell_middle_clicked (const QModelIndex &);
void search_triggered (const QString &t);
protected:
virtual void mouseDoubleClickEvent (QMouseEvent *event);
virtual void mousePressEvent (QMouseEvent *event);
virtual void mouseReleaseEvent (QMouseEvent *event);
virtual void startDrag (Qt::DropActions supportedActions);
virtual bool focusNextPrevChild (bool next);
virtual void keyPressEvent (QKeyEvent *event);
virtual bool event (QEvent *event);
QWidget *mp_key_event_receiver;
};
/**
* @brief The hierarchy control panel
*
* The hierarchy control panel allows to change the cell shown
* browse the hierarchy and disable/enable cells
*
* The class communicates with a Layout interface for
* retrieval of the cell hierarchy
*/
class HierarchyControlPanel
: public QFrame,
public tl::Object
{
Q_OBJECT
public:
typedef lay::CellView::unspecific_cell_path_type cell_path_type;
/**
* @brief Constructor
*
* @param parent The Qt parent widget
* @param name The layer control panel's widget name
*/
HierarchyControlPanel (lay::LayoutView *view, QWidget *parent = 0, const char *name = "control_panel");
/**
* @brief Destructor
*/
~HierarchyControlPanel ();
/**
* @brief Perform the cell control panel's initialisations on the main menu
*/
static void init_menu (lay::AbstractMenu &menu);
/**
* @brief The sizeHint implementation for Qt layout management
*/
virtual QSize sizeHint () const;
/**
* @brief Changing of the background color
*/
void set_background_color (QColor c);
/**
* @brief Changing of the text color
*/
void set_text_color (QColor c);
/**
* @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);
/**
* @brief Get the active cellview
*
* get the active cellview index.
*/
int active ()
{
return m_active_index;
}
/**
* @brief Returns the paths of the selected cells
*/
void selected_cells (int cv_index, std::vector<cell_path_type> &paths) const;
/**
* @brief Return the path to the current cell for the given cellview index
*
* The current cell is the cell that is highlighted.
*/
void current_cell (int cv_index, cell_path_type &path) const;
/**
* @brief Set the path to the current cell
*
* The current cell is the cell that is highlighted. The current cv index
* can be obtained with the "active" method.
*/
void set_current_cell (int cv_index, const cell_path_type &path);
/**
* @brief Event handler
*
* The object subclasses the event handler in order to intercept
* the GTF probe events (Qt::MaxUser).
*/
virtual bool event (QEvent *e);
/**
* @brief Update the contents if necessary
*
* Update the cell trees according to the hierarchy found in
* the layouts. This version allows to give an hint what cellview has changed.
*/
void do_update_content (int cv_index);
/**
* @brief Update the contents if necessary
*
* Update the cell trees according to the hierarchy found in
* the layouts.
*/
void do_update_content ()
{
do_update_content (-1);
}
/**
* @brief Return true, if the tree view has the focus
*/
bool has_focus () const;
/**
* @brief Cut to clipboards
*/
void cut ();
/**
* @brief Copy to clipboards
*/
void copy ();
/**
* @brief Paste from clipboard
*/
void paste ();
/**
* @brief Return true, if the panel has a selection
*/
bool has_selection ();
/**
* @brief Select sorting
*/
void set_sorting (CellTreeModel::Sorting sorting);
/**
* @brief Select flat mode
*/
void set_flat (bool flat);
/**
* @brief Return true if flat mode is selected
*/
bool flat () const
{
return m_flat;
}
/**
* @brief Select split mode
* In split mode all cell trees are shown stacked
*/
void set_split_mode (bool sbs);
/**
* @brief Returns true if side-by-side mode is set
*/
bool split_mode () const
{
return m_split_mode;
}
/**
* @brief Gets the layout view this panel is attached to
*/
lay::LayoutView *view ()
{
return mp_view;
}
signals:
void cell_selected (cell_path_type path, int cellview_index);
void active_cellview_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 context_menu (const QPoint &pt);
void search_triggered (const QString &t);
void search_edited ();
void search_editing_finished ();
void search_next ();
void search_prev ();
void cm_cell_select ();
private:
db::Layout *mp_layout;
bool m_enable_cb;
lay::LayoutView *mp_view;
std::vector <lay::CellView> m_cellviews;
std::vector <QTreeView *> mp_cell_lists;
std::vector <QToolButton *> mp_cell_list_headers;
std::vector <QFrame *> mp_cell_list_frames;
std::vector <bool> m_force_close;
std::vector <bool> m_needs_update;
bool m_visibility_needs_update;
int m_active_index;
bool m_flat;
bool m_split_mode;
CellTreeModel::Sorting m_sorting;
QComboBox *mp_selector;
lay::DecoratedLineEdit *mp_search_edit_box;
QAction *mp_case_sensitive;
QAction *mp_use_regular_expressions;
CellTreeModel *mp_search_model;
QFrame *mp_search_frame;
QCheckBox *mp_search_close_cb;
QSplitter *mp_splitter;
QColor m_background_color;
QColor m_text_color;
tl::DeferredMethod<HierarchyControlPanel> m_do_update_content_dm;
tl::DeferredMethod<HierarchyControlPanel> m_do_full_update_content_dm;
std::auto_ptr<QStyle> mp_tree_style;
// 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;
// event listener for changes in the cellview and layout
void update_required ();
// force a complete update
void do_full_update_content ();
// 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 ();
// clears all widgets of the cell lists
void clear_all ();
};
} // namespace lay
#endif