int cbAuiNotebook::GetTabPositionFromIndex(int index)
{
    if (GetPageCount() <= 0)
        return wxNOT_FOUND;

    UpdateTabControlsArray();

    wxAuiTabCtrl* tabCtrl = nullptr;
    int idx = -1;

    if (!FindTab(GetPage(index), &tabCtrl, &idx))
        return wxNOT_FOUND;

    if (!tabCtrl || idx < 0)
        return wxNOT_FOUND;

    int indexOffset = 0;
    wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
    const size_t pane_count = all_panes.GetCount();
    for (size_t i = 0; i < pane_count; ++i)
    {
        wxAuiPaneInfo& pane = all_panes[i];
        if (pane.name == wxT("dummy"))
            continue;

        if (pane.window == GetTabFrameFromTabCtrl(tabCtrl))
            break;

        for (size_t j = 0; j < m_TabCtrls.GetCount(); ++j)
        {
            if (pane.window == GetTabFrameFromTabCtrl(m_TabCtrls[j]))
            {
                indexOffset += m_TabCtrls[j]->GetPageCount();
                break;
            }
        }
    }
    return idx + indexOffset;
}
Exemple #2
0
void tpanelnotebook::FillWindowLayout(unsigned int mainframeindex) {
	wxAuiPaneInfoArray &all_panes = m_mgr.GetAllPanes();
	size_t pane_count = all_panes.GetCount();

	size_t pagecount = GetPageCount();
	for (size_t i = 0; i < pagecount; ++i) {
		tpanelparentwin_nt *tppw = dynamic_cast<tpanelparentwin_nt*>(GetPage(i));
		if (!tppw) continue;

		wxAuiTabCtrl* tc;
		int tabindex;
		if (!FindTab(tppw, &tc, &tabindex)) continue;

		wxWindow *tabframe = GetTabFrameFromTabCtrl(tc);
		if (!tabframe) continue;

		unsigned int splitindex = 0;
		bool found = false;
		for (size_t j = 0; j < pane_count; ++j) {
			if (all_panes.Item(j).name == wxT("dummy")) {
				continue;
			}
			if (all_panes.Item(j).window == tabframe) {
				found = true;
				break;
			} else {
				splitindex++;
			}
		}
		if (!found) continue;

		ad.twinlayout.emplace_back();
		twin_layout_desc &twld = ad.twinlayout.back();
		twld.mainframeindex = mainframeindex;
		twld.splitindex = splitindex;
		twld.tabindex = tabindex;
		auto tp = tppw->pimpl()->tp_base;
		twld.tpautos = tp->tpautos;
		twld.tpudcautos = tp->tpudcautos;
		twld.name = tp->name;
		twld.dispname = tp->dispname;
		twld.flags = tp->flags;
		twld.intersect_flags = tppw->pimpl()->intersect_flags;
		twld.tppw_flags = tppw->pimpl()->tppw_flags & TPPWF::DB_SAVE_MASK;
	}
}
bool cbAuiNotebook::LoadPerspective(const wxString& layout, bool mergeLayouts)
{
    if (layout.IsEmpty())
        return false;

    wxString tabs = layout.BeforeFirst (wxT ('@') );
    // Remove all tab ctrls (but still keep them in main index)
    const size_t tab_count = m_tabs.GetPageCount();
    for (size_t i = 0; i < tab_count; ++i)
    {
        // only remove tabs that are in the layout-string, do not touch others,
        // so the layout of an already loaded workspace or project will not get destroyed, if the
        // current layout did not know the tab. The layout file which is loaded last takes precedence,
        // if there are two or more layout strings containing the actual tab.
        if ( tabs.Find( UniqueIdFromTooltip(GetPageToolTip(i)) ) < 0 )
            continue;

        wxWindow* wnd = m_tabs.GetWindowFromIdx (i);

        // find out which onscreen tab ctrl owns this tab
        wxAuiTabCtrl* ctrl;
        int ctrl_idx;
        if ( !FindTab(wnd, &ctrl, &ctrl_idx) )
            return false;

        // remove the tab from ctrl
        if ( !ctrl->RemovePage(wnd) )
            return false;
    }
    RemoveEmptyTabFrames();
    wxString currentLayout;
    if (mergeLayouts)
    {
        currentLayout = m_mgr.SavePerspective();
        wxString tempLayout;
        while (!currentLayout.empty())
        {
            if ( currentLayout.BeforeFirst('|').StartsWith(_("layout2")) ||
                 currentLayout.BeforeFirst('|').StartsWith(_("name=dummy")) )
            {
                currentLayout = currentLayout.AfterFirst(('|'));
                currentLayout.Trim();
                currentLayout.Trim(true);
            }
            else
            {
                wxString pane_part = currentLayout.BeforeFirst('|');
                pane_part.Trim();
                pane_part.Trim(true);
                if (!pane_part.empty())
                    tempLayout += pane_part + wxT("|");

                currentLayout = currentLayout.AfterFirst('|');
                currentLayout.Trim();
                currentLayout.Trim(true);
            }
        }
        currentLayout = tempLayout;
        if (currentLayout.empty())
            mergeLayouts = false;
    }

    size_t sel_page = 0;
    int active_tab = 0;
    bool found = false;

    wxString frames = layout.AfterFirst (wxT ('@') );
    // if we load an additional project to an exiting layout, the first new tab always goes into a new frame
    bool firstTabInCtrl =! currentLayout.empty();
    // This creates a new tabframe if none exists; a workaround, because we can not directly access
    // the needed wxTabFrame class, because it is not exported.
    // This also takes care of all needed pane-info
    wxAuiTabCtrl* dest_tabs = GetActiveTabCtrl();
    while (1)
    {
        const wxString tab_part = tabs.BeforeFirst(wxT('|'));

        // if the string is empty, we're done parsing
        if (tab_part.empty())
            break;

        // Get pane name
        wxString pane_name = tab_part.BeforeFirst(wxT('='));

        // create a new tab frame
#if wxCHECK_VERSION(3, 0, 0)
        m_curPage = -1;
#else
        m_curpage = -1;
#endif

        // Get list of tab id's and move them to pane
        wxString tab_list = tab_part.AfterFirst(wxT('='));
        while (1)
        {
            wxString tab = tab_list.BeforeFirst(wxT(','));
            wxString name = tab.AfterFirst(wxT(';'));
            tab = tab.BeforeFirst(wxT(';'));

            if (tab.empty())
                break;
            tab_list = tab_list.AfterFirst(wxT(','));

            // Check if this page has an 'active' marker
            const wxChar c = tab[0];
            if (c == wxT('+') || c == wxT('*'))
                tab = tab.Mid(1);

            // Move tab to pane
            const int index_in_m_tabs = GetTabIndexFromTooltip(name);
            if (index_in_m_tabs < 0)
                continue;

            wxAuiNotebookPage& page = m_tabs.GetPage(index_in_m_tabs);

            // save the actual active tab, because it will be set to 0 after a Split()
            active_tab = dest_tabs->GetActivePage();
            const size_t newpage_idx = dest_tabs->GetPageCount();
            dest_tabs->InsertPage(page.window, page, newpage_idx);

            if (c == wxT('+'))
                dest_tabs->SetActivePage(newpage_idx);
            else if (c == wxT('*'))
                sel_page = index_in_m_tabs;

            // If we should be the first tab in a tab-ctrl we switch to the next existing tab,
            // or create a new one  by calling Split() and update the dest_tabs accordingly.
            if (firstTabInCtrl)
            {
                int nextIndex = m_TabCtrls.Index(dest_tabs) + 1;
                if (nextIndex == 0 || nextIndex >= static_cast<int>(m_TabCtrls.GetCount()))
                {
                    Split(index_in_m_tabs, wxRIGHT);
                    // reset the active tab, because a Split() set it to zero
                    dest_tabs->SetActivePage(active_tab);
                    dest_tabs = GetActiveTabCtrl();
                }
                else
                    dest_tabs = m_TabCtrls.Item(nextIndex);
            }
            // Change the pane name to the one we have stored in the layout-string.
            wxAuiPaneInfo& pane = m_mgr.GetPane( GetTabFrameFromTabCtrl(dest_tabs) );
            if (pane.name != pane_name)
            {
                tab.Replace(pane_name, pane.name);
                frames.Replace(pane_name, pane.name);
                pane_name = pane.name;
            }
            firstTabInCtrl = false;
            found = true;
        }
        // We come here after at least one tabctrl is filled, so the next tab should go in a new one
        firstTabInCtrl = true;

        tabs = tabs.AfterFirst(wxT('|'));
    }

    // Check for windows not readded to the notebook and add the at the end.
    for (size_t i = 0; i < tab_count; ++i)
    {
        wxAuiNotebookPage& page = m_tabs.GetPage(i);

        // find out which onscreen tab ctrl owns this tab
        // if none then add it to the last used tabctrl
        wxAuiTabCtrl* ctrl;
        int ctrl_idx;
        if ( !FindTab(page.window, &ctrl, &ctrl_idx) )
        {
            const size_t newpage_idx = dest_tabs->GetPageCount();
            dest_tabs->InsertPage (page.window, page, newpage_idx);
        }

    }

    if (mergeLayouts)
    {
        wxRegEx reDockSize(_T("(dock_size[()0-9,]+=)[0-9]+"));
        const wxString replacement(wxT("\\1-1"));
        // Make a centered frame left docked
        frames.Replace(wxString::Format(wxT("dock_size(%d"), wxAUI_DOCK_CENTER), wxString::Format(wxT("dock_size(%d"), wxAUI_DOCK_LEFT));
        frames.Replace(wxString::Format(wxT("dir=%d"), wxAUI_DOCK_CENTER), wxString::Format(wxT("dir=%d"), wxAUI_DOCK_LEFT));
        if (reDockSize.Matches(frames))
            reDockSize.ReplaceAll(&frames,replacement);
        if (reDockSize.Matches(currentLayout))
            reDockSize.ReplaceAll(&currentLayout,replacement);
        while (!currentLayout.empty())
        {
            wxString pane_part = currentLayout.BeforeFirst('|');
            pane_part.Trim();
            pane_part.Trim(true);
            if (!pane_part.empty())
                frames += pane_part + wxT("|");
            currentLayout = currentLayout.AfterFirst('|');
            currentLayout.Trim();
            currentLayout.Trim(true);
        }
    }

    if (found)
        m_mgr.LoadPerspective(frames);
    RemoveEmptyTabFrames();

    // Force refresh of selection
#if wxCHECK_VERSION(3, 0, 0)
    m_curPage = -1;
#else
    m_curpage = -1;
#endif
    SetSelection(sel_page);

    UpdateTabControlsArray();
    return true;
}
wxString cbAuiNotebook::SavePerspective(const wxString projectTitle)
{
    // Build list of panes/tabs
    wxString tabs, tabsTmp;
    wxArrayString panes;

    // first get all tab-controls
    UpdateTabControlsArray();

    wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
    const size_t pane_count = all_panes.GetCount();
    for (size_t i = 0; i < pane_count; ++i)
    {
        wxAuiPaneInfo& pane = all_panes.Item(i);
        if (pane.name == wxT("dummy"))
            continue;

        wxAuiTabCtrl* tabCtrl = nullptr;
        for (size_t j = 0; j < m_TabCtrls.GetCount(); ++j)
        {
            if (pane.window == GetTabFrameFromTabCtrl(m_TabCtrls.Item(j)))
            {
                tabCtrl = m_TabCtrls.Item(j);
                break;
            }
        }
        if (tabCtrl)
        {
            tabsTmp.Clear();
            // add tab id's
            size_t page_count = tabCtrl->GetPageCount();
            for (size_t p = 0; p < page_count; ++p)
            {
                wxAuiNotebookPage& page = tabCtrl->GetPage(p);
                const size_t page_idx = m_tabs.GetIdxFromWindow(page.window);

                wxString id = UniqueIdFromTooltip(GetPageToolTip(page_idx));

                // file does not belong to any project, so don't save
                if (id.BeforeLast(':').empty())
                    continue;

                // if we save a project (projectTitle non empty), but file does not belong to the project
                // skip it
                if (!projectTitle.empty() && id.BeforeLast(':') != projectTitle)
                    continue;

                if (!tabsTmp.empty())
                    tabsTmp += wxT(",");

#if wxCHECK_VERSION(3, 0, 0)
                if ((int)page_idx == m_curPage)
#else
                if ((int)page_idx == m_curpage)
#endif
                    tabsTmp += wxT("*");
                else if ((int)p == tabCtrl->GetActivePage())
                    tabsTmp += wxT("+");

                tabsTmp += wxString::Format(wxT("%lu"), static_cast<unsigned long>(page_idx));
                tabsTmp += wxT(";");
                tabsTmp += id;
            }
            if (!tabsTmp.empty())
            {
                if (!tabs.empty())
                    tabs += wxT("|");

                panes.Add(pane.name);
                tabs += pane.name;
                tabs += wxT("=");
                tabs += tabsTmp;
            }
        }
    }
    tabs += wxT("@");

    tabsTmp = m_mgr.SavePerspective();

    wxArrayString arTabsTmp = GetArrayFromString(tabsTmp, wxT("|"));

    for (size_t i = arTabsTmp.GetCount(); i > 0 ; )
    {
        if (arTabsTmp.Item(--i).StartsWith(wxT("name=")))
        {
            wxString strTmp = arTabsTmp.Item(i).AfterFirst('=').BeforeFirst(';');
            if (strTmp == wxT("dummy"))
                continue;
            if (panes.Index(strTmp) < 0)
                arTabsTmp.RemoveAt(i);
        }
    }

    tabsTmp = GetStringFromArray(arTabsTmp, wxT("|"));

    // Add frame perspective
    tabs += tabsTmp;

    return tabs;
}