August 27, 2009

Saver add-in

Saver restores tab positions when opening a solution to the last state. Let’s start from the design questions.

When to save tab positions?

Visual Studio has the OnBeforeCloseSolution event in the IVsSolutionEvents interface. When OnBeforeCloseSolution fires all tabs are still opened and this event seems like a perfect place to save tab positions.

When to restore tab positions?

There is the OnAfterOpenSolution event, but when it fires no solution files are opened yet. So, I did use this event to load tab positions, but implemented tab ordering in response to the ITabsStudioEngine.TabCreated events tab by tab.

Where to store tab positions?

Ideal place to store tab positions would be Solution User Options (.suo) file. Unfortunately, this storage is available only to VSPackages. Instead, I decided to store tab positions in a separate file with the tss extension in a directory along with the sln and suo files.

Implementation

In the OnConnection method Saver gets the IVsSolution Visual Studio interface and subscribes to solution events.

In the OnBeforeCloseSolution method file path of each tab extension (or title for non document windows) in appropriate order are stored in a tss file. Information is stored in human readable xml format.

In the OnAfterOpenSolution method tab positions are loaded from a tss file and stored in the tabsOrderList instance variable.

OnTabCreated event handler gets file path of created tab extension (or title for non document windows) as the tabCreatedID string, finds appropriate tab group in tabsOrderList, scans TabPanel from the beginning looking for a tab that is greater (based on saved order index) than the just created one and if greater tab is found moves the just created tab before it.

OnTabCreated processing should work only while solution is opening. UpdateTabsToGo method is called after loading tab positions from a tss file and calculates the number of tabs that are going to be opened. OnTabCreated event handler each time checks that there are tabsToGo and decrements this counter, thus preventing OnTabCreated to work in Saver add-in after solution is completely loaded.