Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving and setting split window settings for IntelliJ IDEA plugin development

I am writing an IntelliJ IDEA plugin for saving sessions of open tabs called Tab Session. This question is a follow-up of IntelliJ IDEA Plugin Development: Save groups of tabs, save them persistently and reload a set of tabs if requested by the user.

Currently, splitted windows are not supported. Therefore i want to do two things:

  1. Retrieve information about all splitted or unsplitted windows that are containers for editor tabs. I need their position and split direction (horizontal or vertical).
  2. When this information is saved and a tab session needs to be loaded, i need to reconstruct the splitted panes and their tabs exactly as they were before.

Due to the lack of documentation i am currently browsing through the source code and found this promising piece of code:

private EditorsSplitters getSplittersFromFocus() {   return FileEditorManagerEx.getInstanceEx(myProject).getSplitters(); } 

It allows me to iterate through the set of splitted windows by using EditorWindow[] windows = getSplittersFromFocus.getOrderedWindows(). They contain the editor tabs and information about their width and height. But i did not find any information about the split direction and how to reconstruct the splitted windows as they were before.

Can anyone help?

like image 673
Alp Avatar asked Nov 01 '13 14:11

Alp


People also ask

How do I restore IntelliJ settings?

From the main menu, select File | Manage IDE Settings | Restore Default Settings. Alternatively, press Shift twice and type Restore default settings . Click Restore and Restart.

How do I restore default layout in IntelliJ?

From the main menu, select Window | Restore Default Layout or press Shift+F12 .


1 Answers

This is untested code, but as it closely resmbles the procedures inside EditorsSplitters writeExternal and writePanel functions I am positive this will work.

Presented are two methods:

  • access output of writeExternal -> should be the more stable API and offers easier access to file information
  • access components of splitter -> this way writeExternal creates it's information; sadly there is at least one protected field without getter involved (window.myPanel inside findWindowWith)
import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.impl.EditorsSplitters; import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import org.jdom.Element;  import javax.swing.*; import java.awt.*; import java.util.ArrayList;  public class SplitterAction extends AnAction {      public SplitterAction() {         super("Splitter _Action");     }      private static class Info {      }      private static class SplitInfo extends Info {         public Info    first;         public Info    second;         public boolean vertical;         public float   proportions;     }      private static class FileInfo extends Info {         public String[] fileNames;     }      @Override     public void actionPerformed(AnActionEvent anActionEvent) {         final Project project = anActionEvent.getProject();         final FileEditorManagerImpl fileEditorManager = (FileEditorManagerImpl) FileEditorManager.getInstance(project);         EditorsSplitters splitters = fileEditorManager.getSplitters();         // com.intellij.openapi.fileEditor.impl.EditorsSplitters.writeExternal() and         // com.intellij.openapi.fileEditor.impl.EditorsSplitters#writePanel inspired this         final Component component = splitters.getComponent(0);         final SplitInfo infos = splitterVisitor(component);          // or you could use this         Element root = new Element("root");         splitters.writeExternal(root);          elementVisitor(root);          // to restore from writeExternal the following should suffice         splitters.readExternal(root);         splitters.openFiles();     }      /**      * Reads writeExternal output      */     private Info elementVisitor(Element root) {         final Element splitter = root.getChild("splitter");         if (splitter != null) {             // see com.intellij.openapi.fileEditor.impl.EditorsSplitters#writePanel             final SplitInfo splitInfo = new SplitInfo();             // "vertical" or "horizontal"             splitInfo.vertical = "vertical".equals(splitter.getAttributeValue("split-orientation"));             splitInfo.proportions = Float.parseFloat(splitter.getAttributeValue("split-proportion"));             Element first = splitter.getChild("split-first");             if (first != null) {                 splitInfo.first = elementVisitor(first);             }             Element second = splitter.getChild("split-second");             if (second != null) {                 splitInfo.second = elementVisitor(second);             }             return splitInfo;         }         final Element leaf = root.getChild("leaf");         if (leaf != null) {             final ArrayList<String> fileNames = new ArrayList<String>();             for (Element file : leaf.getChildren("file")) {                 final String fileName = file.getAttributeValue("leaf-file-name");                 fileNames.add(fileName);                 // further attributes see com.intellij.openapi.fileEditor.impl.EditorsSplitters#writeComposite             }             final FileInfo fileInfo = new FileInfo();             fileInfo.fileNames = fileNames.toArray(new String[fileNames.size()]);             return fileInfo;         }         return null;     }      /**      * Acts directly upon Component      */     private SplitInfo splitterVisitor(Component component) {         if (component instanceof JPanel && ((JPanel) component).getComponentCount() > 0) {             final Component child = ((JPanel) component).getComponent(0);             if (child instanceof Splitter) {                 final Splitter splitter = (Splitter) child;                 final SplitInfo splitInfos = new SplitInfo();                 splitInfos.vertical = splitter.isVertical();                 splitInfos.proportions = splitter.getProportion();                 splitInfos.first = splitterVisitor(splitter.getFirstComponent());                 splitInfos.second = splitterVisitor(splitter.getSecondComponent());                 return splitInfos;             }             // TODO: retrieve file information         }         return null;     } } 
like image 141
TheConstructor Avatar answered Sep 21 '22 22:09

TheConstructor