Gui: refactor tree view
* Major refactor of tree view to support external linking. * Item update and selection change are now mostly handled by timer for performance improvement. * Major change to drag and drop for better support of switching between copy, move and replace action, and auto adjustment of placement and relative link. * Add second column for user changable object description. * Unified tree view options and action into command group Std_TreeViewActions. * Modified object search function to find external objects using Expression syntax.
This commit is contained in:
@@ -63,8 +63,7 @@ CombiView::CombiView(Gui::Document* pcDocument, QWidget *parent)
|
||||
QSplitter *splitter = new QSplitter();
|
||||
splitter->setOrientation(Qt::Vertical);
|
||||
|
||||
// tree widget
|
||||
tree = new TreePanel(this);
|
||||
tree = new TreePanel("ComboView", this);
|
||||
splitter->addWidget(tree);
|
||||
|
||||
// property view
|
||||
|
||||
@@ -787,47 +787,8 @@ StdCmdToggleVisibility::StdCmdToggleVisibility()
|
||||
|
||||
void StdCmdToggleVisibility::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
// go through all documents
|
||||
const std::vector<App::Document*> docs = App::GetApplication().getDocuments();
|
||||
for (std::vector<App::Document*>::const_iterator it = docs.begin(); it != docs.end(); ++it) {
|
||||
Document *pcDoc = Application::Instance->getDocument(*it);
|
||||
std::vector<App::DocumentObject*> sel = Selection().getObjectsOfType
|
||||
(App::DocumentObject::getClassTypeId(), (*it)->getName());
|
||||
|
||||
// in case a group object and an object of the group is selected then ignore the group object
|
||||
std::vector<App::DocumentObject*> ignore;
|
||||
for (std::vector<App::DocumentObject*>::iterator ft=sel.begin();ft!=sel.end();++ft) {
|
||||
if ((*ft)->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) {
|
||||
App::DocumentObjectGroup* grp = static_cast<App::DocumentObjectGroup*>(*ft);
|
||||
std::vector<App::DocumentObject*> sub = grp->Group.getValues();
|
||||
for (std::vector<App::DocumentObject*>::iterator st = sub.begin(); st != sub.end(); ++st) {
|
||||
if (std::find(sel.begin(), sel.end(), *st) != sel.end()) {
|
||||
ignore.push_back(*ft);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignore.empty()) {
|
||||
std::sort(sel.begin(), sel.end());
|
||||
std::sort(ignore.begin(), ignore.end());
|
||||
std::vector<App::DocumentObject*> diff;
|
||||
std::back_insert_iterator<std::vector<App::DocumentObject*> > biit(diff);
|
||||
std::set_difference(sel.begin(), sel.end(), ignore.begin(), ignore.end(), biit);
|
||||
sel = diff;
|
||||
}
|
||||
|
||||
for (std::vector<App::DocumentObject*>::const_iterator ft=sel.begin();ft!=sel.end();++ft) {
|
||||
if (pcDoc && pcDoc->isShow((*ft)->getNameInDocument()))
|
||||
doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Visibility=False"
|
||||
, (*it)->getName(), (*ft)->getNameInDocument());
|
||||
else
|
||||
doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Visibility=True"
|
||||
, (*it)->getName(), (*ft)->getNameInDocument());
|
||||
}
|
||||
}
|
||||
Q_UNUSED(iMsg);
|
||||
Selection().setVisible(-1);
|
||||
}
|
||||
|
||||
bool StdCmdToggleVisibility::isActive(void)
|
||||
@@ -900,17 +861,8 @@ StdCmdShowSelection::StdCmdShowSelection()
|
||||
|
||||
void StdCmdShowSelection::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
// go through all documents
|
||||
const std::vector<App::Document*> docs = App::GetApplication().getDocuments();
|
||||
for (std::vector<App::Document*>::const_iterator it = docs.begin(); it != docs.end(); ++it) {
|
||||
const std::vector<App::DocumentObject*> sel = Selection().getObjectsOfType
|
||||
(App::DocumentObject::getClassTypeId(), (*it)->getName());
|
||||
for(std::vector<App::DocumentObject*>::const_iterator ft=sel.begin();ft!=sel.end();++ft) {
|
||||
doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Visibility=True"
|
||||
, (*it)->getName(), (*ft)->getNameInDocument());
|
||||
}
|
||||
}
|
||||
Q_UNUSED(iMsg);
|
||||
Selection().setVisible(true);
|
||||
}
|
||||
|
||||
bool StdCmdShowSelection::isActive(void)
|
||||
@@ -936,17 +888,8 @@ StdCmdHideSelection::StdCmdHideSelection()
|
||||
|
||||
void StdCmdHideSelection::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
// go through all documents
|
||||
const std::vector<App::Document*> docs = App::GetApplication().getDocuments();
|
||||
for (std::vector<App::Document*>::const_iterator it = docs.begin(); it != docs.end(); ++it) {
|
||||
const std::vector<App::DocumentObject*> sel = Selection().getObjectsOfType
|
||||
(App::DocumentObject::getClassTypeId(), (*it)->getName());
|
||||
for(std::vector<App::DocumentObject*>::const_iterator ft=sel.begin();ft!=sel.end();++ft) {
|
||||
doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Visibility=False"
|
||||
, (*it)->getName(), (*ft)->getNameInDocument());
|
||||
}
|
||||
}
|
||||
Q_UNUSED(iMsg);
|
||||
Selection().setVisible(false);
|
||||
}
|
||||
|
||||
bool StdCmdHideSelection::isActive(void)
|
||||
@@ -1482,6 +1425,7 @@ StdViewDock::StdViewDock()
|
||||
sStatusTip = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
|
||||
sAccel = "V, D";
|
||||
eType = Alter3DView;
|
||||
bCanLog = false;
|
||||
}
|
||||
|
||||
void StdViewDock::activated(int iMsg)
|
||||
@@ -1510,6 +1454,7 @@ StdViewUndock::StdViewUndock()
|
||||
sStatusTip = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
|
||||
sAccel = "V, U";
|
||||
eType = Alter3DView;
|
||||
bCanLog = false;
|
||||
}
|
||||
|
||||
void StdViewUndock::activated(int iMsg)
|
||||
@@ -1571,6 +1516,7 @@ StdViewFullscreen::StdViewFullscreen()
|
||||
sPixmap = "view-fullscreen";
|
||||
sAccel = "F11";
|
||||
eType = Alter3DView;
|
||||
bCanLog = false;
|
||||
}
|
||||
|
||||
void StdViewFullscreen::activated(int iMsg)
|
||||
@@ -2616,27 +2562,125 @@ void StdBoxSelection::activated(int iMsg)
|
||||
// Std_TreeSelection
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdTreeSelection)
|
||||
DEF_STD_CMD(StdTreeSelection)
|
||||
|
||||
StdCmdTreeSelection::StdCmdTreeSelection()
|
||||
StdTreeSelection::StdTreeSelection()
|
||||
: Command("Std_TreeSelection")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Go to selection");
|
||||
sToolTipText = QT_TR_NOOP("Scroll to first selected item");
|
||||
sWhatsThis = "Std_TreeSelection";
|
||||
sStatusTip = QT_TR_NOOP("Scroll to first selected item");
|
||||
eType = Alter3DView;
|
||||
sPixmap = "tree-goto-sel";
|
||||
sAccel = "T,G";
|
||||
}
|
||||
|
||||
void StdCmdTreeSelection::activated(int iMsg)
|
||||
void StdTreeSelection::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
TreeWidget::scrollItemToTop();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeCollapse
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdTreeCollapse)
|
||||
|
||||
StdCmdTreeCollapse::StdCmdTreeCollapse()
|
||||
: Command("Std_TreeCollapse")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sMenuText = QT_TR_NOOP("Collapse selected item");
|
||||
sToolTipText = QT_TR_NOOP("Collapse currently selected tree items");
|
||||
sWhatsThis = "Std_TreeCollapse";
|
||||
sStatusTip = QT_TR_NOOP("Collapse currently selected tree items");
|
||||
eType = Alter3DView;
|
||||
}
|
||||
|
||||
void StdCmdTreeCollapse::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
QList<TreeWidget*> tree = Gui::getMainWindow()->findChildren<TreeWidget*>();
|
||||
for (QList<TreeWidget*>::iterator it = tree.begin(); it != tree.end(); ++it) {
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
(*it)->scrollItemToTop(doc);
|
||||
}
|
||||
for (QList<TreeWidget*>::iterator it = tree.begin(); it != tree.end(); ++it)
|
||||
(*it)->expandSelectedItems(TreeItemMode::CollapseItem);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeExpand
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD(StdCmdTreeExpand)
|
||||
|
||||
StdCmdTreeExpand::StdCmdTreeExpand()
|
||||
: Command("Std_TreeExpand")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sMenuText = QT_TR_NOOP("Expand selected item");
|
||||
sToolTipText = QT_TR_NOOP("Expand currently selected tree items");
|
||||
sWhatsThis = "Std_TreeExpand";
|
||||
sStatusTip = QT_TR_NOOP("Expand currently selected tree items");
|
||||
eType = Alter3DView;
|
||||
}
|
||||
|
||||
void StdCmdTreeExpand::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
QList<TreeWidget*> tree = Gui::getMainWindow()->findChildren<TreeWidget*>();
|
||||
for (QList<TreeWidget*>::iterator it = tree.begin(); it != tree.end(); ++it)
|
||||
(*it)->expandSelectedItems(TreeItemMode::ExpandItem);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeSelectAllInstance
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD_A(StdCmdTreeSelectAllInstances)
|
||||
|
||||
StdCmdTreeSelectAllInstances::StdCmdTreeSelectAllInstances()
|
||||
: Command("Std_TreeSelectAllInstances")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sMenuText = QT_TR_NOOP("Select all instances");
|
||||
sToolTipText = QT_TR_NOOP("Select all instances of the current selected object");
|
||||
sWhatsThis = "Std_TreeSelectAllInstances";
|
||||
sStatusTip = QT_TR_NOOP("Select all instances of the current selected object");
|
||||
sPixmap = "sel-instance";
|
||||
eType = AlterSelection;
|
||||
}
|
||||
|
||||
bool StdCmdTreeSelectAllInstances::isActive(void)
|
||||
{
|
||||
const auto &sels = Selection().getSelectionEx("*",App::DocumentObject::getClassTypeId(),true,true);
|
||||
if(sels.empty())
|
||||
return false;
|
||||
auto obj = sels[0].getObject();
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
return false;
|
||||
return dynamic_cast<ViewProviderDocumentObject*>(
|
||||
Application::Instance->getViewProvider(obj))!=0;
|
||||
}
|
||||
|
||||
void StdCmdTreeSelectAllInstances::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
const auto &sels = Selection().getSelectionEx("*",App::DocumentObject::getClassTypeId(),true,true);
|
||||
if(sels.empty())
|
||||
return;
|
||||
auto obj = sels[0].getObject();
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
return;
|
||||
auto vpd = dynamic_cast<ViewProviderDocumentObject*>(
|
||||
Application::Instance->getViewProvider(obj));
|
||||
if(!vpd)
|
||||
return;
|
||||
Selection().selStackPush();
|
||||
Selection().clearCompleteSelection();
|
||||
for(auto tree : getMainWindow()->findChildren<TreeWidget*>())
|
||||
tree->selectAllInstances(*vpd);
|
||||
Selection().selStackPush();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -2875,132 +2919,374 @@ void CmdViewMeasureToggleAll::activated(int iMsg)
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_SelBack
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD_A(StdCmdSelBack);
|
||||
|
||||
StdCmdSelBack::StdCmdSelBack()
|
||||
:Command("Std_SelBack")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sMenuText = QT_TR_NOOP("&Back");
|
||||
sToolTipText = QT_TR_NOOP("Go back to previous selection");
|
||||
sWhatsThis = "Std_SelBack";
|
||||
sStatusTip = QT_TR_NOOP("Go back to previous selection");
|
||||
sPixmap = "sel-back";
|
||||
sAccel = "S, B";
|
||||
eType = AlterSelection;
|
||||
}
|
||||
|
||||
void StdCmdSelBack::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
Selection().selStackGoBack();
|
||||
}
|
||||
|
||||
bool StdCmdSelBack::isActive(void)
|
||||
{
|
||||
return Selection().selStackBackSize()>1;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_SelForward
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD_A(StdCmdSelForward);
|
||||
|
||||
StdCmdSelForward::StdCmdSelForward()
|
||||
:Command("Std_SelForward")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sMenuText = QT_TR_NOOP("&Forward");
|
||||
sToolTipText = QT_TR_NOOP("Repeat the backed selection");
|
||||
sWhatsThis = "Std_SelForward";
|
||||
sStatusTip = QT_TR_NOOP("Repeat the backed selection");
|
||||
sPixmap = "sel-forward";
|
||||
sAccel = "S, F";
|
||||
eType = AlterSelection;
|
||||
}
|
||||
|
||||
void StdCmdSelForward::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
Selection().selStackGoForward();
|
||||
}
|
||||
|
||||
bool StdCmdSelForward::isActive(void)
|
||||
{
|
||||
return !!Selection().selStackForwardSize();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// Std_TreeSingleDocument
|
||||
//===========================================================================
|
||||
DEF_STD_CMD(StdTreeSingleDocument)
|
||||
#define TREEVIEW_DOC_CMD_DEF(_name,_v) \
|
||||
DEF_STD_CMD_AC(StdTree##_name) \
|
||||
void StdTree##_name::activated(int){ \
|
||||
FC_TREEPARAM_SET(DocumentMode,_v);\
|
||||
if(_pcAction) _pcAction->setChecked(true,true);\
|
||||
}\
|
||||
Action * StdTree##_name::createAction(void) {\
|
||||
Action *pcAction = Command::createAction();\
|
||||
pcAction->setCheckable(true);\
|
||||
pcAction->setIcon(QIcon());\
|
||||
_pcAction = pcAction;\
|
||||
isActive();\
|
||||
return pcAction;\
|
||||
}\
|
||||
bool StdTree##_name::isActive() {\
|
||||
bool checked = FC_TREEPARAM(DocumentMode)==_v;\
|
||||
if(_pcAction && _pcAction->isChecked()!=checked)\
|
||||
_pcAction->setChecked(checked,true);\
|
||||
return true;\
|
||||
}
|
||||
|
||||
TREEVIEW_DOC_CMD_DEF(SingleDocument,0)
|
||||
|
||||
StdTreeSingleDocument::StdTreeSingleDocument()
|
||||
: Command("Std_TreeSingleDocument")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sMenuText = QT_TR_NOOP("Single Document");
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Single document");
|
||||
sToolTipText = QT_TR_NOOP("Only display the active document in the tree view");
|
||||
sWhatsThis = "Std_TreeSingleDocument";
|
||||
sStatusTip = QT_TR_NOOP("Only display the active document in the tree view");
|
||||
sPixmap = "tree-doc-single";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdTreeSingleDocument::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeMultiDocument
|
||||
//===========================================================================
|
||||
DEF_STD_CMD(StdTreeMultiDocument)
|
||||
TREEVIEW_DOC_CMD_DEF(MultiDocument,1)
|
||||
|
||||
StdTreeMultiDocument::StdTreeMultiDocument()
|
||||
: Command("Std_TreeMultiDocument")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sMenuText = QT_TR_NOOP("Multi Document");
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Multi document");
|
||||
sToolTipText = QT_TR_NOOP("Display all documents in the tree view");
|
||||
sWhatsThis = "Std_TreeMultiDocument";
|
||||
sStatusTip = QT_TR_NOOP("Display all documents in the tree view");
|
||||
sPixmap = "tree-doc-multi";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdTreeMultiDocument::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeCollapseDocument
|
||||
//===========================================================================
|
||||
DEF_STD_CMD(StdTreeCollapseDocument)
|
||||
TREEVIEW_DOC_CMD_DEF(CollapseDocument,2)
|
||||
|
||||
StdTreeCollapseDocument::StdTreeCollapseDocument()
|
||||
: Command("Std_TreeCollapseDocument")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Collapse/Expand");
|
||||
sToolTipText = QT_TR_NOOP("Expand active document and collapse all others");
|
||||
sWhatsThis = "Std_TreeCollapseDocument";
|
||||
sStatusTip = QT_TR_NOOP("Expand active document and collapse all others");
|
||||
sPixmap = "tree-doc-collapse";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdTreeCollapseDocument::activated(int iMsg)
|
||||
//===========================================================================
|
||||
// Std_TreeSyncView
|
||||
//===========================================================================
|
||||
#define TREEVIEW_CMD_DEF(_name) \
|
||||
DEF_STD_CMD_AC(StdTree##_name) \
|
||||
void StdTree##_name::activated(int){ \
|
||||
auto checked = !FC_TREEPARAM(_name);\
|
||||
FC_TREEPARAM_SET(_name,checked);\
|
||||
if(_pcAction) _pcAction->setChecked(checked,true);\
|
||||
}\
|
||||
Action * StdTree##_name::createAction(void) {\
|
||||
Action *pcAction = Command::createAction();\
|
||||
pcAction->setCheckable(true);\
|
||||
pcAction->setIcon(QIcon());\
|
||||
_pcAction = pcAction;\
|
||||
isActive();\
|
||||
return pcAction;\
|
||||
}\
|
||||
bool StdTree##_name::isActive() {\
|
||||
bool checked = FC_TREEPARAM(_name);\
|
||||
if(_pcAction && _pcAction->isChecked()!=checked)\
|
||||
_pcAction->setChecked(checked,true);\
|
||||
return true;\
|
||||
}
|
||||
|
||||
TREEVIEW_CMD_DEF(SyncView)
|
||||
|
||||
StdTreeSyncView::StdTreeSyncView()
|
||||
: Command("Std_TreeSyncView")
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Sync view");
|
||||
sToolTipText = QT_TR_NOOP("Auto switch to the 3D view containing the selected item");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "Std_TreeSyncView";
|
||||
sPixmap = "tree-sync-view";
|
||||
sAccel = "T,1";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeSyncSelection
|
||||
//===========================================================================
|
||||
TREEVIEW_CMD_DEF(SyncSelection)
|
||||
|
||||
StdTreeSyncSelection::StdTreeSyncSelection()
|
||||
: Command("Std_TreeSyncSelection")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Sync selection");
|
||||
sToolTipText = QT_TR_NOOP("Auto expand tree item when the corresponding object is selected in 3D view");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "Std_TreeSyncSelection";
|
||||
sPixmap = "tree-sync-sel";
|
||||
sAccel = "T,2";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeViewDocument
|
||||
// Std_TreeSyncPlacement
|
||||
//===========================================================================
|
||||
TREEVIEW_CMD_DEF(SyncPlacement)
|
||||
|
||||
DEF_STD_CMD_AC(StdTreeViewDocument);
|
||||
StdTreeSyncPlacement::StdTreeSyncPlacement()
|
||||
: Command("Std_TreeSyncPlacement")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Sync placement");
|
||||
sToolTipText = QT_TR_NOOP("Auto adjust placement on drag and drop objects across coordinate systems");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "Std_TreeSyncPlacement";
|
||||
sPixmap = "tree-sync-pla";
|
||||
sAccel = "T,3";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
StdTreeViewDocument::StdTreeViewDocument()
|
||||
: Command("Std_TreeViewDocument")
|
||||
//===========================================================================
|
||||
// Std_TreePreSelection
|
||||
//===========================================================================
|
||||
TREEVIEW_CMD_DEF(PreSelection)
|
||||
|
||||
StdTreePreSelection::StdTreePreSelection()
|
||||
: Command("Std_TreePreSelection")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Pre-selection");
|
||||
sToolTipText = QT_TR_NOOP("Preselect the object in 3D view when mouse over the tree item");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "Std_TreePreSelection";
|
||||
sPixmap = "tree-pre-sel";
|
||||
sAccel = "T,4";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeRecordSelection
|
||||
//===========================================================================
|
||||
TREEVIEW_CMD_DEF(RecordSelection)
|
||||
|
||||
StdTreeRecordSelection::StdTreeRecordSelection()
|
||||
: Command("Std_TreeRecordSelection")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Record selection");
|
||||
sToolTipText = QT_TR_NOOP("Record selection in tree view in order to go back/forward using navigation button");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "Std_TreeRecordSelection";
|
||||
sPixmap = "tree-rec-sel";
|
||||
sAccel = "T,5";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Std_TreeDrag
|
||||
//===========================================================================
|
||||
DEF_STD_CMD(StdTreeDrag)
|
||||
|
||||
StdTreeDrag::StdTreeDrag()
|
||||
: Command("Std_TreeDrag")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("TreeView");
|
||||
sMenuText = QT_TR_NOOP("Initiate dragging");
|
||||
sToolTipText = QT_TR_NOOP("Initiate dragging of current selected tree items");
|
||||
sStatusTip = sToolTipText;
|
||||
sWhatsThis = "Std_TreeDrag";
|
||||
sPixmap = "tree-item-drag";
|
||||
sAccel = "T,D";
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void StdTreeDrag::activated(int)
|
||||
{
|
||||
if(Gui::Selection().hasSelection()) {
|
||||
for(auto tree : getMainWindow()->findChildren<TreeWidget*>()) {
|
||||
if(tree->isVisible()) {
|
||||
tree->startDragging();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Std_TreeViewActions
|
||||
//===========================================================================
|
||||
//
|
||||
class StdCmdTreeViewActions : public Gui::Command
|
||||
{
|
||||
public:
|
||||
StdCmdTreeViewActions();
|
||||
virtual const char* className() const {return "StdCmdTreeViewActions";}
|
||||
protected:
|
||||
virtual void activated(int iMsg);
|
||||
virtual Gui::Action * createAction(void);
|
||||
|
||||
std::vector<std::pair<Command*,size_t> > cmds;
|
||||
};
|
||||
|
||||
StdCmdTreeViewActions::StdCmdTreeViewActions()
|
||||
: Command("Std_TreeViewActions")
|
||||
{
|
||||
sGroup = QT_TR_NOOP("View");
|
||||
sMenuText = QT_TR_NOOP("Document Tree");
|
||||
sToolTipText = QT_TR_NOOP("Set visibility of inactive documents in tree view");
|
||||
sWhatsThis = "Std_TreeViewDocument";
|
||||
sStatusTip = QT_TR_NOOP("Set visibility of inactive documents in tree view");
|
||||
sMenuText = QT_TR_NOOP("TreeView actions");
|
||||
sToolTipText = QT_TR_NOOP("TreeView behavior options and actions");
|
||||
sWhatsThis = "Std_TreeViewActions";
|
||||
sStatusTip = QT_TR_NOOP("TreeView behavior options and actions");
|
||||
eType = 0;
|
||||
bCanLog = false;
|
||||
|
||||
CommandManager &rcCmdMgr = Application::Instance->commandManager();
|
||||
rcCmdMgr.addCommand(new StdTreeSingleDocument());
|
||||
rcCmdMgr.addCommand(new StdTreeMultiDocument());
|
||||
rcCmdMgr.addCommand(new StdTreeCollapseDocument());
|
||||
CommandManager &mgr = Application::Instance->commandManager();
|
||||
cmds.reserve(12);
|
||||
cmds.emplace_back(new StdTreeSyncView(),cmds.size());
|
||||
mgr.addCommand(cmds.back().first);
|
||||
cmds.emplace_back(new StdTreeSyncSelection(),cmds.size());
|
||||
mgr.addCommand(cmds.back().first);
|
||||
cmds.emplace_back(new StdTreeSyncPlacement(),cmds.size());
|
||||
mgr.addCommand(cmds.back().first);
|
||||
cmds.emplace_back(new StdTreePreSelection(),cmds.size());
|
||||
mgr.addCommand(cmds.back().first);
|
||||
cmds.emplace_back(new StdTreeRecordSelection(),cmds.size());
|
||||
mgr.addCommand(cmds.back().first);
|
||||
|
||||
cmds.emplace_back(nullptr,0);
|
||||
|
||||
cmds.emplace_back(new StdTreeSingleDocument(),cmds.size()+1);
|
||||
mgr.addCommand(cmds.back().first);
|
||||
cmds.emplace_back(new StdTreeMultiDocument(),cmds.size()+1);
|
||||
mgr.addCommand(cmds.back().first);
|
||||
cmds.emplace_back(new StdTreeCollapseDocument(),cmds.size()-2);
|
||||
mgr.addCommand(cmds.back().first);
|
||||
|
||||
cmds.emplace_back(nullptr,0);
|
||||
|
||||
cmds.emplace_back(new StdTreeDrag(),cmds.size());
|
||||
mgr.addCommand(cmds.back().first);
|
||||
|
||||
cmds.emplace_back(new StdTreeSelection(),cmds.size());
|
||||
mgr.addCommand(cmds.back().first);
|
||||
}
|
||||
|
||||
Action * StdTreeViewDocument::createAction(void)
|
||||
{
|
||||
Action * StdCmdTreeViewActions::createAction(void) {
|
||||
ActionGroup* pcAction = new ActionGroup(this, getMainWindow());
|
||||
pcAction->setDropDownMenu(true);
|
||||
pcAction->setText(QCoreApplication::translate(this->className(), sMenuText));
|
||||
pcAction->setExclusive(false);
|
||||
applyCommandData(this->className(), pcAction);
|
||||
pcAction->setCheckable(true);
|
||||
|
||||
CommandManager &grp = Application::Instance->commandManager();
|
||||
Command* cmd0 = grp.getCommandByName("Std_TreeSingleDocument");
|
||||
Command* cmd1 = grp.getCommandByName("Std_TreeMultiDocument");
|
||||
Command* cmd2 = grp.getCommandByName("Std_TreeCollapseDocument");
|
||||
cmd0->addToGroup(pcAction, true);
|
||||
cmd1->addToGroup(pcAction, true);
|
||||
cmd2->addToGroup(pcAction, true);
|
||||
for(auto &v : cmds) {
|
||||
if(!v.first)
|
||||
pcAction->addAction(QString::fromLatin1(""))->setSeparator(true);
|
||||
else
|
||||
v.first->addToGroup(pcAction);
|
||||
}
|
||||
pcAction->setIcon(BitmapFactory().iconFromTheme(cmds[0].first->getPixmap()));
|
||||
pcAction->setChecked(cmds[0].first->getAction()->isChecked(),true);
|
||||
|
||||
return pcAction;
|
||||
}
|
||||
|
||||
void StdTreeViewDocument::activated(int iMsg)
|
||||
void StdCmdTreeViewActions::activated(int iMsg)
|
||||
{
|
||||
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
|
||||
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("View");
|
||||
group->SetInt("TreeViewDocument", iMsg);
|
||||
App::GetApplication().setActiveDocument(App::GetApplication().getActiveDocument());
|
||||
}
|
||||
if(iMsg<0 || iMsg>=(int)cmds.size())
|
||||
return;
|
||||
|
||||
auto &v = cmds[iMsg];
|
||||
if(!v.first)
|
||||
return;
|
||||
|
||||
bool StdTreeViewDocument::isActive(void)
|
||||
{
|
||||
ActionGroup* grp = qobject_cast<ActionGroup*>(_pcAction);
|
||||
if (grp) {
|
||||
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
|
||||
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("View");
|
||||
int mode = group->GetInt("TreeViewDocument", 0);
|
||||
int index = grp->checkedAction();
|
||||
if (index != mode) {
|
||||
grp->setCheckedAction(mode);
|
||||
}
|
||||
if(triggerSource()!=TriggerChildAction)
|
||||
v.first->invoke(0);
|
||||
|
||||
Action* cmdAction = v.first->getAction();
|
||||
if(_pcAction && cmdAction) {
|
||||
_pcAction->setIcon(BitmapFactory().iconFromTheme(v.first->getPixmap()));
|
||||
_pcAction->setChecked(cmdAction->isChecked(),true);
|
||||
_pcAction->setProperty("defaultAction", QVariant((int)v.second));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -3065,6 +3351,9 @@ void CreateViewStdCommands(void)
|
||||
rcCmdMgr.addCommand(new StdViewBoxZoom());
|
||||
rcCmdMgr.addCommand(new StdBoxSelection());
|
||||
rcCmdMgr.addCommand(new StdCmdTreeSelection());
|
||||
rcCmdMgr.addCommand(new StdCmdTreeExpand());
|
||||
rcCmdMgr.addCommand(new StdCmdTreeCollapse());
|
||||
rcCmdMgr.addCommand(new StdCmdTreeSelectAllInstances());
|
||||
rcCmdMgr.addCommand(new StdCmdMeasureDistance());
|
||||
rcCmdMgr.addCommand(new StdCmdSceneInspector());
|
||||
rcCmdMgr.addCommand(new StdCmdTextureMapping());
|
||||
@@ -3073,7 +3362,9 @@ void CreateViewStdCommands(void)
|
||||
rcCmdMgr.addCommand(new StdCmdAxisCross());
|
||||
rcCmdMgr.addCommand(new CmdViewMeasureClearAll());
|
||||
rcCmdMgr.addCommand(new CmdViewMeasureToggleAll());
|
||||
rcCmdMgr.addCommand(new StdTreeViewDocument());
|
||||
rcCmdMgr.addCommand(new StdCmdSelBack());
|
||||
rcCmdMgr.addCommand(new StdCmdSelForward());
|
||||
rcCmdMgr.addCommand(new StdCmdTreeViewActions());
|
||||
}
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>396</width>
|
||||
<height>553</height>
|
||||
<width>425</width>
|
||||
<height>578</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -195,6 +195,26 @@ See the FreeCAD Wiki for details about the image.</string>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="treeModeLabel">
|
||||
<property name="text">
|
||||
<string>Tree view mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="treeMode"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -134,6 +134,8 @@ void DlgGeneralImp::saveSettings()
|
||||
hGrp->SetInt("ToolbarIconSize", pixel);
|
||||
getMainWindow()->setIconSize(QSize(pixel,pixel));
|
||||
|
||||
hGrp->SetInt("TreeViewMode",ui->treeMode->currentIndex());
|
||||
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow");
|
||||
hGrp->SetBool("TiledBackground", ui->tiledBackground->isChecked());
|
||||
QMdiArea* mdi = getMainWindow()->findChild<QMdiArea*>();
|
||||
@@ -248,6 +250,14 @@ void DlgGeneralImp::loadSettings()
|
||||
}
|
||||
ui->toolbarIconSize->setCurrentIndex(index);
|
||||
|
||||
ui->treeMode->addItem(tr("CombiView"));
|
||||
ui->treeMode->addItem(tr("TreeView + PropertyView"));
|
||||
ui->treeMode->addItem(tr("Both"));
|
||||
index = hGrp->GetInt("TreeViewMode");
|
||||
if (index<0 || index>2)
|
||||
index=0;
|
||||
ui->treeMode->setCurrentIndex(index);
|
||||
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow");
|
||||
ui->tiledBackground->setChecked(hGrp->GetBool("TiledBackground", false));
|
||||
|
||||
|
||||
4730
src/Gui/Tree.cpp
4730
src/Gui/Tree.cpp
File diff suppressed because it is too large
Load Diff
347
src/Gui/Tree.h
347
src/Gui/Tree.h
@@ -25,7 +25,11 @@
|
||||
#define GUI_TREE_H
|
||||
|
||||
#include <QTreeWidget>
|
||||
#include <QTime>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Persistence.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/Application.h>
|
||||
|
||||
@@ -38,8 +42,9 @@ namespace Gui {
|
||||
|
||||
class ViewProviderDocumentObject;
|
||||
class DocumentObjectItem;
|
||||
typedef std::set<DocumentObjectItem*> DocumentObjectItems;
|
||||
typedef std::shared_ptr<DocumentObjectItems> DocumentObjectItemsPtr;
|
||||
class DocumentObjectData;
|
||||
typedef std::shared_ptr<DocumentObjectData> DocumentObjectDataPtr;
|
||||
|
||||
class DocumentItem;
|
||||
|
||||
/// highlight modes for the tree items
|
||||
@@ -68,16 +73,56 @@ class TreeWidget : public QTreeWidget, public SelectionObserver
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TreeWidget(QWidget* parent=0);
|
||||
TreeWidget(const char *name, QWidget* parent=0);
|
||||
~TreeWidget();
|
||||
|
||||
void scrollItemToTop(Gui::Document*);
|
||||
void setItemsSelected (const QList<QTreeWidgetItem *> items, bool select);
|
||||
static void scrollItemToTop();
|
||||
void selectAllInstances(const ViewProviderDocumentObject &vpd);
|
||||
void selectLinkedObject(App::DocumentObject *linked);
|
||||
void selectAllLinks(App::DocumentObject *obj);
|
||||
void expandSelectedItems(TreeItemMode mode);
|
||||
|
||||
bool eventFilter(QObject *, QEvent *ev);
|
||||
|
||||
struct SelInfo {
|
||||
App::DocumentObject *topParent;
|
||||
std::string subname;
|
||||
ViewProviderDocumentObject *parentVp;
|
||||
ViewProviderDocumentObject *vp;
|
||||
};
|
||||
/* Return a list of selected object of a give document and their parent
|
||||
*
|
||||
* This function can return the non-group parent of the selected object,
|
||||
* which Gui::Selection() cannot provide.
|
||||
*/
|
||||
static std::vector<SelInfo> getSelection(App::Document *doc=0);
|
||||
|
||||
static TreeWidget *instance();
|
||||
|
||||
static const int DocumentType;
|
||||
static const int ObjectType;
|
||||
|
||||
void markItem(const App::DocumentObject* Obj,bool mark);
|
||||
void syncView(ViewProviderDocumentObject *vp);
|
||||
|
||||
const char *getTreeName() const;
|
||||
|
||||
static void updateStatus(bool delay=true);
|
||||
|
||||
static bool isObjectShowable(App::DocumentObject *obj);
|
||||
|
||||
// Check if obj can be considered as a top level object
|
||||
static void checkTopParent(App::DocumentObject *&obj, std::string &subname);
|
||||
|
||||
DocumentItem *getDocumentItem(const Gui::Document *) const;
|
||||
|
||||
static Gui::Document *selectedDocument();
|
||||
|
||||
void startDragging();
|
||||
|
||||
void resetItemSearch();
|
||||
void startItemSearch();
|
||||
void itemSearch(const QString &text, bool select);
|
||||
|
||||
protected:
|
||||
/// Observer message from the Selection
|
||||
@@ -99,8 +144,12 @@ protected:
|
||||
bool event(QEvent *e);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void mouseDoubleClickEvent(QMouseEvent * event);
|
||||
QList<App::DocumentObject *> buildListChildren(QTreeWidgetItem* targetitem,
|
||||
Gui::ViewProviderDocumentObject* vp);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *) override;
|
||||
void hideEvent(QHideEvent *) override;
|
||||
void leaveEvent(QEvent *) override;
|
||||
void _updateStatus(bool delay=true);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onCreateGroup();
|
||||
@@ -109,7 +158,15 @@ protected Q_SLOTS:
|
||||
void onStartEditing();
|
||||
void onFinishEditing();
|
||||
void onSkipRecompute(bool on);
|
||||
void onAllowPartialRecompute(bool on);
|
||||
void onReloadDoc();
|
||||
void onCloseDoc();
|
||||
void onMarkRecompute();
|
||||
void onRecomputeObject();
|
||||
void onPreSelectTimer();
|
||||
void onSelectTimer();
|
||||
void onShowHidden();
|
||||
void onHideInTree();
|
||||
void onSearchObjects();
|
||||
|
||||
private Q_SLOTS:
|
||||
@@ -117,34 +174,74 @@ private Q_SLOTS:
|
||||
void onItemEntered(QTreeWidgetItem * item);
|
||||
void onItemCollapsed(QTreeWidgetItem * item);
|
||||
void onItemExpanded(QTreeWidgetItem * item);
|
||||
void onTestStatus(void);
|
||||
void onUpdateStatus(void);
|
||||
|
||||
Q_SIGNALS:
|
||||
void emitSearchObjects();
|
||||
|
||||
private:
|
||||
void slotNewDocument(const Gui::Document&);
|
||||
void slotNewDocument(const Gui::Document&, bool);
|
||||
void slotDeleteDocument(const Gui::Document&);
|
||||
void slotRenameDocument(const Gui::Document&);
|
||||
void slotActiveDocument(const Gui::Document&);
|
||||
void slotRelabelDocument(const Gui::Document&);
|
||||
void slotShowHidden(const Gui::Document &);
|
||||
void slotChangedViewObject(const Gui::ViewProvider &, const App::Property &);
|
||||
void slotStartOpenDocument();
|
||||
void slotFinishOpenDocument();
|
||||
void _slotDeleteObject(const Gui::ViewProviderDocumentObject&, DocumentItem *deletingDoc);
|
||||
void slotDeleteObject(const Gui::ViewProviderDocumentObject&);
|
||||
void slotChangeObject(const Gui::ViewProviderDocumentObject&, const App::Property &prop);
|
||||
|
||||
void changeEvent(QEvent *e);
|
||||
void setupText();
|
||||
|
||||
void updateChildren(App::DocumentObject *obj,
|
||||
const std::set<DocumentObjectDataPtr> &data, bool output, bool force);
|
||||
|
||||
private:
|
||||
QAction* createGroupAction;
|
||||
QAction* relabelObjectAction;
|
||||
QAction* finishEditingAction;
|
||||
QAction* skipRecomputeAction;
|
||||
QAction* allowPartialRecomputeAction;
|
||||
QAction* markRecomputeAction;
|
||||
QAction* recomputeObjectAction;
|
||||
QAction* showHiddenAction;
|
||||
QAction* hideInTreeAction;
|
||||
QAction* reloadDocAction;
|
||||
QAction* closeDocAction;
|
||||
QAction* searchObjectsAction;
|
||||
QTreeWidgetItem* contextItem;
|
||||
|
||||
QTreeWidgetItem *contextItem;
|
||||
App::DocumentObject *searchObject;
|
||||
Gui::Document *searchDoc;
|
||||
Gui::Document *searchContextDoc;
|
||||
DocumentObjectItem *editingItem;
|
||||
DocumentItem *currentDocItem;
|
||||
QTreeWidgetItem* rootItem;
|
||||
QTimer* statusTimer;
|
||||
static QPixmap* documentPixmap;
|
||||
std::map<const Gui::Document*,DocumentItem*> DocumentMap;
|
||||
bool fromOutside;
|
||||
QTimer* selectTimer;
|
||||
QTimer* preselectTimer;
|
||||
QTime preselectTime;
|
||||
static std::unique_ptr<QPixmap> documentPixmap;
|
||||
static std::unique_ptr<QPixmap> documentPartialPixmap;
|
||||
std::unordered_map<const Gui::Document*,DocumentItem*> DocumentMap;
|
||||
std::unordered_map<App::DocumentObject*,std::set<DocumentObjectDataPtr> > ObjectTable;
|
||||
|
||||
enum ChangedObjectStatus {
|
||||
CS_Output,
|
||||
CS_Error,
|
||||
};
|
||||
std::unordered_map<App::DocumentObject*,std::bitset<32> > ChangedObjects;
|
||||
|
||||
std::unordered_map<std::string,std::vector<long> > NewObjects;
|
||||
|
||||
static std::set<TreeWidget*> Instances;
|
||||
|
||||
std::string myName; // for debugging purpose
|
||||
|
||||
friend class DocumentItem;
|
||||
friend class DocumentObjectItem;
|
||||
|
||||
typedef boost::signals2::connection Connection;
|
||||
Connection connectNewDocument;
|
||||
@@ -152,6 +249,8 @@ private:
|
||||
Connection connectRenDocument;
|
||||
Connection connectActDocument;
|
||||
Connection connectRelDocument;
|
||||
Connection connectShowHidden;
|
||||
Connection connectChangedViewObj;
|
||||
};
|
||||
|
||||
/** The link between the tree and a document.
|
||||
@@ -159,21 +258,42 @@ private:
|
||||
* the visibility and the functions of the document.
|
||||
* \author Jürgen Riegel
|
||||
*/
|
||||
class DocumentItem : public QTreeWidgetItem
|
||||
class DocumentItem : public QTreeWidgetItem, public Base::Persistence
|
||||
{
|
||||
public:
|
||||
DocumentItem(const Gui::Document* doc, QTreeWidgetItem * parent);
|
||||
~DocumentItem();
|
||||
|
||||
const Gui::Document* document() const;
|
||||
void setObjectHighlighted(const char*, bool);
|
||||
void setObjectSelected(const char*, bool);
|
||||
void clearSelection(void);
|
||||
void updateSelection(void);
|
||||
void selectItems(void);
|
||||
Gui::Document* document() const;
|
||||
void clearSelection(DocumentObjectItem *exclude=0);
|
||||
void updateSelection(QTreeWidgetItem *, bool unselect=false);
|
||||
void updateSelection();
|
||||
void updateItemSelection(DocumentObjectItem *);
|
||||
void selectItems(bool sync);
|
||||
void testStatus(void);
|
||||
void setData(int column, int role, const QVariant & value);
|
||||
void populateItem(DocumentObjectItem *item, bool refresh = false);
|
||||
void populateItem(DocumentObjectItem *item, bool refresh=false, bool delayUpdate=true);
|
||||
bool populateObject(App::DocumentObject *obj);
|
||||
void selectAllInstances(const ViewProviderDocumentObject &vpd);
|
||||
bool showItem(DocumentObjectItem *item, bool select, bool force=false);
|
||||
void updateItemsVisibility(QTreeWidgetItem *item, bool show);
|
||||
void updateLinks(const ViewProviderDocumentObject &view);
|
||||
ViewProviderDocumentObject *getViewProvider(App::DocumentObject *);
|
||||
|
||||
bool showHidden() const;
|
||||
void setShowHidden(bool show);
|
||||
|
||||
TreeWidget *getTree() const;
|
||||
const char *getTreeName() const;
|
||||
|
||||
bool isObjectShowable(App::DocumentObject *obj);
|
||||
|
||||
virtual unsigned int getMemSize (void) const override;
|
||||
virtual void Save (Base::Writer &) const override;
|
||||
virtual void Restore(Base::XMLReader &) override;
|
||||
|
||||
class ExpandInfo;
|
||||
typedef std::shared_ptr<ExpandInfo> ExpandInfoPtr;
|
||||
|
||||
protected:
|
||||
/** Adds a view provider to the document item.
|
||||
@@ -183,35 +303,59 @@ protected:
|
||||
/** Removes a view provider from the document item.
|
||||
* If this view provider is not added nothing happens.
|
||||
*/
|
||||
void slotDeleteObject (const Gui::ViewProviderDocumentObject&);
|
||||
void slotChangeObject (const Gui::ViewProviderDocumentObject&);
|
||||
void slotRenameObject (const Gui::ViewProviderDocumentObject&);
|
||||
void slotActiveObject (const Gui::ViewProviderDocumentObject&);
|
||||
void slotInEdit (const Gui::ViewProviderDocumentObject&);
|
||||
void slotResetEdit (const Gui::ViewProviderDocumentObject&);
|
||||
void slotHighlightObject (const Gui::ViewProviderDocumentObject&,const Gui::HighlightMode&,bool);
|
||||
void slotExpandObject (const Gui::ViewProviderDocumentObject&,const Gui::TreeItemMode&);
|
||||
void slotHighlightObject (const Gui::ViewProviderDocumentObject&,const Gui::HighlightMode&,bool,
|
||||
const App::DocumentObject *parent, const char *subname);
|
||||
void slotExpandObject (const Gui::ViewProviderDocumentObject&,const Gui::TreeItemMode&,
|
||||
const App::DocumentObject *parent, const char *subname);
|
||||
void slotScrollToObject (const Gui::ViewProviderDocumentObject&);
|
||||
void slotRecomputed (const App::Document &doc, const std::vector<App::DocumentObject*> &objs);
|
||||
void slotRecomputedObject(const App::DocumentObject &);
|
||||
|
||||
bool updateObject(const Gui::ViewProviderDocumentObject&, const App::Property &prop);
|
||||
|
||||
bool createNewItem(const Gui::ViewProviderDocumentObject&,
|
||||
QTreeWidgetItem *parent=0, int index=-1,
|
||||
DocumentObjectItemsPtr ptrs = DocumentObjectItemsPtr());
|
||||
|
||||
DocumentObjectDataPtr ptrs = DocumentObjectDataPtr());
|
||||
|
||||
int findRootIndex(App::DocumentObject *childObj);
|
||||
|
||||
DocumentObjectItem *findItemByObject(bool sync,
|
||||
App::DocumentObject *obj, const char *subname, bool select=false);
|
||||
|
||||
DocumentObjectItem *findItem(bool sync, DocumentObjectItem *item, const char *subname, bool select=true);
|
||||
|
||||
App::DocumentObject *getTopParent(App::DocumentObject *obj, std::string &subname);
|
||||
|
||||
typedef std::unordered_map<const ViewProvider *, std::vector<ViewProviderDocumentObject*> > ViewParentMap;
|
||||
void populateParents(const ViewProvider *vp, ViewParentMap &);
|
||||
|
||||
private:
|
||||
const Gui::Document* pDocument;
|
||||
std::map<std::string,DocumentObjectItemsPtr> ObjectMap;
|
||||
const char *treeName; // for debugging purpose
|
||||
Gui::Document* pDocument;
|
||||
std::unordered_map<App::DocumentObject*,DocumentObjectDataPtr> ObjectMap;
|
||||
std::unordered_map<App::DocumentObject*, std::set<App::DocumentObject*> > _ParentMap;
|
||||
std::vector<App::DocumentObject*> PopulateObjects;
|
||||
|
||||
ExpandInfoPtr _ExpandInfo;
|
||||
void restoreItemExpansion(const ExpandInfoPtr &, DocumentObjectItem *);
|
||||
|
||||
typedef boost::signals2::connection Connection;
|
||||
Connection connectNewObject;
|
||||
Connection connectDelObject;
|
||||
Connection connectChgObject;
|
||||
Connection connectRenObject;
|
||||
Connection connectActObject;
|
||||
Connection connectEdtObject;
|
||||
Connection connectResObject;
|
||||
Connection connectHltObject;
|
||||
Connection connectExpObject;
|
||||
Connection connectScrObject;
|
||||
Connection connectRecomputed;
|
||||
Connection connectRecomputedObj;
|
||||
|
||||
friend class TreeWidget;
|
||||
friend class DocumentObjectData;
|
||||
friend class DocumentObjectItem;
|
||||
};
|
||||
|
||||
/** The link between the tree and a document object.
|
||||
@@ -222,31 +366,68 @@ private:
|
||||
class DocumentObjectItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
DocumentObjectItem(Gui::ViewProviderDocumentObject* pcViewProvider,
|
||||
DocumentObjectItemsPtr selves);
|
||||
DocumentObjectItem(DocumentItem *ownerDocItem, DocumentObjectDataPtr data);
|
||||
~DocumentObjectItem();
|
||||
|
||||
Gui::ViewProviderDocumentObject* object() const;
|
||||
void testStatus();
|
||||
void testStatus(bool resetStatus, QIcon &icon1, QIcon &icon2);
|
||||
void testStatus(bool resetStatus);
|
||||
void displayStatusInfo();
|
||||
void setExpandedStatus(bool);
|
||||
void setData(int column, int role, const QVariant & value);
|
||||
bool isChildOfItem(DocumentObjectItem*);
|
||||
|
||||
protected:
|
||||
void slotChangeIcon();
|
||||
void slotChangeToolTip(const QString&);
|
||||
void slotChangeStatusTip(const QString&);
|
||||
void restoreBackground();
|
||||
|
||||
// Get the parent document (where the object is stored) of this item
|
||||
DocumentItem *getParentDocument() const;
|
||||
// Get the owner document (where the object is displayed, either stored or
|
||||
// linked in) of this object
|
||||
DocumentItem *getOwnerDocument() const;
|
||||
|
||||
// check if a new item is required at root
|
||||
bool requiredAtRoot(bool excludeSelf=true) const;
|
||||
|
||||
// return the owner, and full quanlified subname
|
||||
App::DocumentObject *getFullSubName(std::ostringstream &str,
|
||||
DocumentObjectItem *parent = 0) const;
|
||||
|
||||
// return the immediate decendent of the common ancestor of this item and
|
||||
// 'cousin'.
|
||||
App::DocumentObject *getRelativeParent(
|
||||
std::ostringstream &str,
|
||||
DocumentObjectItem *cousin,
|
||||
App::DocumentObject **topParent=0,
|
||||
std::string *topSubname=0) const;
|
||||
|
||||
// return the top most linked group owner's name, and subname. This method
|
||||
// is necssary despite have getFullSubName above is because native geo group
|
||||
// cannot handle selection with sub name. So only a linked group can have
|
||||
// subname in selection
|
||||
int getSubName(std::ostringstream &str, App::DocumentObject *&topParent) const;
|
||||
|
||||
void setHighlight(bool set, Gui::HighlightMode mode = Gui::LightBlue);
|
||||
|
||||
const char *getName() const;
|
||||
const char *getTreeName() const;
|
||||
|
||||
bool isLink() const;
|
||||
bool isLinkFinal() const;
|
||||
bool isParentLink() const;
|
||||
int isGroup() const;
|
||||
int isParentGroup() const;
|
||||
|
||||
DocumentObjectItem *getParentItem() const;
|
||||
TreeWidget *getTree() const;
|
||||
|
||||
private:
|
||||
QBrush bgBrush;
|
||||
DocumentItem *myOwner;
|
||||
DocumentObjectDataPtr myData;
|
||||
std::vector<std::string> mySubs;
|
||||
typedef boost::signals2::connection Connection;
|
||||
int previousStatus;
|
||||
Gui::ViewProviderDocumentObject* viewObject;
|
||||
Connection connectIcon;
|
||||
Connection connectTool;
|
||||
Connection connectStat;
|
||||
|
||||
DocumentObjectItemsPtr myselves;
|
||||
int selected;
|
||||
bool populated;
|
||||
|
||||
friend class TreeWidget;
|
||||
@@ -258,7 +439,7 @@ class TreePanel : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TreePanel(QWidget* parent=nullptr);
|
||||
TreePanel(const char *name, QWidget* parent=nullptr);
|
||||
virtual ~TreePanel();
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *ev);
|
||||
@@ -267,16 +448,11 @@ private Q_SLOTS:
|
||||
void accept();
|
||||
void showEditor();
|
||||
void hideEditor();
|
||||
void findMatchingItems(const QString&);
|
||||
|
||||
private:
|
||||
void searchTreeItem(QTreeWidgetItem* item, const QString& text);
|
||||
void selectTreeItem(QTreeWidgetItem* item, const QString& text);
|
||||
void resetBackground(QTreeWidgetItem* item);
|
||||
void itemSearch(const QString &text);
|
||||
|
||||
private:
|
||||
QLineEdit* searchBox;
|
||||
QTreeWidget* treeWidget;
|
||||
TreeWidget* treeWidget;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -295,8 +471,65 @@ private:
|
||||
QTreeWidget* treeWidget;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* TreeWidget item delegate for editing
|
||||
*/
|
||||
class TreeWidgetEditDelegate: public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TreeWidgetEditDelegate(QObject* parent=0);
|
||||
virtual QWidget* createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &, const QModelIndex &index) const;
|
||||
};
|
||||
|
||||
|
||||
/// Helper class to read/write tree view options
|
||||
class GuiExport TreeParams : public ParameterGrp::ObserverType {
|
||||
public:
|
||||
TreeParams();
|
||||
void OnChange(Base::Subject<const char*> &, const char* sReason);
|
||||
static TreeParams *Instance();
|
||||
|
||||
#define FC_TREEPARAM_DEFS \
|
||||
FC_TREEPARAM_DEF(SyncSelection,bool,Bool,true) \
|
||||
FC_TREEPARAM_DEF(SyncView,bool,Bool,true) \
|
||||
FC_TREEPARAM_DEF(PreSelection,bool,Bool,true) \
|
||||
FC_TREEPARAM_DEF(SyncPlacement,bool,Bool,false) \
|
||||
FC_TREEPARAM_DEF(RecordSelection,bool,Bool,true) \
|
||||
FC_TREEPARAM_DEF(DocumentMode,int,Int,1) \
|
||||
FC_TREEPARAM_DEF(StatusTimeout,int,Int,100) \
|
||||
FC_TREEPARAM_DEF(SelectionTimeout,int,Int,100) \
|
||||
FC_TREEPARAM_DEF(PreSelectionTimeout,int,Int,500) \
|
||||
FC_TREEPARAM_DEF(PreSelectionDelay,int,Int,700) \
|
||||
FC_TREEPARAM_DEF(RecomputeOnDrop,bool,Bool,true) \
|
||||
FC_TREEPARAM_DEF(KeepRootOrder,bool,Bool,true) \
|
||||
FC_TREEPARAM_DEF(TreeActiveAutoExpand,bool,Bool,true) \
|
||||
|
||||
#define FC_TREEPARAM_FUNCS(_name,_type,_Type,_default) \
|
||||
_type _name() const {return _##_name;} \
|
||||
void set##_name(_type);\
|
||||
void on##_name##Changed();
|
||||
|
||||
#undef FC_TREEPARAM_DEF
|
||||
#define FC_TREEPARAM_DEF FC_TREEPARAM_FUNCS
|
||||
FC_TREEPARAM_DEFS
|
||||
|
||||
private:
|
||||
|
||||
#define FC_TREEPARAM_DECLARE(_name,_type,_Type,_default) \
|
||||
_type _##_name;
|
||||
|
||||
#undef FC_TREEPARAM_DEF
|
||||
#define FC_TREEPARAM_DEF FC_TREEPARAM_DECLARE
|
||||
FC_TREEPARAM_DEFS
|
||||
|
||||
ParameterGrp::handle handle;
|
||||
};
|
||||
|
||||
#define FC_TREEPARAM(_name) (Gui::TreeParams::Instance()->_name())
|
||||
#define FC_TREEPARAM_SET(_name,_v) Gui::TreeParams::Instance()->set##_name(_v)
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // GUI_TREE_H
|
||||
|
||||
|
||||
@@ -204,13 +204,21 @@ void ViewProviderDocumentObject::hide(void)
|
||||
|
||||
void ViewProviderDocumentObject::show(void)
|
||||
{
|
||||
if(TreeWidget::isObjectShowable(getObject()))
|
||||
ViewProvider::show();
|
||||
else {
|
||||
Visibility.setValue(false);
|
||||
if(getObject())
|
||||
getObject()->Visibility.setValue(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// use this bit to check whether 'Visibility' must be adjusted
|
||||
if (Visibility.testStatus(App::Property::User2) == false) {
|
||||
Visibility.setStatus(App::Property::User2, true);
|
||||
Visibility.setValue(true);
|
||||
Visibility.setStatus(App::Property::User2, false);
|
||||
}
|
||||
ViewProvider::show();
|
||||
}
|
||||
|
||||
void ViewProviderDocumentObject::updateView()
|
||||
|
||||
@@ -340,6 +340,35 @@ void Workbench::createMainWindowPopupMenu(MenuItem*) const
|
||||
{
|
||||
}
|
||||
|
||||
void Workbench::createLinkMenu(MenuItem *item) {
|
||||
if(!item || !App::GetApplication().getActiveDocument())
|
||||
return;
|
||||
MenuItem* linkMenu = new MenuItem;
|
||||
linkMenu->setCommand("Link actions");
|
||||
*linkMenu << "Std_LinkMakeGroup" << "Std_LinkMake";
|
||||
|
||||
auto &rMgr = Application::Instance->commandManager();
|
||||
const char *cmds[] = {"Std_LinkMakeRelative",0,"Std_LinkUnlink","Std_LinkReplace",
|
||||
"Std_LinkImport","Std_LinkImportAll",0,"Std_LinkSelectLinked",
|
||||
"Std_LinkSelectLinkedFinal","Std_LinkSelectAllLinks"};
|
||||
bool separator = true;
|
||||
for(size_t i=0;i<sizeof(cmds)/sizeof(cmds[0]);++i) {
|
||||
if(!cmds[i]) {
|
||||
if(separator) {
|
||||
separator = false;
|
||||
*linkMenu << "Separator";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
auto cmd = rMgr.getCommandByName(cmds[i]);
|
||||
if(cmd->isActive()) {
|
||||
separator = true;
|
||||
*linkMenu << cmds[i];
|
||||
}
|
||||
}
|
||||
*item << linkMenu;
|
||||
}
|
||||
|
||||
void Workbench::activated()
|
||||
{
|
||||
}
|
||||
@@ -446,6 +475,9 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
|
||||
{
|
||||
if (strcmp(recipient,"View") == 0)
|
||||
{
|
||||
createLinkMenu(item);
|
||||
*item << "Separator";
|
||||
|
||||
MenuItem* StdViews = new MenuItem;
|
||||
StdViews->setCommand( "Standard views" );
|
||||
|
||||
@@ -470,9 +502,9 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
|
||||
{
|
||||
if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) > 0) {
|
||||
*item << "Std_ToggleVisibility" << "Std_ShowSelection" << "Std_HideSelection"
|
||||
<< "Std_ToggleSelectability" << "Separator" << "Std_SetAppearance"
|
||||
<< "Std_RandomColor" << "Std_Cut" << "Std_Copy" << "Std_Paste"
|
||||
<< "Separator" << "Std_Delete";
|
||||
<< "Std_ToggleSelectability" << "Std_TreeSelectAllInstances" << "Separator"
|
||||
<< "Std_SetAppearance" << "Std_RandomColor" << "Separator"
|
||||
<< "Std_Cut" << "Std_Copy" << "Std_Paste" << "Std_Delete" << "Separator";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -492,8 +524,8 @@ MenuItem* StdWorkbench::setupMenuBar() const
|
||||
file->setCommand("&File");
|
||||
*file << "Std_New" << "Std_Open" << "Separator" << "Std_CloseActiveWindow"
|
||||
<< "Std_CloseAllWindows" << "Separator" << "Std_Save" << "Std_SaveAs"
|
||||
<< "Std_SaveCopy" << "Std_Revert" << "Separator" << "Std_Import"
|
||||
<< "Std_Export" << "Std_MergeProjects" << "Std_ProjectInfo"
|
||||
<< "Std_SaveCopy" << "Std_SaveAll" << "Std_Revert" << "Separator" << "Std_Import"
|
||||
<< "Std_Export" << "Std_MergeProjects" << "Std_ProjectInfo"
|
||||
<< "Separator" << "Std_Print" << "Std_PrintPreview" << "Std_PrintPdf"
|
||||
<< "Separator" << "Std_RecentFiles" << "Separator" << "Std_Quit";
|
||||
|
||||
@@ -547,15 +579,16 @@ MenuItem* StdWorkbench::setupMenuBar() const
|
||||
view->setCommand("&View");
|
||||
*view << "Std_ViewCreate" << "Std_OrthographicCamera" << "Std_PerspectiveCamera" << "Std_MainFullscreen" << "Separator"
|
||||
<< stdviews << "Std_FreezeViews" << "Std_DrawStyle" << "Separator" << view3d << zoom
|
||||
<< "Std_ViewDockUndockFullscreen" << "Std_TreeViewDocument" << "Std_AxisCross" << "Std_ToggleClipPlane"
|
||||
<< "Std_ViewDockUndockFullscreen" << "Std_AxisCross" << "Std_ToggleClipPlane"
|
||||
<< "Std_TextureMapping"
|
||||
#ifdef BUILD_VR
|
||||
<< "Std_ViewVR"
|
||||
#endif
|
||||
<< "Separator" << visu
|
||||
<< "Std_ToggleVisibility" << "Std_ToggleNavigation"
|
||||
<< "Std_SetAppearance" << "Std_RandomColor" << "Separator"
|
||||
<< "Std_Workbench" << "Std_ToolBarMenu" << "Std_DockViewMenu" << "Separator"
|
||||
<< "Std_SetAppearance" << "Std_RandomColor" << "Separator"
|
||||
<< "Std_Workbench" << "Std_ToolBarMenu" << "Std_DockViewMenu" << "Separator"
|
||||
<< "Std_TreeViewActions"
|
||||
<< "Std_ViewStatusBar";
|
||||
|
||||
// Tools
|
||||
@@ -625,7 +658,8 @@ ToolBarItem* StdWorkbench::setupToolBars() const
|
||||
// View
|
||||
ToolBarItem* view = new ToolBarItem( root );
|
||||
view->setCommand("View");
|
||||
*view << "Std_ViewFitAll" << "Std_ViewFitSelection" << "Std_DrawStyle" << "Separator" << "Std_ViewIsometric" << "Separator" << "Std_ViewFront"
|
||||
*view << "Std_ViewFitAll" << "Std_ViewFitSelection" << "Std_DrawStyle"
|
||||
<< "Separator" << "Std_TreeViewActions" << "Std_ViewIsometric" << "Separator" << "Std_ViewFront"
|
||||
<< "Std_ViewTop" << "Std_ViewRight" << "Separator" << "Std_ViewRear" << "Std_ViewBottom"
|
||||
<< "Std_ViewLeft" << "Separator" << "Std_MeasureDistance" ;
|
||||
|
||||
@@ -671,6 +705,7 @@ DockWindowItems* StdWorkbench::setupDockWindows() const
|
||||
//Dagview through parameter.
|
||||
ParameterGrp::handle group = App::GetApplication().GetUserParameter().
|
||||
GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DAGView");
|
||||
|
||||
bool enabled = group->GetBool("Enabled", false);
|
||||
if (enabled)
|
||||
root->addDockWidget("Std_DAGView", Qt::RightDockWidgetArea, false, false);
|
||||
|
||||
@@ -95,6 +95,8 @@ public:
|
||||
/// remove the added TaskWatcher
|
||||
void removeTaskWatcher(void);
|
||||
|
||||
static void createLinkMenu(MenuItem *);
|
||||
|
||||
protected:
|
||||
/** Returns a MenuItem tree structure of menus for this workbench. */
|
||||
virtual MenuItem* setupMenuBar() const=0;
|
||||
|
||||
Reference in New Issue
Block a user