workspace explorer - preserve tree items expand/collapse state and selected item - implement #252

This commit is contained in:
Vadim Lopatin 2017-09-12 17:20:07 +03:00
parent b40dc8ba81
commit b34670873d
5 changed files with 130 additions and 12 deletions

View File

@ -12,7 +12,7 @@
"stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"], "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
"dependencies": { "dependencies": {
"dlangui": "==0.9.126", "dlangui": "==0.9.127",
"dsymbol": "~>0.2.9", "dsymbol": "~>0.2.9",
"dcd": "~>0.9.1" "dcd": "~>0.9.1"
}, },

View File

@ -53,6 +53,15 @@ class WorkspacePanel : DockWindow {
void onTreeItemSelected(TreeItems source, TreeItem selectedItem, bool activated) { void onTreeItemSelected(TreeItems source, TreeItem selectedItem, bool activated) {
if (!selectedItem) if (!selectedItem)
return; return;
if (_workspace) {
// save selected item id
ProjectItem item = cast(ProjectItem)selectedItem.objectParam;
if (item) {
string id = item.filename;
if (id)
_workspace.selectedWorkspaceItem = id;
}
}
if (selectedItem.intParam == ProjectItemType.SourceFile) { if (selectedItem.intParam == ProjectItemType.SourceFile) {
// file selected // file selected
if (sourceFileSelectionListener.assigned) { if (sourceFileSelectionListener.assigned) {
@ -70,6 +79,7 @@ class WorkspacePanel : DockWindow {
_tree = new TreeWidget("wstree"); _tree = new TreeWidget("wstree");
_tree.layoutHeight(FILL_PARENT).layoutHeight(FILL_PARENT); _tree.layoutHeight(FILL_PARENT).layoutHeight(FILL_PARENT);
_tree.selectionChange = &onTreeItemSelected; _tree.selectionChange = &onTreeItemSelected;
_tree.expandedChange.connect(&onTreeExpandedStateChange);
_tree.fontSize = 16; _tree.fontSize = 16;
_tree.noCollapseForSingleTopLevelItem = true; _tree.noCollapseForSingleTopLevelItem = true;
_tree.popupMenu = &onTreeItemPopupMenu; _tree.popupMenu = &onTreeItemPopupMenu;
@ -173,6 +183,10 @@ class WorkspacePanel : DockWindow {
TreeItem p = root.newChild(child.filename, child.name, "folder"); TreeItem p = root.newChild(child.filename, child.name, "folder");
p.intParam = ProjectItemType.SourceFolder; p.intParam = ProjectItemType.SourceFolder;
p.objectParam = child; p.objectParam = child;
if (restoreItemState(child.filename))
p.expand();
else
p.collapse();
addProjectItems(p, child); addProjectItems(p, child);
} else { } else {
string icon = "text-other"; string icon = "text-other";
@ -201,7 +215,55 @@ class WorkspacePanel : DockWindow {
_tree.items.setDefaultItem(defaultItem); _tree.items.setDefaultItem(defaultItem);
} }
protected bool[string] _itemStates;
protected bool _itemStatesDirty;
protected void readExpandedStateFromWorkspace() {
_itemStates.clear();
if (_workspace) {
string[] items = _workspace.expandedItems;
foreach(item; items)
_itemStates[item] = true;
}
}
protected void saveItemState(string itemPath, bool expanded) {
bool changed = restoreItemState(itemPath) != expanded;
if (!_itemStatesDirty && changed)
_itemStatesDirty = true;
if (changed) {
if (expanded) {
_itemStates[itemPath] = true;
} else {
_itemStates.remove(itemPath);
}
string[] items;
items.assumeSafeAppend;
foreach(k,v; _itemStates) {
items ~= k;
}
_workspace.expandedItems = items;
}
debug Log.d("stored Expanded state ", expanded, " for ", itemPath);
}
protected bool restoreItemState(string itemPath) {
if (auto p = itemPath in _itemStates) {
debug Log.d("restored Expanded state for ", itemPath);
return *p;
}
return false;
}
void onTreeExpandedStateChange(TreeItems source, TreeItem item) {
bool expanded = item.expanded;
ProjectItem prjItem = cast(ProjectItem)item.objectParam;
if (prjItem) {
string fn = prjItem.filename;
debug Log.d("onTreeExpandedStateChange expanded=", expanded, " fn=", fn);
saveItemState(fn, expanded);
}
}
void reloadItems() { void reloadItems() {
_tree.expandedChange.disconnect(&onTreeExpandedStateChange);
_tree.clearAllItems(); _tree.clearAllItems();
if (_workspace) { if (_workspace) {
TreeItem defaultItem = null; TreeItem defaultItem = null;
@ -211,6 +273,10 @@ class WorkspacePanel : DockWindow {
TreeItem p = root.newChild(project.filename, project.name, project.isDependency ? "project-d-dependency" : "project-d"); TreeItem p = root.newChild(project.filename, project.name, project.isDependency ? "project-d-dependency" : "project-d");
p.intParam = ProjectItemType.Project; p.intParam = ProjectItemType.Project;
p.objectParam = project; p.objectParam = project;
if (restoreItemState(project.filename))
p.expand();
else
p.collapse();
if (project && _workspace.startupProject is project) if (project && _workspace.startupProject is project)
defaultItem = p; defaultItem = p;
addProjectItems(p, project.items); addProjectItems(p, project.items);
@ -219,24 +285,31 @@ class WorkspacePanel : DockWindow {
} else { } else {
_tree.items.newChild("none", "No workspace"d, "project-development"); _tree.items.newChild("none", "No workspace"d, "project-development");
} }
_tree.onTreeContentChange(null); _tree.expandedChange.connect(&onTreeExpandedStateChange);
if (_workspace) {
TreeItem root = _tree.items.child(0); // expand default project if no information about expanded items
for (int i = 0; i < root.childCount; i++) { if (!_itemStates.length) {
TreeItem child = root.child(i); if (_workspace && _workspace.startupProject) {
if (child.intParam == ProjectItemType.Project) { string fn = _workspace.startupProject.filename;
Object obj = child.objectParam; TreeItem startupProjectItem = _tree.items.findItemById(fn);
Project prj = cast(Project)obj; if (startupProjectItem) {
if (prj && prj.isDependency) startupProjectItem.expand();
child.collapse(); saveItemState(fn, true);
} }
} }
} }
if (_workspace) {
// restore selection
string id = _workspace.selectedWorkspaceItem;
_tree.selectItem(id);
}
updateDefault(); updateDefault();
} }
@property void workspace(Workspace w) { @property void workspace(Workspace w) {
_workspace = w; _workspace = w;
readExpandedStateFromWorkspace();
reloadItems(); reloadItems();
} }

View File

@ -107,6 +107,27 @@ class Workspace : WorkspaceItem {
_settings.files(fs); _settings.files(fs);
} }
/// read list of expanded items from settings
@property string[] expandedItems() {
return _settings.expandedItems();
}
/// update list of expanded items in settings
@property void expandedItems(string[] items) {
_settings.expandedItems(items);
}
/// last selected workspace item in workspace explorer
@property string selectedWorkspaceItem() {
return _settings.selectedWorkspaceItem;
}
/// update last selected workspace item in workspace explorer
@property void selectedWorkspaceItem(string item) {
if (_settings.selectedWorkspaceItem != item)
_settings.selectedWorkspaceItem = item;
}
/// setups currrent project configuration by name /// setups currrent project configuration by name
void setStartupProjectConfiguration(string conf) void setStartupProjectConfiguration(string conf)
{ {

View File

@ -53,6 +53,30 @@ class WorkspaceSettings : SettingsFile {
} }
} }
/// list of expanded workspace explorer items
@property string[] expandedItems() {
Setting obj = _setting.settingByPath("expandedItems", SettingType.ARRAY);
return obj.strArray;
}
/// update list of expanded workspace explorer items
@property void expandedItems(string[] items) {
Setting obj = _setting.settingByPath("expandedItems", SettingType.ARRAY);
obj.strArray = items;
}
/// last selected workspace item in workspace explorer
@property string selectedWorkspaceItem() {
Setting obj = _setting.settingByPath("selectedWorkspaceItem", SettingType.STRING);
return obj.str;
}
/// update last selected workspace item in workspace explorer
@property void selectedWorkspaceItem(string item) {
Setting obj = _setting.settingByPath("selectedWorkspaceItem", SettingType.STRING);
obj.str = item;
}
/// get all breakpoints for project (for specified source file only, if specified) /// get all breakpoints for project (for specified source file only, if specified)
Breakpoint[] getProjectBreakpoints(string projectName, string projectFilePath) { Breakpoint[] getProjectBreakpoints(string projectName, string projectFilePath) {
Breakpoint[] res; Breakpoint[] res;

View File

@ -1 +1 @@
v0.7.76 v0.7.77