<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -345,7 +345,6 @@ public:
 
 	// Settings functions
 	const wxLongLong&amp; GetId() const;
-	void MoveOldSettings(eSettings&amp; settings);
 
 	// List of documents
 	void GetDocList(vector&lt;doc_id&gt;&amp; doclist) const;</diff>
      <filename>ecore/Catalyst.h</filename>
    </modified>
    <modified>
      <diff></diff>
      <filename>ecore/ecore.lib</filename>
    </modified>
    <modified>
      <diff></diff>
      <filename>ecore/ecored.lib</filename>
    </modified>
    <modified>
      <diff>@@ -21,8 +21,8 @@
 #include &quot;images/tmLanguage.xpm&quot;
 
 /// Open a page saved from a previous session
-BundleItemEditorCtrl::BundleItemEditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame, const wxPoint&amp; pos, const wxSize&amp; size):
-	EditorCtrl(page_id, cw, bitmap,parent,parentFrame,pos,size)	
+BundleItemEditorCtrl::BundleItemEditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame):
+	EditorCtrl(page_id, cw, bitmap, parent, parentFrame)	
 {
 	const PListHandler&amp; plistHandler = m_syntaxHandler.GetPListHandler();
 	m_bundleType = plistHandler.GetBundleTypeFromUri(m_remotePath);</diff>
      <filename>src/BundleItemEditorCtrl.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,7 @@ class IUpdatePanel;
 
 class BundleItemEditorCtrl : public EditorCtrl {
 public:
-	BundleItemEditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame, const wxPoint&amp; pos = wxPoint(-100,-100), const wxSize&amp; size = wxDefaultSize);
+	BundleItemEditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame);
 
 	BundleItemEditorCtrl(CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame, const wxPoint&amp; pos = wxPoint(-100,-100), const wxSize&amp; size = wxDefaultSize);
 </diff>
      <filename>src/BundleItemEditorCtrl.h</filename>
    </modified>
    <modified>
      <diff>@@ -46,13 +46,13 @@ CompareDlg::CompareDlg(wxWindow *parent, eSettings&amp; settings):
 
 	// Add recents
 	wxArrayString recentPaths;
-	m_settings.GetRecentDiffs(recentPaths, eSettings::SP_LEFT);
+	m_settings.GetRecentDiffs(recentPaths, SP_LEFT);
 	if (!recentPaths.empty()) {
 		m_leftPathCtrl-&gt;Append(recentPaths);
 		m_leftPathCtrl-&gt;SetSelection(0);
 	}
 	recentPaths.clear();
-	m_settings.GetRecentDiffs(recentPaths, eSettings::SP_RIGHT);
+	m_settings.GetRecentDiffs(recentPaths, SP_RIGHT);
 	if (!recentPaths.empty()) {
 		m_rightPathCtrl-&gt;Append(recentPaths);
 		m_rightPathCtrl-&gt;SetSelection(0);
@@ -81,8 +81,8 @@ void CompareDlg::OnButtonOk(wxCommandEvent&amp; evt) {
 	const wxString leftPath = m_leftPathCtrl-&gt;GetValue();
 	const wxString rightPath = m_rightPathCtrl-&gt;GetValue();
 
-	m_settings.AddRecentDiff(leftPath, eSettings::SP_LEFT);
-	m_settings.AddRecentDiff(rightPath, eSettings::SP_RIGHT);
+	m_settings.AddRecentDiff(leftPath, SP_LEFT);
+	m_settings.AddRecentDiff(rightPath, SP_RIGHT);
 
 	// If we get here the paths are valid
 	evt.Skip(); </diff>
      <filename>src/CompareDlg.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -179,12 +179,12 @@ void DiffPanel::OnChildFocus(wxChildFocusEvent&amp; event) {
 	}
 }
 
-void DiffPanel::SaveSettings(unsigned int i, eSettings&amp; settings) {
+void DiffPanel::SaveSettings(unsigned int i, eFrameSettings&amp; settings) {
 	m_leftEditor-&gt;SaveSettings(i, settings, 1);
 	m_rightEditor-&gt;SaveSettings(i, settings, 2);
 }
 
-void DiffPanel::RestoreSettings(unsigned int i, eSettings&amp; settings) {
+void DiffPanel::RestoreSettings(unsigned int i, eFrameSettings&amp; settings) {
 	m_leftEditor-&gt;RestoreSettings(i, settings, 1);
 	m_rightEditor-&gt;RestoreSettings(i, settings, 2);
 </diff>
      <filename>src/DiffPanel.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -28,6 +28,7 @@ class EditorCtrl;
 class DiffBar;
 class DiffMarkBar;
 class wxGridBagSizer;
+class eFrameSettings;
 
 class DiffPanel : public wxPanel, public ITabPage {
 public:
@@ -41,8 +42,8 @@ public:
 	bool CmpPaths(const wxString&amp; path1, const wxString&amp; path2) const;
 	void UpdateMarkBars();
 
-	virtual void SaveSettings(unsigned int i, eSettings&amp; settings);
-	void RestoreSettings(unsigned int i, eSettings&amp; settings);
+	virtual void SaveSettings(unsigned int i, eFrameSettings&amp; settings);
+	void RestoreSettings(unsigned int i, eFrameSettings&amp; settings);
 
 	virtual EditorCtrl* GetActiveEditor();
 	virtual const char** RecommendedIcon() const;</diff>
      <filename>src/DiffPanel.h</filename>
    </modified>
    <modified>
      <diff>@@ -40,7 +40,7 @@ END_EVENT_TABLE()
 DocHistory::DocHistory(CatalystWrapper&amp; cw, int win_id, wxWindow* parent, wxWindowID id, const wxPoint&amp; pos, const wxSize&amp; size)
 	: wxControl(parent, id, pos, size, wxNO_BORDER|wxWANTS_CHARS|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE),
 	  m_catalyst(cw), m_dispatcher(cw.GetDispatcher()), m_doc(cw), m_mdc(), m_bitmap(1,1), m_cell(m_mdc, m_doc), m_hotNode(-1),
-	  m_revTooltip(cw)
+	  m_revTooltip(cw), m_editorCtrl(NULL), m_source_win_id(win_id)
 {
 	m_revTooltip.Create(this);
 	m_tooltipTimer.SetOwner(this, ID_TOOLTIP_TIMER);
@@ -49,7 +49,6 @@ DocHistory::DocHistory(CatalystWrapper&amp; cw, int win_id, wxWindow* parent, wxWind
 	// Initialize variables
 	m_needRedrawing = true; // Make sure the ctrl gets drawn on first idle event
 	m_document_id = -1;
-	m_source_win_id = win_id;
 	m_scrollPos = 0;
 	m_isScrolling = false;
 	m_lineHeight = 18;
@@ -65,6 +64,7 @@ DocHistory::DocHistory(CatalystWrapper&amp; cw, int win_id, wxWindow* parent, wxWind
 	m_mdc.SetFont(wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, false));
 
 	// Make sure we recieve notifications of new versions and updates
+	m_dispatcher.SubscribeC(wxT(&quot;WIN_CLOSEPAGE&quot;), (CALL_BACK)OnClosePage, this);
 	m_dispatcher.SubscribeC(wxT(&quot;WIN_CHANGEDOC&quot;), (CALL_BACK)OnChangeDoc, this);
 	m_dispatcher.SubscribeC(wxT(&quot;DOC_UPDATED&quot;), (CALL_BACK)OnDocUpdated, this);
 	m_dispatcher.SubscribeC(wxT(&quot;DOC_DELETED&quot;), (CALL_BACK)OnDocDeleted, this);
@@ -74,6 +74,7 @@ DocHistory::DocHistory(CatalystWrapper&amp; cw, int win_id, wxWindow* parent, wxWind
 }
 
 DocHistory::~DocHistory() {
+	m_dispatcher.UnSubscribe(wxT(&quot;WIN_CLOSEPAGE&quot;), (CALL_BACK)OnClosePage, this);
 	m_dispatcher.UnSubscribe(wxT(&quot;WIN_CHANGEDOC&quot;), (CALL_BACK)OnChangeDoc, this);
 	m_dispatcher.UnSubscribe(wxT(&quot;DOC_UPDATED&quot;), (CALL_BACK)OnDocUpdated, this);
 	m_dispatcher.UnSubscribe(wxT(&quot;DOC_DELETED&quot;), (CALL_BACK)OnDocDeleted, this);
@@ -85,6 +86,7 @@ DocHistory::~DocHistory() {
 void DocHistory::Clear() {
 	// Invalidate doc ref
 	m_sourceDoc.Invalidate();
+	m_editorCtrl = NULL;
 
 	// Clear data structures
 	m_items.clear();
@@ -475,9 +477,9 @@ void DocHistory::OnMouseLeftDown(wxMouseEvent&amp; event) {
 			cxLOCK_READ(m_catalyst)
 				draft_head = catalyst.GetDraftHead(hot_doc.document_id);
 			cxENDLOCK
-			m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;draft_head, m_source_win_id);
+			m_editorCtrl-&gt;SetDocument(draft_head);
 		}
-		else m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;hot_doc, m_source_win_id);
+		else m_editorCtrl-&gt;SetDocument(hot_doc);
 	}
 }
 
@@ -597,9 +599,9 @@ void DocHistory::OnVersionTreeSel(VersionTreeEvent&amp; event) {
 		cxLOCK_READ(m_catalyst)
 			draft_head = catalyst.GetDraftHead(hot_doc.document_id);
 		cxENDLOCK
-		m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;draft_head, m_source_win_id);
+		m_editorCtrl-&gt;SetDocument(draft_head);
 	}
-	else m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;hot_doc, m_source_win_id);
+	else m_editorCtrl-&gt;SetDocument(hot_doc);
 }
 
 void DocHistory::OnVersionTreeTooltip(VersionTreeEvent&amp; event) {
@@ -651,12 +653,38 @@ void DocHistory::OnEraseBackground(wxEraseEvent&amp; WXUNUSED(event)) {
 	// # no evt.skip() as we don't want the control to erase the background
 }
 
+void DocHistory::HandleDocUpdate(const doc_id&amp; di) {
+	if (di == m_editorCtrl-&gt;GetDocID()) {
+		SetDocument(di);
+	}
+	else {
+		bool isSameDoc;
+		cxLOCK_READ(m_catalyst)
+			isSameDoc = catalyst.InSameHistory(di, m_sourceDoc);
+		cxENDLOCK
+
+		// Doc has been changed in another editor, so we just redraw
+		if (isSameDoc) {
+			ReBuildTree();
+			m_isScrolling = false; // avoid moving old image if scrolling during update
+			wxClientDC dc(this);
+			DrawLayout(dc);
+		}
+	}
+}
+
+// static notification handler
+void DocHistory::OnClosePage(DocHistory* self, void* data, int WXUNUSED(filter)) {
+	if (self-&gt;m_editorCtrl == (EditorCtrl*)data) self-&gt;Clear();
+}
+
 // static notification handler
 void DocHistory::OnChangeDoc(DocHistory* self, void* data, int filter) {
-	const doc_id di = ((EditorCtrl*)data)-&gt;GetDocID();
+	if (filter != self-&gt;m_source_win_id) return;
 	//wxLogTrace(&quot;OnChangeDoc %d %d - %d&quot;, di.document_id, di.revision_id, filter);
 
-	self-&gt;m_source_win_id = filter;
+	self-&gt;m_editorCtrl = (EditorCtrl*)data;
+	const doc_id di = self-&gt;m_editorCtrl-&gt;GetDocID();
 	self-&gt;SetDocument(di);
 }
 
@@ -665,18 +693,7 @@ void DocHistory::OnDocUpdated(DocHistory* self, void* data, int WXUNUSED(filter)
 	if (!self-&gt;m_sourceDoc.IsOk()) return;
 
 	const doc_id&amp; di = *(const doc_id*)data;
-
-	bool isSameDoc;
-	cxLOCK_READ(self-&gt;m_catalyst)
-		isSameDoc = catalyst.InSameHistory(di, self-&gt;m_sourceDoc);
-	cxENDLOCK
-
-	if (isSameDoc) {
-		self-&gt;ReBuildTree();
-		self-&gt;m_isScrolling = false; // avoid moving old image if scrolling during update
-		wxClientDC dc(self);
-		self-&gt;DrawLayout(dc);
-	}
+	self-&gt;HandleDocUpdate(di);
 }
 
 // static notification handler
@@ -700,43 +717,24 @@ void DocHistory::OnDocCommited(DocHistory* self, void* data, int WXUNUSED(filter
 	if (self-&gt;m_sourceDoc.SameDoc(diPair-&gt;doc1)) {
 		self-&gt;m_isScrolling = false; // avoid moving old image if scrolling during update
 		self-&gt;SetDocument(diPair-&gt;doc2);
-	/*self-&gt;m_sourceDoc = diPair-&gt;doc2;
-
-		self-&gt;ReBuildTree();
-		self-&gt;m_isScrolling = false; // avoid moving old image if scrolling during update
-		wxClientDC dc(self);
-		self-&gt;DrawLayout(dc);*/
+	}
+	else {
+		self-&gt;HandleDocUpdate(diPair-&gt;doc2);
 	}
 }
 
 // static notification handler
 void DocHistory::OnNewRevision(DocHistory* self, void* data, int WXUNUSED(filter)) {
 	if (!self-&gt;m_sourceDoc.IsOk()) return;
-	const doc_id* const di = (doc_id*)data;
-	wxASSERT(di-&gt;IsDraft());
-
-	bool inSame;
-	cxLOCK_READ(self-&gt;m_catalyst)
-		inSame = catalyst.InSameHistory(self-&gt;m_sourceDoc, *di);
-	cxENDLOCK
 
-	if (inSame) {
-		self-&gt;SetDocument(*di);
-	}
+	const doc_id&amp; di = *(const doc_id*)data;
+	self-&gt;HandleDocUpdate(di);
 }
 
 // static notification handler
 void DocHistory::OnUpdateRevision(DocHistory* self, void* data, int WXUNUSED(filter)) {
 	if (!self-&gt;m_sourceDoc.IsOk()) return;
-	const doc_id* const di = (doc_id*)data;
-	wxASSERT(di-&gt;IsDraft());
 
-	bool inSame;
-	cxLOCK_READ(self-&gt;m_catalyst)
-		inSame = catalyst.InSameHistory(self-&gt;m_sourceDoc, *di);
-	cxENDLOCK
-
-	if (inSame) {
-		self-&gt;SetDocument(*di);
-	}
+	const doc_id&amp; di = *(const doc_id*)data;
+	self-&gt;HandleDocUpdate(di);
 }</diff>
      <filename>src/DocHistory.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -24,6 +24,7 @@
 class VersionTree;
 class VersionTreeEvent;
 class Timeline;
+class EditorCtrl;
 
 class DocHistory : public wxControl {
 public:
@@ -38,6 +39,7 @@ private:
 	void MakeItemVisible(unsigned int item_id);
 	void DrawLayout(wxDC&amp; dc);
 	void AddChildren(int parent_pos, const doc_id&amp; doc, const doc_id&amp; sel_doc, const Catalyst&amp; catalyst);
+	void HandleDocUpdate(const doc_id&amp; di);
 
 	// Event handlers
 	void OnPaint(wxPaintEvent&amp; event);
@@ -56,6 +58,7 @@ private:
 	DECLARE_EVENT_TABLE();
 
 	// Notifier handlers
+	static void OnClosePage(DocHistory* self, void* data, int filter);
 	static void OnChangeDoc(DocHistory* self, void* data, int filter);
 	static void OnDocUpdated(DocHistory* self, void* data, int filter);
 	static void OnDocDeleted(DocHistory* self, void* data, int filter);
@@ -75,6 +78,7 @@ private:
 	wxTimer m_tooltipTimer;
 	int m_hotNode;
 	RevTooltip m_revTooltip;
+	EditorCtrl* m_editorCtrl;
 
 	wxBrush bgBrush;
 	wxPen linePen;
@@ -92,7 +96,7 @@ private:
 	int m_document_id;
 	doc_id m_sourceDoc;
 	int m_selectedNode;
-	int m_source_win_id;
+	const int m_source_win_id;
 	int m_lineHeight;
 	int m_treeHeight;
 	int m_scrollPos;</diff>
      <filename>src/DocHistory.h</filename>
    </modified>
    <modified>
      <diff>@@ -173,7 +173,7 @@ const char** EditorBundlePanel::RecommendedIcon() const {
 	return m_editorCtrl-&gt;RecommendedIcon();
 }
 
-void EditorBundlePanel::SaveSettings(unsigned int i, eSettings&amp; settings) {
+void EditorBundlePanel::SaveSettings(unsigned int i, eFrameSettings&amp; settings) {
 	m_editorCtrl-&gt;SaveSettings(i, settings);
 }
 </diff>
      <filename>src/EditorBundlePanel.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -46,7 +46,7 @@ public:
 
 	virtual EditorCtrl* GetActiveEditor();
 	virtual const char** RecommendedIcon() const;
-	virtual void SaveSettings(unsigned int i, eSettings&amp; settings);
+	virtual void SaveSettings(unsigned int i, eFrameSettings&amp; settings);
 
 private:
 	void Init();</diff>
      <filename>src/EditorBundlePanel.h</filename>
    </modified>
    <modified>
      <diff>@@ -107,7 +107,7 @@ unsigned long EditorCtrl::s_ctrlDownTime = 0;
 bool EditorCtrl::s_altGrDown = false;
 
 /// Open a page saved from a previous session
-EditorCtrl::EditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame, const wxPoint&amp; pos, const wxSize&amp; size)	: 
+EditorCtrl::EditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame) : 
 	m_catalyst(cw),
 	m_doc(cw),
 	dispatcher(cw.GetDispatcher()),
@@ -144,11 +144,11 @@ EditorCtrl::EditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap,
 	m_re(NULL), 
 	m_symbolCacheToken(0)
 {
-	Create(parent, wxID_ANY, pos, size, wxNO_BORDER|wxWANTS_CHARS|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE);
+	Create(parent, wxID_ANY, wxPoint(-100,-100), wxDefaultSize, wxNO_BORDER|wxWANTS_CHARS|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE);
 	Hide(); // start hidden to avoid flicker
 	Init();
 
-	eSettings&amp; settings = eGetSettings();
+	eFrameSettings&amp; settings = parentFrame.GetFrameSettings();
 	RestoreSettings(page_id, settings);
 }
 
@@ -263,7 +263,7 @@ EditorCtrl::EditorCtrl(CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent,
 	FoldingInvalidate();
 }
 
-void EditorCtrl::RestoreSettings(unsigned int page_id, eSettings&amp; settings, unsigned int subid) {
+void EditorCtrl::RestoreSettings(unsigned int page_id, eFrameSettings&amp; settings, unsigned int subid) {
 	wxString mirrorPath;
 	doc_id di;
 	int newpos;
@@ -274,7 +274,7 @@ void EditorCtrl::RestoreSettings(unsigned int page_id, eSettings&amp; settings, unsi
 
 	// Retrieve the page info
 	wxASSERT(0 &lt;= page_id &amp;&amp; page_id &lt; (int)settings.GetPageCount());
-	settings.GetPageSettings(page_id, mirrorPath, di, newpos, topline, syntax, folds, bookmarks, (eSettings::SubPage)subid);
+	settings.GetPageSettings(page_id, mirrorPath, di, newpos, topline, syntax, folds, bookmarks, (SubPage)subid);
 
 	if (eDocumentPath::IsRemotePath(mirrorPath)) {
 		// If the mirror points to a remote file, we have to download it first.
@@ -453,11 +453,11 @@ EditorCtrl::~EditorCtrl() {
 	ClearRemoteInfo();
 }
 
-void EditorCtrl::SaveSettings(unsigned int i, eSettings&amp; settings) {
+void EditorCtrl::SaveSettings(unsigned int i, eFrameSettings&amp; settings) {
 	SaveSettings(i, settings, 0); 
 }
 
-void EditorCtrl::SaveSettings(unsigned int i, eSettings&amp; settings, unsigned int subid) {
+void EditorCtrl::SaveSettings(unsigned int i, eFrameSettings&amp; settings, unsigned int subid) {
 	const wxString&amp; path = GetPath();
 	const doc_id di = GetDocID();
 	const int pos = GetPos();
@@ -466,7 +466,7 @@ void EditorCtrl::SaveSettings(unsigned int i, eSettings&amp; settings, unsigned int
 	const vector&lt;unsigned int&gt; folds = GetFoldedLines();
 	const vector&lt;cxBookmark&gt;&amp; bookmarks = GetBookmarks();
 
-	settings.SetPageSettings(i, path, di, pos, topline, syntax, folds, bookmarks, (eSettings::SubPage)subid);
+	settings.SetPageSettings(i, path, di, pos, topline, syntax, folds, bookmarks, (SubPage)subid);
 	//wxLogDebug(wxT(&quot;  %d (%d,%d,%d) pos:%d topline:%d&quot;), i, di.type, di.document_id, di.version_id, pos, topline);
 }
 
@@ -2933,7 +2933,7 @@ bool EditorCtrl::SetDocument(const doc_id&amp; di, const wxString&amp; path, const Remot
 
 	// Notify that we have changed document
 	const doc_id docId = di; // AdamV: Does this exist just to be on the stack in bug reports?
-	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), this, GetId());
+	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), this, m_parentFrame.GetId());
 
 	return true;
 }</diff>
      <filename>src/EditorCtrl.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -51,6 +51,7 @@ class PreviewDlg;
 class cxRemoteAction;
 class MultilineDataObject;
 class TextTip;
+class eFrameSettings;
 
 struct thTheme;
 class tmAction;
@@ -68,7 +69,7 @@ class EditorCtrl : public KeyHookable&lt;wxControl&gt;,
 public:
 	EditorCtrl(const doc_id di, const wxString&amp; mirrorPath, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame, const wxPoint&amp; pos = wxPoint(-100,-100), const wxSize&amp; size = wxDefaultSize);
 
-	EditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame, const wxPoint&amp; pos = wxPoint(-100,-100), const wxSize&amp; size = wxDefaultSize);
+	EditorCtrl(const int page_id, CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame);
 
 	EditorCtrl(CatalystWrapper&amp; cw, wxBitmap&amp; bitmap, wxWindow* parent, EditorFrame&amp; parentFrame, const wxPoint&amp; pos = wxPoint(-100,-100), const wxSize&amp; size = wxDefaultSize);
 
@@ -166,7 +167,7 @@ public:
 	// TabPage interface
 	virtual EditorCtrl* GetActiveEditor();
 	virtual const char** RecommendedIcon() const;
-	virtual void SaveSettings(unsigned int i, eSettings&amp; settings);
+	virtual void SaveSettings(unsigned int i, eFrameSettings&amp; settings);
 
 	// Bundle Editing
 	bool IsBundleItem() const {return m_remotePath.StartsWith(wxT(&quot;bundle://&quot;));};
@@ -237,8 +238,8 @@ public:
 	void ClearSearchRange(bool reset=false);
 
 	// Settings
-	void SaveSettings(unsigned int i, eSettings&amp; settings, unsigned int id);
-	void RestoreSettings(unsigned int i, eSettings&amp; settings, unsigned int id=0);
+	void SaveSettings(unsigned int i, eFrameSettings&amp; settings, unsigned int id);
+	void RestoreSettings(unsigned int i, eFrameSettings&amp; settings, unsigned int id=0);
 
 	// Needed by IEditorSearch interface
 	wxEvtHandler* GetEventHandlerI() const {return GetEventHandler();};</diff>
      <filename>src/EditorCtrl.h</filename>
    </modified>
    <modified>
      <diff>@@ -80,6 +80,8 @@ enum {
 
 // Menu id's
 enum {
+	MENU_NEWWINDOW,
+	MENU_CLOSEWINDOW,
 	MENU_DIFF,
 	MENU_OPENPROJECT,
 	MENU_OPENREMOTE,
@@ -184,7 +186,6 @@ enum {
 	MENU_BOOKMARK_CLEAR
 };
 
-
 wxString EditorFrame::DefaultFileFilters = wxT(&quot;All files (*.*)|*.*|Text files (*.txt)|*.txt|&quot;) \
 						wxT(&quot;Batch Files (*.bat)|*.bat|INI Files (*.ini)|*.ini|&quot;) \
 						wxT(&quot;C/C++ Files (*.c, *.cpp, *.cxx)|*.c;*.cpp;*.cxx|&quot;) \
@@ -193,10 +194,14 @@ wxString EditorFrame::DefaultFileFilters = wxT(&quot;All files (*.*)|*.*|Text files (
 						wxT(&quot;Perl Files (*.pl, *.pm, *.pod)|*.pl;*.pm;*.pod|&quot;) \
 						wxT(&quot;Python Files (*.py, *.pyw)|*.py;*.pyw&quot;);
 
+// This sets RTTI info but without the dynamic part
+wxIMPLEMENT_CLASS_COMMON1(EditorFrame, wxFrame, NULL)
+
 BEGIN_EVENT_TABLE(EditorFrame, wxFrame)
 	EVT_SIZE(EditorFrame::OnSize)
 	EVT_MENU_OPEN(EditorFrame::OnOpeningMenu)
 	EVT_MENU(wxID_NEW, EditorFrame::OnMenuNew)
+	EVT_MENU(MENU_NEWWINDOW, EditorFrame::OnMenuNewWindow)
 	EVT_MENU(wxID_OPEN, EditorFrame::OnMenuOpen)
 	EVT_MENU(MENU_DIFF, EditorFrame::OnMenuCompareFiles)
 	EVT_MENU(MENU_OPENPROJECT, EditorFrame::OnMenuOpenProject)
@@ -209,6 +214,7 @@ BEGIN_EVENT_TABLE(EditorFrame, wxFrame)
 	//EVT_MENU(wxID_PREVIEW, EditorFrame::OnMenuPrintPreview)
 	EVT_MENU(wxID_PRINT, EditorFrame::OnMenuPrint)
 	EVT_MENU(MENU_CLOSE, EditorFrame::OnMenuClose)
+	EVT_MENU(MENU_CLOSEWINDOW, EditorFrame::OnMenuCloseWindow)
 	EVT_MENU(wxID_EXIT, EditorFrame::OnMenuExit)
 	EVT_MENU(wxID_UNDO, EditorFrame::OnMenuUndo)
 	EVT_MENU(wxID_REDO, EditorFrame::OnMenuRedo)
@@ -328,10 +334,11 @@ BEGIN_EVENT_TABLE(EditorFrame, wxFrame)
 	//EVT_MENU(MENU_HL_USERS, EditorFrame::OnMenuHighlightUsers)
 END_EVENT_TABLE()
 
-EditorFrame::EditorFrame(CatalystWrapper cat, int id,  const wxString&amp; title, const wxRect&amp; rect, TmSyntaxHandler&amp; syntax_handler):
+EditorFrame::EditorFrame(CatalystWrapper cat, unsigned int frameId,  const wxString&amp; title, const wxRect&amp; rect, TmSyntaxHandler&amp; syntax_handler):
 	m_catalyst(cat),
 	dispatcher(cat.GetDispatcher()),
-	m_settings(eGetSettings()),
+	m_generalSettings(eGetSettings()),
+	m_settings(m_generalSettings.GetFrameSettings(frameId)),
 	m_syntax_handler(syntax_handler),
 
 	m_sizeChanged(false), m_needStateSave(true), m_keyDiags(false), m_inAskReload(false),
@@ -341,7 +348,7 @@ EditorFrame::EditorFrame(CatalystWrapper cat, int id,  const wxString&amp; title, co
 	bitmap(1,1)
 	//,m_incommingBmp(incomming_xpm), m_incommingFullBmp(incomming_full_xpm)
 {
-	Create(NULL, id, title, rect.GetPosition(), rect.GetSize(), wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE|wxWANTS_CHARS, wxT(&quot;eMainFrame&quot;));
+	Create(NULL, wxID_ANY, title, rect.GetPosition(), rect.GetSize(), wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE|wxWANTS_CHARS, wxT(&quot;eMainFrame&quot;));
 
 	m_remoteThread = new RemoteThread();
 
@@ -388,7 +395,7 @@ EditorFrame::EditorFrame(CatalystWrapper cat, int id,  const wxString&amp; title, co
 		box-&gt;Add(m_tabBar, 1, wxEXPAND);
 
 		// Create and add the searchpanel
-		m_searchPanel = new SearchPanel(*this, panel, -1, wxDefaultPosition, wxSize(10,25));
+		m_searchPanel = new SearchPanel(*this, panel, wxID_ANY, wxDefaultPosition, wxSize(10,25));
 		box-&gt;Add(m_searchPanel, 0, wxEXPAND);
 		box-&gt;Show(m_searchPanel, false);
 
@@ -401,17 +408,13 @@ EditorFrame::EditorFrame(CatalystWrapper cat, int id,  const wxString&amp; title, co
 		m_frameManager.AddPane(panel, wxAuiPaneInfo().Name(wxT(&quot;Center&quot;)).CenterPane().PaneBorder(false));
 
 		// Add the Document History Pane
-		documentHistory = new DocHistory(m_catalyst, id, this, 1); 
+		documentHistory = new DocHistory(m_catalyst, GetId(), this, wxID_ANY); 
 		m_frameManager.AddPane(documentHistory, wxAuiPaneInfo().Name(wxT(&quot;History&quot;)).Hide().Right().Caption(_(&quot;History&quot;)).BestSize(wxSize(150,200)));
 
 		// Add the Undo History Pane
-		undoHistory = new UndoHistory(m_catalyst, this, id, this, 1);
+		undoHistory = new UndoHistory(m_catalyst, this, GetId(), this, wxID_ANY);
 		m_frameManager.AddPane(undoHistory, wxAuiPaneInfo().Name(wxT(&quot;Undo&quot;)).Hide().Right().Caption(_(&quot;Undo&quot;)).BestSize(wxSize(150,50)));
 
-		//incommingPane = new Incomming(m_catalyst, this, 1); // Add the Incomming Pane
-		//incommingPane-&gt;MakeLastItemVisible();
-		//m_frameManager.AddPane(incommingPane, wxAuiPaneInfo().Name(wxT(&quot;Incoming&quot;)).Hide().Top().Caption(_(&quot;Incoming&quot;)).BestSize(wxSize(150,100)));
-
 		m_outputPane = new HtmlOutputPane(this, *this);
 		m_frameManager.AddPane(m_outputPane, wxAuiPaneInfo().Name(wxT(&quot;Output&quot;)).Hide().Bottom().Caption(_(&quot;Output&quot;)).BestSize(wxSize(150,100)));
 
@@ -505,10 +508,10 @@ EditorFrame::~EditorFrame() {
 
 // Loads settings that end up as member variables
 void EditorFrame::InitMemberSettings() {
-	if (!m_settings.GetSettingInt(wxT(&quot;wrapmode&quot;), (int&amp;)m_wrapMode)) {
+	if (!m_generalSettings.GetSettingInt(wxT(&quot;wrapmode&quot;), (int&amp;)m_wrapMode)) {
 		// fallback to old settings format
 		bool wordwrap = cxWRAP_NORMAL;
-		if (m_settings.GetSettingBool(wxT(&quot;wordwrap&quot;), wordwrap)) {
+		if (m_generalSettings.GetSettingBool(wxT(&quot;wordwrap&quot;), wordwrap)) {
 			m_wrapMode = wordwrap ? cxWRAP_NORMAL : cxWRAP_NONE;
 		}
 	}
@@ -521,16 +524,16 @@ void EditorFrame::InitMemberSettings() {
 	regKey.SetValue(wxT(&quot;ww&quot;), ww);
 #endif // __WXMSW__
 
-	if (!m_settings.GetSettingBool(wxT(&quot;showgutter&quot;), m_showGutter)) m_showGutter = true;
-	if (!m_settings.GetSettingBool(wxT(&quot;hl_users&quot;), m_userHighlight)) m_userHighlight = true;
-	if (!m_settings.GetSettingBool(wxT(&quot;softtabs&quot;), m_softTabs)) m_softTabs = false;
-	if (!m_settings.GetSettingInt(wxT(&quot;tabwidth&quot;), m_tabWidth)) m_tabWidth = 4;
-	if (!m_settings.GetSettingBool(wxT(&quot;showindent&quot;), m_showIndent)) m_showIndent = false;
+	if (!m_generalSettings.GetSettingBool(wxT(&quot;showgutter&quot;), m_showGutter)) m_showGutter = true;
+	if (!m_generalSettings.GetSettingBool(wxT(&quot;hl_users&quot;), m_userHighlight)) m_userHighlight = true;
+	if (!m_generalSettings.GetSettingBool(wxT(&quot;softtabs&quot;), m_softTabs)) m_softTabs = false;
+	if (!m_generalSettings.GetSettingInt(wxT(&quot;tabwidth&quot;), m_tabWidth)) m_tabWidth = 4;
+	if (!m_generalSettings.GetSettingBool(wxT(&quot;showindent&quot;), m_showIndent)) m_showIndent = false;
 }
 
 void EditorFrame::InitStatusbar() {
 	bool showStatusbar = true;
-	m_settings.GetSettingBool(wxT(&quot;statusbar&quot;), showStatusbar);
+	m_generalSettings.GetSettingBool(wxT(&quot;statusbar&quot;), showStatusbar);
 	if (showStatusbar) CreateAndSetStatusbar();
 }
 
@@ -569,6 +572,7 @@ void EditorFrame::InitMenus() {
 	fileMenu-&gt;Append(wxID_NEW, _(&quot;&amp;New\tCtrl+N&quot;), _(&quot;New File&quot;));
 	fileMenu-&gt;Append(wxID_OPEN, _(&quot;&amp;Open...\tCtrl+O&quot;), _(&quot;Open File&quot;));
 	fileMenu-&gt;Append(MENU_DIFF, _(&quot;&amp;Compare...&quot;), _(&quot;Compare...&quot;));
+	fileMenu-&gt;Append(MENU_NEWWINDOW, _(&quot;New Window&quot;), _(&quot;Open New Window&quot;));
 	fileMenu-&gt;AppendSeparator();
 	fileMenu-&gt;Append(wxID_SAVE, _(&quot;&amp;Save\tCtrl+S&quot;), _(&quot;Save File&quot;));
 	fileMenu-&gt;Append(wxID_SAVEAS, _(&quot;Save &amp;As...\tCtrl-Shift-S&quot;), _(&quot;Save File as&quot;));
@@ -594,6 +598,7 @@ void EditorFrame::InitMenus() {
 	fileMenu-&gt;Append(MENU_CLOSE, _(&quot;&amp;Close Tab\tCtrl+W&quot;), _(&quot;Close Tab&quot;));
 	fileMenu-&gt;Append(MENU_TABS_CLOSE_ALL, _(&quot;Close all &amp;Tabs&quot;), _(&quot;Close all Tabs&quot;));
 	fileMenu-&gt;Append(MENU_TABS_CLOSE_OTHER, _(&quot;Clos&amp;e other Tabs\tCtrl+Alt+W&quot;), _(&quot;Close other Tabs&quot;));
+	fileMenu-&gt;Append(MENU_CLOSEWINDOW, _(&quot;Close &amp;Window&quot;), _(&quot;Close Window&quot;));
 	fileMenu-&gt;Append(wxID_EXIT, _(&quot;E&amp;xit&quot;), _(&quot;Exit&quot;));
 	menuBar-&gt;Append(fileMenu, _(&quot;&amp;File&quot;));
 
@@ -792,9 +797,9 @@ void EditorFrame::RestoreState() {
 		unsigned int sp = isDiff ? 1 : 0;
 		const unsigned int sp_end = isDiff ? 3 : 1; // diffs have both left and rightd
 		for (; sp &lt; sp_end; ++sp) {
-			mirrorPath = m_settings.GetPagePath(i, (eSettings::SubPage)sp);
+			mirrorPath = m_settings.GetPagePath(i, (SubPage)sp);
 			if (mirrorPath.empty()) continue;
-			const doc_id mirrorDoc = m_settings.GetPageDoc(i, (eSettings::SubPage)sp);
+			const doc_id mirrorDoc = m_settings.GetPageDoc(i, (SubPage)sp);
 			
 			cxLOCK_READ(m_catalyst)
 				isMirrored = catalyst.VerifyMirror(mirrorPath, mirrorDoc);
@@ -1314,7 +1319,7 @@ void EditorFrame::AddTab(wxWindow* page) {
 	Thaw();
 
 	// Notify that we are editing a new document
-	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), editorCtrl, editorCtrl-&gt;GetId());
+	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), editorCtrl, GetId());
 	UpdateTabMenu();
 }
 
@@ -1655,7 +1660,7 @@ void EditorFrame::ShowProjectPane(const wxString&amp; project) {
 	if (!project.empty()) {
 		m_settings.SetSettingBool(wxT(&quot;showproject&quot;), true);
 		m_settings.SetSettingString(wxT(&quot;project&quot;), project);
-		m_settings.AddRecentProject(project);
+		m_generalSettings.AddRecentProject(project);
 		UpdateRecentFiles();
 	}
 
@@ -1876,7 +1881,7 @@ const RemoteProfile* EditorFrame::GetRemoteProfile(const wxString&amp; url, bool wit
 	wxASSERT(eDocumentPath::IsRemotePath(url));
 
 	// Get (or create) matching profile
-	return m_settings.GetRemoteProfileFromUrl(url, withDir);
+	return m_generalSettings.GetRemoteProfileFromUrl(url, withDir);
 }
 
 bool EditorFrame::AskRemoteLogin(const RemoteProfile* rp) {
@@ -1885,7 +1890,7 @@ bool EditorFrame::AskRemoteLogin(const RemoteProfile* rp) {
 		return false;
 
 	// this also updates rp with the new login
-	m_settings.SetRemoteProfileLogin(rp, dlg.GetUsername(), dlg.GetPassword(), dlg.GetSaveProfile());
+	m_generalSettings.SetRemoteProfileLogin(rp, dlg.GetUsername(), dlg.GetPassword(), dlg.GetSaveProfile());
 
 	return true;
 }
@@ -1985,7 +1990,7 @@ bool EditorFrame::DoOpenFile(const wxString&amp; filepath, wxFontEncoding enc, const
 	}
 
 	// Add to recent files list
-	m_settings.AddRecentFile(filepath);
+	m_generalSettings.AddRecentFile(filepath);
 	UpdateRecentFiles();
 
 	// Create and draw the new page
@@ -2329,6 +2334,10 @@ void EditorFrame::OnMenuNew(wxCommandEvent&amp; WXUNUSED(event)) {
 	AddTab();
 }
 
+void EditorFrame::OnMenuNewWindow(wxCommandEvent&amp; WXUNUSED(event)) {
+	((eApp*)wxTheApp)-&gt;NewFrame();
+}
+
 void EditorFrame::OnNotebookDClick(wxAuiNotebookEvent&amp; WXUNUSED(event)) {
 	AddTab();
 }
@@ -2425,7 +2434,7 @@ void EditorFrame::OnMenuOpen(wxCommandEvent&amp; event) {
 }
 
 void EditorFrame::OnMenuCompareFiles(wxCommandEvent&amp; WXUNUSED(event)) {
-	CompareDlg dlg(this, m_settings);
+	CompareDlg dlg(this, m_generalSettings);
 	if (dlg.ShowModal() != wxID_OK) return;
 
 	const wxString leftPath = dlg.GetLeftPath();
@@ -2466,14 +2475,14 @@ void EditorFrame::OnMenuOpenProject(wxCommandEvent&amp; WXUNUSED(event)) {
 }
 
 void EditorFrame::OnMenuOpenRemote(wxCommandEvent&amp; WXUNUSED(event)) {
-	RemoteProfileDlg dlg(this, this-&gt;m_settings);
+	RemoteProfileDlg dlg(this, this-&gt;m_generalSettings);
 	if (dlg.ShowModal() != wxID_OPEN) return;
 
 	const int profile_id = dlg.GetCurrentProfile();
 	if (profile_id == -1) return;
 
 	// Get the profile from db
-	const RemoteProfile* rp = m_settings.GetRemoteProfile(profile_id);
+	const RemoteProfile* rp = m_generalSettings.GetRemoteProfile(profile_id);
 	if (rp) OpenRemoteProject(rp);
 }
 
@@ -2507,7 +2516,7 @@ void EditorFrame::OnMenuSaveAs(wxCommandEvent&amp; WXUNUSED(event)) {
 	// Add to recent files list
 	const wxString path = editorCtrl-&gt;GetPath();
 	if (!path.empty()) {
-		m_settings.AddRecentFile(path);
+		m_generalSettings.AddRecentFile(path);
 		UpdateRecentFiles();
 	}
 }
@@ -2575,10 +2584,14 @@ void EditorFrame::OnMenuClose(wxCommandEvent&amp; WXUNUSED(event)) {
 	CloseTab(tab_id);
 }
 
-void EditorFrame::OnMenuExit(wxCommandEvent&amp; WXUNUSED(event)) {
+void EditorFrame::OnMenuCloseWindow(wxCommandEvent&amp; WXUNUSED(event)) {
 	Close();
 }
 
+void EditorFrame::OnMenuExit(wxCommandEvent&amp; WXUNUSED(event)) {
+	((eApp*)wxTheApp)-&gt;CloseAllFrames();
+}
+
 void EditorFrame::OnMenuUndo(wxCommandEvent&amp; WXUNUSED(event)) {
 	editorCtrl-&gt;DoUndo();
 }
@@ -2733,7 +2746,7 @@ void EditorFrame::OnMenuSpacesToTabs(wxCommandEvent&amp; WXUNUSED(event)) {
 }
 
 void EditorFrame::OnMenuSettings(wxCommandEvent&amp; WXUNUSED(event)) {
-	SettingsDlg dlg(this, m_catalyst, m_settings);
+	SettingsDlg dlg(this, m_catalyst, m_generalSettings);
 	dlg.ShowModal();
 }
 
@@ -2896,8 +2909,8 @@ void EditorFrame::UpdateRecentFiles() {
 
 	m_recentFiles.clear();
 	m_recentProjects.clear();
-	m_settings.GetRecentFiles(m_recentFiles);
-	m_settings.GetRecentProjects(m_recentProjects);
+	m_generalSettings.GetRecentFiles(m_recentFiles);
+	m_generalSettings.GetRecentProjects(m_recentProjects);
 
 	Freeze();
 
@@ -3059,7 +3072,7 @@ void EditorFrame::OnMenuCommit(wxCommandEvent&amp; WXUNUSED(event)) {
 	cxENDLOCK
 
 	// Notify that we are editing a new document
-	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), editorCtrl, editorCtrl-&gt;GetId());
+	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), editorCtrl, GetId());
 }
 /*
 void EditorFrame::OnMenuRevTooltip(wxCommandEvent&amp; WXUNUSED(event)) {
@@ -3403,7 +3416,7 @@ void EditorFrame::OnNotebook(wxAuiNotebookEvent&amp; event) {
 	UpdateWindowTitle();
 
 	// Notify that we are editing a new document
-	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), editorCtrl, editorCtrl-&gt;GetId());
+	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), editorCtrl, GetId());
 }
 
 void EditorFrame::UpdateNotebook() {
@@ -3414,7 +3427,7 @@ void EditorFrame::UpdateNotebook() {
 	UpdateWindowTitle();
 
 	// Notify that we are editing a new document
-	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), editorCtrl, editorCtrl-&gt;GetId());
+	dispatcher.Notify(wxT(&quot;WIN_CHANGEDOC&quot;), editorCtrl, GetId());
 }
 
 void EditorFrame::OnNotebookDragDone(wxAuiNotebookEvent&amp; WXUNUSED(event)) {
@@ -3427,7 +3440,6 @@ void EditorFrame::OnClose(wxCloseEvent&amp; event) {
 	m_settings.GetSettingBool(wxT(&quot;keepState&quot;), keep_state);
 	if (wxGetKeyState(WXK_SHIFT)) keep_state = true; // override
 
-
 	// Check if we have any unsaved documents
 	// and ask the user if he wants to save them
 	if (AskToSaveMulti() == false) {
@@ -3435,10 +3447,6 @@ void EditorFrame::OnClose(wxCloseEvent&amp; event) {
 		return;
 	}
 
-	// Make sure any data copied to the clipboard stays there after
-	// the app has closed
-	wxTheClipboard-&gt;Flush();
-
 #ifdef __WXMSW__
 	// Show nag screen if the trial is about to expire
 	if (!((eApp*)wxTheApp)-&gt;IsRegistered() &amp;&amp; ((eApp*)wxTheApp)-&gt;DaysLeftOfTrial() &lt;= 5) {
@@ -3485,15 +3493,11 @@ void EditorFrame::OnClose(wxCloseEvent&amp; event) {
 	}
 	editorCtrl = NULL; // avoid dangling pointer
 
-	// Commit the documents &amp; settings before closing
+	// Clean up state info
 	if (!keep_state) {
-		m_settings.DeleteAllPageSettings(); // remove old state
 		m_settings.SetSettingBool(wxT(&quot;showproject&quot;), false);
+		m_generalSettings.RemoveFrame(m_settings);
 	}
-	m_settings.Save();
-	cxLOCK_WRITE(m_catalyst)
-		catalyst.Commit();
-	cxENDLOCK
 
 	Destroy();
 }
@@ -3807,6 +3811,9 @@ bool EditorFrame::DeletePage(unsigned int page_id, bool removetab) {
 	// Notify PreviewDlg that the tab is closing (it might be pinned)
 	if (m_previewDlg) m_previewDlg-&gt;PageClosed(ec);
 
+	// Notify that we are closing the page (there might be subscribers with refs)
+	dispatcher.Notify(wxT(&quot;WIN_CLOSEPAGE&quot;), editorCtrl, GetId());
+
 	if (ec == editorCtrl) editorCtrl = NULL; // Make sure we don't accidentally use deleted ctrl
 
 	//eGetSettings().DeletePageSettings(page_id);</diff>
      <filename>src/EditorFrame.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -26,6 +26,7 @@
 #include &quot;Catalyst.h&quot;
 #include &quot;RemoteThread.h&quot;
 #include &quot;key_hook.h&quot;
+#include &quot;eSettings.h&quot;
 
 #include &quot;WrapMode.h&quot;
 
@@ -51,7 +52,6 @@ class ChangeCheckerThread;
 class BundlePane;
 class DocHistory;
 class UndoHistory;
-class eSettings;
 class SearchPanel;
 class TmSyntaxHandler;
 class StatusBar;
@@ -73,7 +73,7 @@ class EditorFrame : public KeyHookable&lt;wxFrame&gt;,
 	public IOpenTextmateURL
 {
 public:
-	EditorFrame(CatalystWrapper cat, int id, const wxString&amp; title, const wxRect&amp; rect, TmSyntaxHandler&amp; syntax_handler);
+	EditorFrame(CatalystWrapper cat, unsigned int frameId, const wxString&amp; title, const wxRect&amp; rect, TmSyntaxHandler&amp; syntax_handler);
 	~EditorFrame();
 
 	void RestoreState();
@@ -139,6 +139,7 @@ public:
 	cxWrapMode GetWrapMode() const {return m_wrapMode;};
 	bool IsGutterShown() const {return m_showGutter;};
 	bool IsIndentShown() const {return m_showIndent;};
+	eFrameSettings&amp; GetFrameSettings() {return m_settings;};
 
 	// Registration
 	void RemoveRegMenus();
@@ -242,6 +243,7 @@ private:
 	void OnOpeningMenu(wxMenuEvent&amp; event);
 
 	void OnMenuNew(wxCommandEvent&amp; event);
+	void OnMenuNewWindow(wxCommandEvent&amp; event);
 	void OnMenuOpen(wxCommandEvent&amp; event);
 	void OnMenuCompareFiles(wxCommandEvent&amp; event);
 	void OnMenuOpenProject(wxCommandEvent&amp; event);
@@ -256,6 +258,7 @@ private:
 	//void OnMenuPrintPreview(wxCommandEvent&amp; event);
 	void OnMenuPrint(wxCommandEvent&amp; event);
 	void OnMenuClose(wxCommandEvent&amp; event);
+	void OnMenuCloseWindow(wxCommandEvent&amp; event);
 	void OnMenuExit(wxCommandEvent&amp; event);
 	void OnMenuUndo(wxCommandEvent&amp; event);
 	void OnMenuRedo(wxCommandEvent&amp; event);
@@ -382,7 +385,8 @@ private:
 	// Member variables
 	CatalystWrapper m_catalyst;
 	Dispatcher&amp; dispatcher;
-	eSettings&amp; m_settings;
+	eSettings&amp; m_generalSettings;
+	eFrameSettings m_settings;
 	TmSyntaxHandler&amp; m_syntax_handler;
 
 	wxImageList imageList;
@@ -455,6 +459,8 @@ private:
 	wxPageSetupDialogData m_printData;
 
 	wxBitmap bitmap; // shared by EditorCtrl's
+
+	DECLARE_DYNAMIC_CLASS_NO_COPY(EditorFrame)
 };
 
 #endif // __EDITORFRAME_H__</diff>
      <filename>src/EditorFrame.h</filename>
    </modified>
    <modified>
      <diff>@@ -3,13 +3,13 @@
 
 // Pre-definitions
 class EditorCtrl;
-class eSettings;
+class eFrameSettings;
 
 class ITabPage {
 public:
 	virtual EditorCtrl* GetActiveEditor() = 0;
 	virtual const char** RecommendedIcon() const = 0;
-	virtual void SaveSettings(unsigned int i, eSettings&amp; settings) = 0;
+	virtual void SaveSettings(unsigned int i, eFrameSettings&amp; settings) = 0;
 };
 
 #endif // __ITABPAGE_H__</diff>
      <filename>src/ITabPage.h</filename>
    </modified>
    <modified>
      <diff>@@ -183,7 +183,7 @@ PreviewDlg::~PreviewDlg() {
 	if (m_re_href) free(m_re_href);
 }
 
-void PreviewDlg::LoadSettings(const eSettings&amp; settings) {
+void PreviewDlg::LoadSettings(const eFrameSettings&amp; settings) {
 	// Get saved position
 	bool showOptions = false;
 	bool doPipe = false;
@@ -208,7 +208,7 @@ void PreviewDlg::LoadSettings(const eSettings&amp; settings) {
 	}
 }
 
-void PreviewDlg::SaveSettings(eSettings&amp; settings) const {
+void PreviewDlg::SaveSettings(eFrameSettings&amp; settings) const {
 	settings.SetSettingBool(wxT(&quot;prvw_showoptions&quot;), m_showOptions-&gt;IsChecked());
 	settings.SetSettingBool(wxT(&quot;prvw_dopipe&quot;), m_pipeCheck-&gt;IsChecked());
 	settings.SetSettingString(wxT(&quot;prvw_pipecmd&quot;), m_cmdText-&gt;GetValue());</diff>
      <filename>src/PreviewDlg.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -34,7 +34,7 @@ struct real_pcre;                 // This double pre-definition is needed
 typedef struct real_pcre pcre;    // because of the way it is defined in pcre.h
 class EditorFrame;
 class EditorCtrl;
-class eSettings;
+class eFrameSettings;
 class wxProcessEvent;
 class wxWebControl;
 class wxWebEvent;
@@ -44,8 +44,8 @@ public:
 	PreviewDlg(EditorFrame&amp; parent);
 	~PreviewDlg();
 
-	void LoadSettings(const eSettings&amp; settings);
-	void SaveSettings(eSettings&amp; settings) const;
+	void LoadSettings(const eFrameSettings&amp; settings);
+	void SaveSettings(eFrameSettings&amp; settings) const;
 	void PageClosed(const EditorCtrl* ec);
 
 	// Utility functions</diff>
      <filename>src/PreviewDlg.h</filename>
    </modified>
    <modified>
      <diff>@@ -41,13 +41,12 @@ END_EVENT_TABLE()
 UndoHistory::UndoHistory(CatalystWrapper&amp; cw, IFrameUndoPane* parentFrame, int win_id, wxWindow* parent, wxWindowID id, const wxPoint&amp; pos, const wxSize&amp; size)
 	: wxControl(parent, id, pos, size, wxNO_BORDER|wxWANTS_CHARS|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE),
 	  m_catalyst(cw), m_doc(cw), m_dispatcher(cw.GetDispatcher()), m_mdc(), m_bitmap(1,1), m_cell(m_mdc, m_doc), 
-	  m_ignoreUpdates(false), m_editorCtrl(NULL), m_parentFrame(parentFrame)
+	  m_ignoreUpdates(false), m_editorCtrl(NULL), m_parentFrame(parentFrame), m_source_win_id(win_id)
 {
 	SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Avoid flicker
 
 	// Initialize variables
 	m_needRedrawing = true; // Make sure the ctrl gets drawn on first idle event
-	m_source_win_id = win_id;
 	m_scrollPos = 0;
 	m_isScrolling = false;
 	m_lineHeight = 18;
@@ -62,6 +61,7 @@ UndoHistory::UndoHistory(CatalystWrapper&amp; cw, IFrameUndoPane* parentFrame, int w
 	m_mdc.SetFont(wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, false));
 
 	// Make sure we recieve notifications of new versions and updates
+	m_dispatcher.SubscribeC(wxT(&quot;WIN_CLOSEPAGE&quot;), (CALL_BACK)OnClosePage, this);
 	m_dispatcher.SubscribeC(wxT(&quot;WIN_CHANGEDOC&quot;), (CALL_BACK)OnChangeDoc, this);
 	m_dispatcher.SubscribeC(wxT(&quot;DOC_DELETED&quot;), (CALL_BACK)OnDocDeleted, this);
 	m_dispatcher.SubscribeC(wxT(&quot;DOC_NEWREVISION&quot;), (CALL_BACK)OnNewRevision, this);
@@ -71,6 +71,7 @@ UndoHistory::UndoHistory(CatalystWrapper&amp; cw, IFrameUndoPane* parentFrame, int w
 }
 
 UndoHistory::~UndoHistory() {
+	m_dispatcher.UnSubscribe(wxT(&quot;WIN_CLOSEPAGE&quot;), (CALL_BACK)OnClosePage, this);
 	m_dispatcher.UnSubscribe(wxT(&quot;WIN_CHANGEDOC&quot;), (CALL_BACK)OnChangeDoc, this);
 	m_dispatcher.UnSubscribe(wxT(&quot;DOC_DELETED&quot;), (CALL_BACK)OnDocDeleted, this);
 	m_dispatcher.UnSubscribe(wxT(&quot;DOC_NEWREVISION&quot;), (CALL_BACK)OnNewRevision, this);
@@ -80,6 +81,7 @@ UndoHistory::~UndoHistory() {
 }
 
 void UndoHistory::Clear() {
+	m_editorCtrl = NULL;
 	m_sourceDoc.Invalidate();
 	m_pTree-&gt;Clear();
 	m_scrollPos = 0;
@@ -428,7 +430,7 @@ void UndoHistory::OnChar(wxKeyEvent&amp; event) {
 			cxENDLOCK
 
 			if (!di.IsOk()) return; // We are in top document (has no parent)
-			m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;di, m_source_win_id);
+			m_editorCtrl-&gt;SetDocument(di);
 		}
 		break;
 
@@ -441,7 +443,7 @@ void UndoHistory::OnChar(wxKeyEvent&amp; event) {
 
 			if (!childlist.empty()) {
 				const doc_id di(DRAFT, m_sourceDoc.document_id, childlist[0]);
-				m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;di, m_source_win_id);
+				m_editorCtrl-&gt;SetDocument(di);
 			}
 		}
 		break;
@@ -457,7 +459,7 @@ void UndoHistory::OnChar(wxKeyEvent&amp; event) {
 			vector&lt;int&gt;::const_iterator idx = find(childlist.begin(), childlist.end(), m_sourceDoc.version_id);
 			if (idx &gt; childlist.begin()) {
 				const doc_id di(DRAFT, m_sourceDoc.document_id, *(idx-1));
-				m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;di, m_source_win_id);
+				m_editorCtrl-&gt;SetDocument(di);
 			}
 		}
 		break;
@@ -473,7 +475,7 @@ void UndoHistory::OnChar(wxKeyEvent&amp; event) {
 			vector&lt;int&gt;::const_iterator idx = find(childlist.begin(), childlist.end(), m_sourceDoc.version_id);
 			if (idx &lt; childlist.end()-1) {
 				const doc_id di(DRAFT, m_sourceDoc.document_id, *(idx+1));
-				m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;di, m_source_win_id);
+				m_editorCtrl-&gt;SetDocument(di);
 			}
 		}
 	}
@@ -506,7 +508,7 @@ void UndoHistory::OnVersionTreeSel(VersionTreeEvent&amp; event) {
 		// a WIN_CHANGEDOC notifer if the documents actually gets
 		// set on a page.
 
-		m_dispatcher.Notify(wxT(&quot;WIN_SETDOCUMENT&quot;), &amp;clicked_doc, m_source_win_id);
+		m_editorCtrl-&gt;SetDocument(clicked_doc);
 
 		// Check if we were double-clicked
 		if (event.GetInt() == 1) {
@@ -576,11 +578,16 @@ void UndoHistory::OnEraseBackground(wxEraseEvent&amp; WXUNUSED(event)) {
 }
 
 // static notification handler
+void UndoHistory::OnClosePage(UndoHistory* self, void* data, int WXUNUSED(filter)) {
+	if (self-&gt;m_editorCtrl == (EditorCtrl*)data) self-&gt;Clear();
+}
+
+// static notification handler
 void UndoHistory::OnChangeDoc(UndoHistory* self, void* data, int filter) {
+	if (filter != self-&gt;m_source_win_id) return;
 	//wxLogTrace(&quot;OnChangeDoc %d %d - %d&quot;, di.document_id, di.revision_id, filter);
 
 	self-&gt;m_editorCtrl = (EditorCtrl*)data;
-	self-&gt;m_source_win_id = filter;
 	const doc_id di = self-&gt;m_editorCtrl-&gt;GetDocID();
 	self-&gt;m_range.Set(0, 0); // reset to no selection (will update in idle)
 	self-&gt;SetDocument(di);
@@ -605,38 +612,46 @@ void UndoHistory::OnDocDeleted(UndoHistory* self, void* data, int WXUNUSED(filte
 
 // static notification handler
 void UndoHistory::OnNewRevision(UndoHistory* self, void* data, int WXUNUSED(filter)) {
-	const doc_id* const di = (doc_id*)data;
-	wxASSERT(di-&gt;IsDraft());
+	if (!self-&gt;m_editorCtrl) return; // may be called before first editor
 
-	self-&gt;SetDocument(*di);
+	const doc_id&amp; di = *(const doc_id*)data;
+	wxASSERT(di.IsDraft());
+	
+	if (di == self-&gt;m_editorCtrl-&gt;GetDocID()) {
+		self-&gt;SetDocument(di);
+	}
+	else if (self-&gt;m_sourceDoc.SameDoc(di)) {
+		// Doc has been changed in another editor, so we just redraw
+		self-&gt;UpdateTree();
+	}
 }
 
 // static notification handler
 void UndoHistory::OnUpdateRevision(UndoHistory* self, void* data, int WXUNUSED(filter)) {
 	if (!self-&gt;m_sourceDoc.IsOk()) return;
-	const doc_id* const di = (doc_id*)data;
-	wxASSERT(di-&gt;IsDraft());
+	const doc_id&amp; di = *(const doc_id*)data;
+	wxASSERT(di.IsDraft());
 
-	if (self-&gt;m_sourceDoc.SameDoc(*di)) {
-		self-&gt;SetDocument(*di);
+	if (di == self-&gt;m_editorCtrl-&gt;GetDocID()) {
+		self-&gt;SetDocument(di);
+	}
+	else if (self-&gt;m_sourceDoc.SameDoc(di)) {
+		// Doc has been changed in another editor, so we just redraw
+		self-&gt;UpdateTree();
 	}
 }
 
 // static notification handler
 void UndoHistory::OnDocUpdated(UndoHistory* self, void* data, int WXUNUSED(filter)) {
 	if (!self-&gt;m_sourceDoc.IsOk()) return;
-
 	const doc_id&amp; di = *(const doc_id*)data;
 
-	bool isSameDoc;
-	cxLOCK_READ(self-&gt;m_catalyst)
-		isSameDoc = catalyst.InSameHistory(di, self-&gt;m_sourceDoc);
-	cxENDLOCK
-
-	if (isSameDoc) {
-		wxClientDC dc(self);
-		self-&gt;m_pTree-&gt;UpdateTree();
-		self-&gt;DrawLayout(dc);
+	if (di == self-&gt;m_editorCtrl-&gt;GetDocID()) {
+		self-&gt;SetDocument(di);
+	}
+	else if (self-&gt;m_sourceDoc.SameDoc(di)) {
+		// Doc has been changed in another editor, so we just redraw
+		self-&gt;UpdateTree();
 	}
 }
 </diff>
      <filename>src/UndoHistory.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -59,6 +59,7 @@ private:
 	DECLARE_EVENT_TABLE();
 
 	// Notifier handlers
+	static void OnClosePage(UndoHistory* self, void* data, int filter);
 	static void OnChangeDoc(UndoHistory* self, void* data, int filter);
 	static void OnDocDeleted(UndoHistory* self, void* data, int filter);
 	static void OnNewRevision(UndoHistory* self, void* data, int filter);
@@ -74,20 +75,20 @@ private:
 
 	wxMemoryDC m_mdc;
 	wxBitmap m_bitmap;
+	DiffLineCell m_cell;
 
 	bool m_ignoreUpdates;
 
 	EditorCtrl* m_editorCtrl;
 	IFrameUndoPane* m_parentFrame;
 
-	DiffLineCell m_cell;
 	VersionTree* m_pTree;
 
 	wxBrush bgBrush;
 	wxPen linePen;
 
 	doc_id m_sourceDoc;
-	int m_source_win_id;
+	const int m_source_win_id;
 	interval m_range;
 	std::vector&lt;cxDiffEntry&gt; m_rangeHistory;
 </diff>
      <filename>src/UndoHistory.h</filename>
    </modified>
    <modified>
      <diff>@@ -28,6 +28,7 @@
 #include &lt;wx/file.h&gt;
 #include &lt;wx/image.h&gt;
 #include &lt;wx/stdpaths.h&gt;
+#include &lt;wx/clipbrd.h&gt;
 
 #include &quot;UpdaterThread.h&quot;
 #include &quot;Dispatcher.h&quot;
@@ -58,7 +59,6 @@ END_EVENT_TABLE()
 
 bool eApp::OnInit() {
 	// Initialize variables
-	frame = NULL;
 	m_pCatalyst = NULL;
 	m_catalyst = NULL;
 	m_pSyntaxHandler = NULL;
@@ -165,7 +165,6 @@ bool eApp::OnInit() {
 
 	// Load Settings
 	m_settings.Load(m_appDataPath);
-	if (m_settings.IsEmpty()) m_pCatalyst-&gt;MoveOldSettings(m_settings);
 
 	// Apply options
 	if (clearState) ClearState();
@@ -180,21 +179,19 @@ bool eApp::OnInit() {
 	m_pListHandler = new PListHandler(GetAppPath(), GetAppDataPath(), clearBundleCache);
 	m_pSyntaxHandler = new TmSyntaxHandler(m_pCatalyst-&gt;GetDispatcher(), *m_pListHandler);
 
-    // Create the main window
-	wxLogDebug(wxT(&quot;Creating main frame&quot;));
-	frame = new EditorFrame( *m_catalyst, -1, wxT(&quot;e&quot;), DetermineFrameSize(), *m_pSyntaxHandler);
-	SetTopWindow(frame);
-
-	// Show the main window, bringing it to the top.
-	frame-&gt;Show(true);
-	frame-&gt;Raise();
-	frame-&gt;Update();
-
-	// Open files from saved state
-	frame-&gt;RestoreState();
+    // Create the main windows
+	wxLogDebug(wxT(&quot;Creating main frames&quot;));
+	const size_t framecount = m_settings.GetFrameCount();
+	if (framecount == 0) NewFrame();
+	else {
+		for (size_t i = 0; i &lt; framecount; ++i) {
+			OpenFrame(i);
+		}
+	}
 
 	// Open files from command-line options
 	if (argc &gt; 1) {
+		EditorFrame* frame = GetTopFrame();
 		for (unsigned int i = 0; i &lt; m_files.Count(); ++i) {
 			const wxString&amp; arg = m_files[i];
 			frame-&gt;Open(arg, mate);
@@ -218,9 +215,7 @@ bool eApp::OnInit() {
 	eDocumentPath::InitCygwinOnce();
 #endif
 
-	wxLogDebug(wxT(&quot;Checking for modified files&quot;));
-	frame-&gt;CheckForModifiedFilesAsync();
-	wxLogDebug(wxT(&quot;Done Checking for modified files&quot;));
+	CheckForModifiedFiles();
 
 	// If the command-line option didn't prevent checking for updates,
 	// read the corresponding setting.
@@ -234,34 +229,107 @@ bool eApp::OnInit() {
     return true;
 }
 
-void eApp::ClearState() {
-	// Pages
-	m_settings.DeleteAllPageSettings();
+EditorFrame* eApp::OpenFrame(size_t frameId) {
+	const wxRect frameSize = DetermineFrameSize();
+	EditorFrame* frame = new EditorFrame( *m_catalyst, frameId, wxT(&quot;e&quot;), frameSize, *m_pSyntaxHandler);
+
+	// Show the main window, bringing it to the top.
+	frame-&gt;Show(true);
+	frame-&gt;Raise();
+	frame-&gt;Update();
+
+	// Open files from saved state
+	frame-&gt;RestoreState();
+
+	return frame;
+}
+
+EditorFrame* eApp::NewFrame() {
+	// We want to copy settings from currently active frame
+	size_t activeId = 0;
+	EditorFrame* frame = GetTopFrame();
+	if (frame) {
+		activeId = m_settings.GetIndexFromFrameSettings(frame-&gt;GetFrameSettings());
+	}
 
-	// Tab layout
-	m_settings.RemoveSetting(wxT(&quot;topwin/tablayout&quot;));
-	m_settings.RemoveSetting(wxT(&quot;topwin/page_id&quot;));
+	// Create settings for new frame and open
+	const size_t frameId = m_settings.AddFrame(activeId);
+	return OpenFrame(frameId);
+}
+
+void eApp::CloseAllFrames() {
+	wxWindowList::const_iterator i;
+    const wxWindowList::const_iterator end = wxTopLevelWindows.end();
+
+	// The app will exit when all frames are closed
+	for ( i = wxTopLevelWindows.begin(); i != end; ++i )
+    {
+        if (!(*i)-&gt;IsKindOf(CLASSINFO(EditorFrame))) continue;
+
+		EditorFrame* win = wx_static_cast(EditorFrame*, *i);
+		if (!win-&gt;Close()) return;
+	}
+}
+
+EditorFrame* eApp::GetTopFrame() {
+	EditorFrame* win = NULL;
+	wxWindowList::const_iterator i;
+    const wxWindowList::const_iterator end = wxTopLevelWindows.end();
+
+    for ( i = wxTopLevelWindows.begin(); i != end; ++i )
+    {
+        if (!(*i)-&gt;IsKindOf(CLASSINFO(EditorFrame))) continue;
+
+		win = wx_static_cast(EditorFrame*, *i);
+		if (win-&gt;IsActive()) return win;
+	}
+
+	// If no frame is active, just return last
+	return win;
+}
+
+void eApp::CheckForModifiedFiles() {
+	wxWindowList::const_iterator i;
+    const wxWindowList::const_iterator end = wxTopLevelWindows.end();
 
+    wxLogDebug(wxT(&quot;Checking for modified files&quot;));
+	for ( i = wxTopLevelWindows.begin(); i != end; ++i )
+    {
+        if (!(*i)-&gt;IsKindOf(CLASSINFO(EditorFrame))) continue;
+
+		EditorFrame* win = wx_static_cast(EditorFrame*, *i);
+		win-&gt;CheckForModifiedFilesAsync();
+	}
+	wxLogDebug(wxT(&quot;Done Checking for modified files&quot;));
+}
+
+void eApp::ClearState() {
+	m_settings.DeleteAllFrameSettings(0);
 	m_settings.Save();
 }
 
 void eApp::ClearLayout() {
+	m_settings.DeleteAllFrameSettings(0);
+	if (m_settings.GetFrameCount() == 0) return;
+
+	eFrameSettings settings = m_settings.GetFrameSettings(0);
+
 	// Window size and position
-	m_settings.RemoveSetting(wxT(&quot;topwin/x&quot;));
-	m_settings.RemoveSetting(wxT(&quot;topwin/y&quot;));
-	m_settings.RemoveSetting(wxT(&quot;topwin/width&quot;));
-	m_settings.RemoveSetting(wxT(&quot;topwin/height&quot;));
-	m_settings.RemoveSetting(wxT(&quot;topwin/ismax&quot;));
+	settings.RemoveSetting(wxT(&quot;topwin/x&quot;));
+	settings.RemoveSetting(wxT(&quot;topwin/y&quot;));
+	settings.RemoveSetting(wxT(&quot;topwin/width&quot;));
+	settings.RemoveSetting(wxT(&quot;topwin/height&quot;));
+	settings.RemoveSetting(wxT(&quot;topwin/ismax&quot;));
 
 	// wxAUI perspective
-	m_settings.RemoveSetting(wxT(&quot;topwin/panes&quot;));
+	settings.RemoveSetting(wxT(&quot;topwin/panes&quot;));
 
 	// pane settings
-	m_settings.RemoveSetting(wxT(&quot;symbol_pane&quot;));
-	m_settings.RemoveSetting(wxT(&quot;showsymbols&quot;));
-	m_settings.RemoveSetting(wxT(&quot;prvw_pane&quot;));
-	m_settings.RemoveSetting(wxT(&quot;showpreview&quot;));
-	m_settings.RemoveSetting(wxT(&quot;showproject&quot;));
+	settings.RemoveSetting(wxT(&quot;symbol_pane&quot;));
+	settings.RemoveSetting(wxT(&quot;showsymbols&quot;));
+	settings.RemoveSetting(wxT(&quot;prvw_pane&quot;));
+	settings.RemoveSetting(wxT(&quot;showpreview&quot;));
+	settings.RemoveSetting(wxT(&quot;showproject&quot;));
 
 	m_settings.Save();
 }
@@ -407,7 +475,8 @@ void eApp::OnIdle(wxIdleEvent&amp; event) {
 	if (!m_openStack.IsEmpty()) {
 		const wxString cmd = m_openStack[0];
 		m_openStack.RemoveAt(0);
-		frame-&gt;Open(cmd);
+
+		GetTopFrame()-&gt;Open(cmd);
 	}
 
 	if (m_pSyntaxHandler) {
@@ -425,6 +494,7 @@ bool eApp::ExecuteCmd(const wxString&amp; cmd) {
 
 bool eApp::ExecuteCmd(const wxString&amp; cmd, wxString&amp; result) {
 	wxASSERT(!cmd.empty());
+	EditorFrame* frame = GetTopFrame();
 	if (!frame) return false; // May not be created yet
 
 	wxString exec_cmd = cmd;
@@ -590,6 +660,15 @@ wxRect eApp::DetermineFrameSize() {
 }
 
 int eApp::OnExit() {
+	// Make sure any data copied to the clipboard stays there after
+	// the app has closed
+	wxTheClipboard-&gt;Flush();
+
+	m_settings.Save();
+	cxLOCK_WRITE((*m_catalyst))
+		catalyst.Commit();
+	cxENDLOCK
+
 	// Release allocated memory
 #ifndef __WXMSW__
 	if (m_server) delete m_server;
@@ -630,7 +709,7 @@ wxString eApp::GetAppTitle() {
 
 void eApp::OnUpdatesAvailable(wxCommandEvent&amp; WXUNUSED(event)) {
 	// Ask user if he wants to download new release
-	const int answer = wxMessageBox(_(&quot;A new release of e is available.\nDo you wish to go the the website to download it now?&quot;), wxT(&quot;Program update!&quot;), wxYES_NO|wxICON_EXCLAMATION, frame);
+	const int answer = wxMessageBox(_(&quot;A new release of e is available.\nDo you wish to go the the website to download it now?&quot;), wxT(&quot;Program update!&quot;), wxYES_NO|wxICON_EXCLAMATION, GetTopFrame());
 	if (answer == wxYES) {
 		// Go to website
 		wxLaunchDefaultBrowser(wxT(&quot;http://www.e-texteditor.com&quot;));</diff>
      <filename>src/eApp.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -54,6 +54,10 @@ public:
 	const wxString&amp; VersionName() const { return m_version_name; }
 	const unsigned int VersionId() const { return m_version_id; }
 
+	// Frames
+	EditorFrame* NewFrame();
+	void CloseAllFrames();
+
 	// Execute internal commands
 	virtual bool ExecuteCmd(const wxString&amp; cmd);
 	virtual bool ExecuteCmd(const wxString&amp; cmd, wxString&amp; result);
@@ -86,8 +90,12 @@ public:
 #endif  //__WXDEBUG__
 
 private:
+	// Frames
+	EditorFrame* OpenFrame(size_t frameId);
+	EditorFrame* GetTopFrame();
+	void CheckForModifiedFiles();
+
 	// Member variables
-	EditorFrame* frame;
 	wxString m_version_name;
 	unsigned int m_version_id;
 </diff>
      <filename>src/eApp.h</filename>
    </modified>
    <modified>
      <diff>@@ -61,6 +61,24 @@ void eSettings::Load(const wxString&amp; appDataPath) {
 			env[key] = envNode.ItemAt(key).AsString();
 		}
 	}
+
+	// If this is an old config file, move frame related settings into it's own section
+	if (!m_jsonRoot.HasMember(wxT(&quot;frames&quot;))) {
+		wxJSONValue&amp; frames = m_jsonRoot[wxT(&quot;frames&quot;)];
+		wxJSONValue&amp; frame = frames[0]; // there should always be at least one frame
+
+		// Move page settings
+		if (m_jsonRoot.HasMember(wxT(&quot;pages&quot;))) {
+			wxJSONValue&amp; pages = m_jsonRoot[wxT(&quot;pages&quot;)];
+			frame[wxT(&quot;pages&quot;)] = pages;
+			m_jsonRoot.Remove(wxT(&quot;pages&quot;));
+		}
+
+		// Copy general settings
+		if (m_jsonRoot.HasMember(wxT(&quot;settings&quot;))) {
+			frame[wxT(&quot;settings&quot;)] = m_jsonRoot[wxT(&quot;settings&quot;)];
+		}
+	}
 }
 
 bool eSettings::Save() {
@@ -93,6 +111,94 @@ bool eSettings::IsEmpty() const {
 	return !m_jsonRoot.IsObject();
 }
 
+unsigned int eSettings::GetFrameCount() const {
+	if (!m_jsonRoot.HasMember(wxT(&quot;frames&quot;))) return 0;
+
+	const wxJSONValue frames = m_jsonRoot.ItemAt(wxT(&quot;frames&quot;));
+	return frames.Size();
+}
+
+eFrameSettings eSettings::GetFrameSettings(unsigned int frameId) {
+	wxASSERT(m_jsonRoot.HasMember(wxT(&quot;frames&quot;)));
+
+	wxJSONValue&amp; frames = m_jsonRoot[wxT(&quot;frames&quot;)];
+	wxASSERT((int)frameId &lt; frames.Size());
+
+	wxJSONValue&amp; frame = frames[frameId];
+	return eFrameSettings(frame);
+}
+
+unsigned int eSettings::AddFrame(unsigned int top) {
+	// Create new frame
+	wxJSONValue&amp; frames = m_jsonRoot[wxT(&quot;frames&quot;)];
+	wxJSONValue&amp; frame = frames.IsArray() ? frames[frames.Size()] : frames[0];
+
+	// Copy settings from active frame
+	if (frames.Size() &gt; 1) {
+		frame[wxT(&quot;settings&quot;)] = frames[top][wxT(&quot;settings&quot;)];
+	}
+
+	return frames.Size()-1;
+}
+
+void eSettings::RemoveFrame(unsigned int frameId) {
+	wxASSERT(m_jsonRoot.HasMember(wxT(&quot;frames&quot;)));
+
+	wxJSONValue frames = m_jsonRoot.ItemAt(wxT(&quot;frames&quot;));
+	wxASSERT((int)frameId &lt; frames.Size());
+
+	// we need to leave at least one frame
+	if (frames.Size() == 1) {
+		// just clear page info
+		wxJSONValue&amp; frame = frames[0];
+		frame.Remove(wxT(&quot;pages&quot;));
+	}
+	else frames.Remove(frameId);
+}
+
+void eSettings::RemoveFrame(const eFrameSettings&amp; fs) {
+	const int frameId = GetIndexFromFrameSettings(fs);
+	if (frameId == -1) return;
+
+	RemoveFrame(frameId);
+}
+
+void eSettings::DeleteAllFrameSettings(int top) {
+	if (!m_jsonRoot.HasMember(wxT(&quot;frames&quot;))) return;
+
+	wxJSONValue&amp; frames = m_jsonRoot[wxT(&quot;frames&quot;)];
+	if (frames.Size() == 0) return;
+
+	// Remove all frames, but keep settings from the active one
+	for (int i = frames.Size()-1; i &gt;= 0; --i) {
+		if (i == top) {
+			// just clear page info
+			wxJSONValue&amp; frame = frames[i];
+			frame.Remove(wxT(&quot;pages&quot;));
+			continue;
+		}
+		frames.Remove(i);
+	}
+
+	// Remove page related settings
+	eFrameSettings frmSettings = GetFrameSettings(0);
+	frmSettings.RemoveSetting(wxT(&quot;topwin/tablayout&quot;));
+	frmSettings.RemoveSetting(wxT(&quot;topwin/page_id&quot;));
+}
+
+int eSettings::GetIndexFromFrameSettings(const eFrameSettings&amp; fs) const {
+	if (!m_jsonRoot.HasMember(wxT(&quot;frames&quot;))) return -1;
+
+	wxJSONValue frames = m_jsonRoot.ItemAt(wxT(&quot;frames&quot;));
+	if (frames.Size() == 0) return -1;
+
+	for (int i = 0; i &lt; frames.Size(); ++i) {
+		if (frames[i].GetRefData() == fs.GetRefData()) return i;
+	}
+
+	return -1; // not found
+}
+
 bool eSettings::GetSettingBool(const wxString&amp; name, bool&amp; value) const {
 	if (!m_jsonRoot.HasMember(wxT(&quot;settings&quot;))) return false;
 
@@ -232,125 +338,6 @@ void eSettings::GetRecents(const wxJSONValue&amp; jarray, wxArrayString&amp; recents) co
 	}
 }
 
-size_t eSettings::GetPageCount() const {
-	if (!m_jsonRoot.HasMember(wxT(&quot;pages&quot;))) return 0;
-
-	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
-	return pages.Size();
-}
-
-void eSettings::SetPageSettings(size_t page_id, const wxString&amp; path, doc_id di, int pos, int topline, const wxString&amp; syntax, const vector&lt;unsigned int&gt;&amp; folds, const vector&lt;cxBookmark&gt;&amp; bookmarks, SubPage sp) {
-	wxJSONValue&amp; pages = m_jsonRoot.Item(wxT(&quot;pages&quot;));
-	if (!pages.IsArray()) pages.SetType(wxJSONTYPE_ARRAY);
-
-	wxASSERT((int)page_id &lt;= pages.Size());
-	wxJSONValue&amp; toppage = ((int)page_id == pages.Size()) ? pages.Append(wxJSONValue(wxJSONTYPE_OBJECT)) : pages[page_id];
-	
-	// With diffs we may have subpages
-	wxJSONValue&amp; page = (sp == SP_MAIN) ? toppage : ((sp == SP_LEFT) ? toppage[wxT(&quot;left&quot;)] : toppage[wxT(&quot;right&quot;)]);
-
-	page.RemoveAll();
-	page[wxT(&quot;path&quot;)] = path;
-	page[wxT(&quot;pos&quot;)] = pos;
-	page[wxT(&quot;topline&quot;)] = topline;
-	page[wxT(&quot;syntax&quot;)] = syntax;
-
-	// doc_id
-	page[wxT(&quot;doc_type&quot;)] = di.type;
-	page[wxT(&quot;doc_doc&quot;)] = di.document_id;
-	page[wxT(&quot;doc_version&quot;)] = di.version_id;
-
-	// Set folds
-	wxJSONValue&amp; foldsArray = page[wxT(&quot;folds&quot;)];
-	if (!foldsArray.IsArray()) foldsArray.SetType(wxJSONTYPE_ARRAY);
-	for (vector&lt;unsigned int&gt;::const_iterator p = folds.begin(); p != folds.end(); ++p) {
-		foldsArray.Append(*p);
-	}
-
-	// Set bookmarks
-	wxJSONValue&amp; bookmarksArray = page[wxT(&quot;bookmarks&quot;)];
-	if (!bookmarksArray.IsArray()) bookmarksArray.SetType(wxJSONTYPE_ARRAY);
-	for (vector&lt;cxBookmark&gt;::const_iterator b = bookmarks.begin(); b != bookmarks.end(); ++b) {
-		bookmarksArray.Append(b-&gt;line_id);
-	}
-}
-
-void eSettings::GetPageSettings(size_t page_id, wxString&amp; path, doc_id&amp; di, int&amp; pos, int&amp; topline, wxString&amp; syntax, vector&lt;unsigned int&gt;&amp; folds, vector&lt;unsigned int&gt;&amp; bookmarks, SubPage sp) const {
-	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
-	wxASSERT((int)page_id &lt; pages.Size());
-	const wxJSONValue toppage = pages.ItemAt(page_id);
-
-	// With diffs we may have subpages
-	const wxJSONValue page = (sp == SP_MAIN) ? toppage : ((sp == SP_LEFT) ? toppage.ItemAt(wxT(&quot;left&quot;)) : toppage.ItemAt(wxT(&quot;right&quot;)));
-
-	path = page.ItemAt(wxT(&quot;path&quot;)).AsString();
-	pos = page.ItemAt(wxT(&quot;pos&quot;)).AsInt();
-	topline = page.ItemAt(wxT(&quot;topline&quot;)).AsInt();
-	syntax = page.ItemAt(wxT(&quot;syntax&quot;)).AsString();
-
-	// doc_id
-	di.type = (doc_type)page.ItemAt(wxT(&quot;doc_type&quot;)).AsInt();
-	di.document_id = page.ItemAt(wxT(&quot;doc_doc&quot;)).AsInt();
-	di.version_id = page.ItemAt(wxT(&quot;doc_version&quot;)).AsInt();
-
-	// Set folds
-	const wxJSONValue foldsArray = page.ItemAt(wxT(&quot;folds&quot;));
-	for (int f = 0; f &lt; foldsArray.Size(); ++f) {
-		folds.push_back(foldsArray.ItemAt(f).AsInt());
-	}
-
-	// Set bookmarks
-	const wxJSONValue bookmarksArray = page.ItemAt(wxT(&quot;bookmarks&quot;));
-	for (int b = 0; b &lt; bookmarksArray.Size(); ++b) {
-		bookmarks.push_back(bookmarksArray.ItemAt(b).AsInt());
-	}
-}
-
-bool eSettings::IsPageDiff(size_t page_id) const {
-	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
-	wxASSERT((int)page_id &lt; pages.Size());
-	const wxJSONValue page = pages.ItemAt(page_id);
-	return page.HasMember(wxT(&quot;left&quot;));
-}
-
-wxString eSettings::GetPagePath(size_t page_id, SubPage sp) const {
-	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
-	wxASSERT((int)page_id &lt; pages.Size());
-	const wxJSONValue toppage = pages.ItemAt(page_id);
-
-	// With diffs we may have subpages
-	const wxJSONValue page = (sp == SP_MAIN) ? toppage : ((sp == SP_LEFT) ? toppage.ItemAt(wxT(&quot;left&quot;)) : toppage.ItemAt(wxT(&quot;right&quot;)));
-
-	return page.ItemAt(wxT(&quot;path&quot;)).AsString();
-}
-
-doc_id eSettings::GetPageDoc(size_t page_id, SubPage sp) const {
-	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
-	wxASSERT((int)page_id &lt; pages.Size());
-	const wxJSONValue toppage = pages.ItemAt(page_id);
-
-	// With diffs we may have subpages
-	const wxJSONValue page = (sp == SP_MAIN) ? toppage : ((sp == SP_LEFT) ? toppage.ItemAt(wxT(&quot;left&quot;)) : toppage.ItemAt(wxT(&quot;right&quot;)));
-
-	doc_id di;
-	di.type = (doc_type)page.ItemAt(wxT(&quot;doc_type&quot;)).AsInt();
-	di.document_id = page.ItemAt(wxT(&quot;doc_doc&quot;)).AsInt();
-	di.version_id = page.ItemAt(wxT(&quot;doc_version&quot;)).AsInt();
-
-	return di;
-}
-
-void eSettings::DeleteAllPageSettings() {
-	m_jsonRoot.Remove(wxT(&quot;pages&quot;));
-}
-
-void eSettings::DeletePageSettings(size_t page_id) {
-	wxJSONValue&amp; pages = m_jsonRoot.Item(wxT(&quot;pages&quot;));
-	wxASSERT((int)page_id &lt; pages.Size());
-
-	pages.Remove(page_id);
-}
-
 RemoteProfile* eSettings::DoGetRemoteProfile(size_t profile_id)  {
 	// Check if profile is already in cache
 	for (auto_vector&lt;RemoteProfile&gt;::iterator p = m_tempRemotes.begin(); p != m_tempRemotes.end(); ++p) {
@@ -688,3 +675,189 @@ bool eSettings::AddFilterCommand(const wxString&amp; command) {
 
 	return true;
 }
+
+// ---- eFrameSettings ---------------------------------------------------------
+
+eFrameSettings::eFrameSettings(wxJSONValue&amp; framesettings) : m_jsonRoot(framesettings) {
+}
+
+void eFrameSettings::RemoveSetting(const wxString&amp; name) {
+	wxJSONValue&amp; settings = m_jsonRoot[wxT(&quot;settings&quot;)];
+	settings.Remove(name);
+}
+
+bool eFrameSettings::GetSettingBool(const wxString&amp; name, bool&amp; value) const {
+	if (!m_jsonRoot.HasMember(wxT(&quot;settings&quot;))) return false;
+
+	const wxJSONValue settings = m_jsonRoot.ItemAt(wxT(&quot;settings&quot;));
+	if (!settings.HasMember(name)) return false;
+
+	// old bool values may have been stored as ints
+	const wxJSONValue val = settings.ItemAt(name);
+	if (val.IsInt()) return (val.AsInt() &gt; 0);
+
+	if (!val.IsBool()) return false;
+
+	value = val.AsBool();
+	return true;
+}
+
+void eFrameSettings::SetSettingBool(const wxString&amp; name, bool value) {
+	wxJSONValue&amp; settings = m_jsonRoot[wxT(&quot;settings&quot;)];
+	settings[name] = value;
+}
+
+bool eFrameSettings::GetSettingInt(const wxString&amp; name, int&amp; value) const {
+	if (!m_jsonRoot.HasMember(wxT(&quot;settings&quot;))) return false;
+
+	const wxJSONValue settings = m_jsonRoot.ItemAt(wxT(&quot;settings&quot;));
+	if (!settings.HasMember(name)) return false;
+
+	const wxJSONValue val = settings.ItemAt(name);
+	if (!val.IsInt()) return false;
+
+	value = val.AsInt();
+	return true;
+}
+
+void eFrameSettings::SetSettingInt(const wxString&amp; name, int value) {
+	wxJSONValue&amp; settings = m_jsonRoot[wxT(&quot;settings&quot;)];
+	settings[name] = value;
+}
+
+bool eFrameSettings::GetSettingString(const wxString&amp; name, wxString&amp; value) const {
+	if (!m_jsonRoot.HasMember(wxT(&quot;settings&quot;))) return false;
+
+	const wxJSONValue settings = m_jsonRoot.ItemAt(wxT(&quot;settings&quot;));
+	if (!settings.HasMember(name)) return false;
+
+	const wxJSONValue val = settings.ItemAt(name);
+	if (!val.IsString()) return false;
+
+	value = val.AsString();
+	return true;
+}
+
+void eFrameSettings::SetSettingString(const wxString&amp; name, const wxString&amp; value) {
+	wxJSONValue&amp; settings = m_jsonRoot[wxT(&quot;settings&quot;)];
+	settings[name] = value;
+}
+
+size_t eFrameSettings::GetPageCount() const {
+	if (!m_jsonRoot.HasMember(wxT(&quot;pages&quot;))) return 0;
+
+	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
+	return pages.Size();
+}
+
+void eFrameSettings::SetPageSettings(size_t page_id, const wxString&amp; path, doc_id di, int pos, int topline, const wxString&amp; syntax, const vector&lt;unsigned int&gt;&amp; folds, const vector&lt;cxBookmark&gt;&amp; bookmarks, SubPage sp) {
+	wxJSONValue&amp; pages = m_jsonRoot.Item(wxT(&quot;pages&quot;));
+	if (!pages.IsArray()) pages.SetType(wxJSONTYPE_ARRAY);
+
+	wxASSERT((int)page_id &lt;= pages.Size());
+	wxJSONValue&amp; toppage = ((int)page_id == pages.Size()) ? pages.Append(wxJSONValue(wxJSONTYPE_OBJECT)) : pages[page_id];
+	
+	// With diffs we may have subpages
+	wxJSONValue&amp; page = (sp == SP_MAIN) ? toppage : ((sp == SP_LEFT) ? toppage[wxT(&quot;left&quot;)] : toppage[wxT(&quot;right&quot;)]);
+
+	page.RemoveAll();
+	page[wxT(&quot;path&quot;)] = path;
+	page[wxT(&quot;pos&quot;)] = pos;
+	page[wxT(&quot;topline&quot;)] = topline;
+	page[wxT(&quot;syntax&quot;)] = syntax;
+
+	// doc_id
+	page[wxT(&quot;doc_type&quot;)] = di.type;
+	page[wxT(&quot;doc_doc&quot;)] = di.document_id;
+	page[wxT(&quot;doc_version&quot;)] = di.version_id;
+
+	// Set folds
+	wxJSONValue&amp; foldsArray = page[wxT(&quot;folds&quot;)];
+	if (!foldsArray.IsArray()) foldsArray.SetType(wxJSONTYPE_ARRAY);
+	for (vector&lt;unsigned int&gt;::const_iterator p = folds.begin(); p != folds.end(); ++p) {
+		foldsArray.Append(*p);
+	}
+
+	// Set bookmarks
+	wxJSONValue&amp; bookmarksArray = page[wxT(&quot;bookmarks&quot;)];
+	if (!bookmarksArray.IsArray()) bookmarksArray.SetType(wxJSONTYPE_ARRAY);
+	for (vector&lt;cxBookmark&gt;::const_iterator b = bookmarks.begin(); b != bookmarks.end(); ++b) {
+		bookmarksArray.Append(b-&gt;line_id);
+	}
+}
+
+void eFrameSettings::GetPageSettings(size_t page_id, wxString&amp; path, doc_id&amp; di, int&amp; pos, int&amp; topline, wxString&amp; syntax, vector&lt;unsigned int&gt;&amp; folds, vector&lt;unsigned int&gt;&amp; bookmarks, SubPage sp) const {
+	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
+	wxASSERT((int)page_id &lt; pages.Size());
+	const wxJSONValue toppage = pages.ItemAt(page_id);
+
+	// With diffs we may have subpages
+	const wxJSONValue page = (sp == SP_MAIN) ? toppage : ((sp == SP_LEFT) ? toppage.ItemAt(wxT(&quot;left&quot;)) : toppage.ItemAt(wxT(&quot;right&quot;)));
+
+	path = page.ItemAt(wxT(&quot;path&quot;)).AsString();
+	pos = page.ItemAt(wxT(&quot;pos&quot;)).AsInt();
+	topline = page.ItemAt(wxT(&quot;topline&quot;)).AsInt();
+	syntax = page.ItemAt(wxT(&quot;syntax&quot;)).AsString();
+
+	// doc_id
+	di.type = (doc_type)page.ItemAt(wxT(&quot;doc_type&quot;)).AsInt();
+	di.document_id = page.ItemAt(wxT(&quot;doc_doc&quot;)).AsInt();
+	di.version_id = page.ItemAt(wxT(&quot;doc_version&quot;)).AsInt();
+
+	// Set folds
+	const wxJSONValue foldsArray = page.ItemAt(wxT(&quot;folds&quot;));
+	for (int f = 0; f &lt; foldsArray.Size(); ++f) {
+		folds.push_back(foldsArray.ItemAt(f).AsInt());
+	}
+
+	// Set bookmarks
+	const wxJSONValue bookmarksArray = page.ItemAt(wxT(&quot;bookmarks&quot;));
+	for (int b = 0; b &lt; bookmarksArray.Size(); ++b) {
+		bookmarks.push_back(bookmarksArray.ItemAt(b).AsInt());
+	}
+}
+
+bool eFrameSettings::IsPageDiff(size_t page_id) const {
+	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
+	wxASSERT((int)page_id &lt; pages.Size());
+	const wxJSONValue page = pages.ItemAt(page_id);
+	return page.HasMember(wxT(&quot;left&quot;));
+}
+
+wxString eFrameSettings::GetPagePath(size_t page_id, SubPage sp) const {
+	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
+	wxASSERT((int)page_id &lt; pages.Size());
+	const wxJSONValue toppage = pages.ItemAt(page_id);
+
+	// With diffs we may have subpages
+	const wxJSONValue page = (sp == SP_MAIN) ? toppage : ((sp == SP_LEFT) ? toppage.ItemAt(wxT(&quot;left&quot;)) : toppage.ItemAt(wxT(&quot;right&quot;)));
+
+	return page.ItemAt(wxT(&quot;path&quot;)).AsString();
+}
+
+doc_id eFrameSettings::GetPageDoc(size_t page_id, SubPage sp) const {
+	const wxJSONValue pages = m_jsonRoot.ItemAt(wxT(&quot;pages&quot;));
+	wxASSERT((int)page_id &lt; pages.Size());
+	const wxJSONValue toppage = pages.ItemAt(page_id);
+
+	// With diffs we may have subpages
+	const wxJSONValue page = (sp == SP_MAIN) ? toppage : ((sp == SP_LEFT) ? toppage.ItemAt(wxT(&quot;left&quot;)) : toppage.ItemAt(wxT(&quot;right&quot;)));
+
+	doc_id di;
+	di.type = (doc_type)page.ItemAt(wxT(&quot;doc_type&quot;)).AsInt();
+	di.document_id = page.ItemAt(wxT(&quot;doc_doc&quot;)).AsInt();
+	di.version_id = page.ItemAt(wxT(&quot;doc_version&quot;)).AsInt();
+
+	return di;
+}
+
+void eFrameSettings::DeleteAllPageSettings() {
+	m_jsonRoot.Remove(wxT(&quot;pages&quot;));
+}
+
+void eFrameSettings::DeletePageSettings(size_t page_id) {
+	wxJSONValue&amp; pages = m_jsonRoot.Item(wxT(&quot;pages&quot;));
+	wxASSERT((int)page_id &lt; pages.Size());
+
+	pages.Remove(page_id);
+}</diff>
      <filename>src/eSettings.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -27,6 +27,37 @@
 // pre-declarations
 class RemoteProfile;
 
+enum SubPage {SP_MAIN=0, SP_LEFT, SP_RIGHT};
+
+class eFrameSettings {
+public:
+	eFrameSettings(wxJSONValue&amp; framesettings);
+
+	// Individual settings
+	bool GetSettingBool(const wxString&amp; name, bool&amp; value) const;
+	void SetSettingBool(const wxString&amp; name, bool value);
+	bool GetSettingInt(const wxString&amp; name, int&amp; value) const;
+	void SetSettingInt(const wxString&amp; name, int value);
+	bool GetSettingString(const wxString&amp; name, wxString&amp; value) const;
+	void SetSettingString(const wxString&amp; name, const wxString&amp; value);
+	void RemoveSetting(const wxString&amp; name);
+
+	// Pages
+	size_t GetPageCount() const;
+	void SetPageSettings(size_t page_id, const wxString&amp; path, doc_id di, int pos, int topline, const wxString&amp; syntax, const vector&lt;unsigned int&gt;&amp; folds, const vector&lt;cxBookmark&gt;&amp; bookmarks, SubPage sp=SP_MAIN);
+	void GetPageSettings(size_t page_id, wxString&amp; path, doc_id&amp; di, int&amp; pos, int&amp; topline, wxString&amp; syntax, vector&lt;unsigned int&gt;&amp; folds, vector&lt;unsigned int&gt;&amp; bookmarks, SubPage sp=SP_MAIN) const;
+	bool IsPageDiff(size_t page_id) const;
+	wxString GetPagePath(size_t page_id, SubPage sp=SP_MAIN) const;
+	doc_id GetPageDoc(size_t page_id, SubPage sp=SP_MAIN) const;
+	void DeletePageSettings(size_t page_id);
+	void DeleteAllPageSettings();
+
+	wxJSONRefData* GetRefData() const {return m_jsonRoot.GetRefData();};
+
+private:
+	wxJSONValue&amp; m_jsonRoot;
+};
+
 class eSettings: public ISettings {
 public:
 	eSettings();
@@ -44,26 +75,23 @@ public:
 	void SetSettingLong(const wxString&amp; name, const wxLongLong&amp; value);
 	bool GetSettingString(const wxString&amp; name, wxString&amp; value) const;
 	void SetSettingString(const wxString&amp; name, const wxString&amp; value);
-
 	void RemoveSetting(const wxString&amp; name);
 
+	// Frames
+	unsigned int GetFrameCount() const;
+	eFrameSettings GetFrameSettings(unsigned int frameId);
+	unsigned int AddFrame(unsigned int top);
+	void RemoveFrame(unsigned int frameId);
+	void RemoveFrame(const eFrameSettings&amp; fs);
+	void DeleteAllFrameSettings(int top);
+	int GetIndexFromFrameSettings(const eFrameSettings&amp; fs) const;
+
 	// Recent files
 	void AddRecentFile(const wxString&amp; path);
 	void AddRecentProject(const wxString&amp; path);
 	void GetRecentFiles(wxArrayString&amp; recentfiles) const;
 	void GetRecentProjects(wxArrayString&amp; recentprojects) const;
 
-	// Pages
-	enum SubPage {SP_MAIN=0, SP_LEFT, SP_RIGHT};
-	size_t GetPageCount() const;
-	void SetPageSettings(size_t page_id, const wxString&amp; path, doc_id di, int pos, int topline, const wxString&amp; syntax, const vector&lt;unsigned int&gt;&amp; folds, const vector&lt;cxBookmark&gt;&amp; bookmarks, SubPage sp=SP_MAIN);
-	void GetPageSettings(size_t page_id, wxString&amp; path, doc_id&amp; di, int&amp; pos, int&amp; topline, wxString&amp; syntax, vector&lt;unsigned int&gt;&amp; folds, vector&lt;unsigned int&gt;&amp; bookmarks, SubPage sp=SP_MAIN) const;
-	bool IsPageDiff(size_t page_id) const;
-	wxString GetPagePath(size_t page_id, SubPage sp=SP_MAIN) const;
-	doc_id GetPageDoc(size_t page_id, SubPage sp=SP_MAIN) const;
-	void DeletePageSettings(size_t page_id);
-	void DeleteAllPageSettings();
-
 	// Recent Diffs
 	void AddRecentDiff(const wxString&amp; path, SubPage sp);
 	void GetRecentDiffs(wxArrayString&amp; recentprojectsh, SubPage sp) const;</diff>
      <filename>src/eSettings.h</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>5e061bc457af3093e82cab310fadfd7f4a022f2b</id>
    </parent>
  </parents>
  <author>
    <name>Alexander Stigsen</name>
    <email>stigsen@e-texteditor.com</email>
  </author>
  <url>http://github.com/adamv/e/commit/00a68e16258ba551a0100439eb05ee6b1c2ec728</url>
  <id>00a68e16258ba551a0100439eb05ee6b1c2ec728</id>
  <committed-date>2009-10-12T05:20:28-07:00</committed-date>
  <authored-date>2009-10-12T05:20:28-07:00</authored-date>
  <message>Added Multi-Window support</message>
  <tree>c257b5e806987bfb91a76b63e43ff709f2c6b7ec</tree>
  <committer>
    <name>Alexander Stigsen</name>
    <email>stigsen@e-texteditor.com</email>
  </committer>
</commit>
