/* NppPluginIface_DocTabMap.h * * This file is part of the Notepad++ Plugin Interface Lib. * Copyright 2008 - 2009 Thell Fowler (thell@almostautomated.com) * * This program is free software; you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Notepad++ Plugin Interface Lib extension providing mapping of Notepad++ tab bufferID and * visibility to Scintilla Document pointers, as well as tracking the currently open files * by docID and a docId to bufferID map. * * For an example of using this see NppPluginIface_ActionIndex. * */ #include "NppPluginIface_DocTabMap.h" #include #include // <--- Notepad++ Scintilla Components for BufferID to pDoc ---> #define TIXMLA_USE_STL #include "Buffer.h" // <--- Boost ---> #include #include #include #include namespace npp_plugin { namespace doctabmap { // The main class for storing the document to buffer state information. struct DocTab { HWND _view; int _tab; BufferID _bufferID; Document _pDoc; bool _isVisible; DocTab( HWND view, int tab, BufferID bufferID, Document pDoc, bool isVisible) :_view(view), _tab(tab), _bufferID(bufferID), _pDoc(pDoc), _isVisible(isVisible){}; }; // Boost mulit_index_container setup for tracking tab visibility states. using boost::multi_index::multi_index_container; using namespace boost::multi_index; // Namespace for the DocTab multi_index_container. namespace doctabmap_mic { // DocTab_set index key for comp_visible_key. struct dt_visible_key{}; // DocTab_set composite index key for unique view/visible combination. struct comp_visible_key:composite_key< DocTab, BOOST_MULTI_INDEX_MEMBER(DocTab, HWND, _view), BOOST_MULTI_INDEX_MEMBER(DocTab, bool, _isVisible) >{}; // Multi Index Container for indexing N++ Doc Tab state data. typedef multi_index_container< DocTab, indexed_by< ordered_unique< tag, comp_visible_key > > > DocTab_set; // Index definition type for the DocTab_set container. typedef DocTab_set::index::type dts_by_visibleTab; // The one and only DocTab_set container. DocTab_set dts; // A set for storing active and ready open documents std::set open_docs; // A map for storing buffer id to doc id. Usefull for doc open/close operations. std::map< int, int > buff2doc_map; } // End namespace doctabmap_mic using namespace doctabmap_mic; // Public index to the DocTab_set. dts_by_visibleTab& visibleTab_index = dts.get(); // Update the tab mapping between bufferIDs and pDocs for message filtering. void update_DocTabMap() { // Since there isn't a buffer-deactivate message to remove an entry we empty the set and // rebuild on buffer activated messages. if ( dts.size() > 0 ) { dts.clear(); open_docs.clear(); } // Populate the DocTab_set // The tab and buffer ID aren't really needed, yet I believe there may be some other // uses for that information so they've been left in there. bool isVisible = false; for ( int view = MAIN_VIEW; view <= SUB_VIEW; view++ ) { HWND targetView = hViewByInt(view); Document viewDocID = (Document)::SendMessage( targetView, SCI_GETDOCPOINTER, 0, 0); int nb_openfiles_view = ( view == MAIN_VIEW ) ? ( PRIMARY_VIEW ) : ( SECOND_VIEW ); int nb_Tabs = ::SendMessage( hNpp(), NPPM_GETNBOPENFILES, 0, nb_openfiles_view ); for ( int tab = 0; tab < nb_Tabs; tab++ ) { int tabBuffID = ::SendMessage( hNpp(), NPPM_GETBUFFERIDFROMPOS, tab, view); if ( tabBuffID > 0 ) { BufferID pBuff = (BufferID)tabBuffID;; Document pDoc = pBuff->getDocument(); isVisible = ( pDoc == viewDocID ) ? ( true ) : ( false ); dts.insert( DocTab( targetView, tab, pBuff, pDoc, isVisible) ); open_docs.insert( (int)pDoc ); if ( buff2doc_map.find( (int)pBuff ) == buff2doc_map.end() ) { buff2doc_map[ (int)pBuff ] = (int)pDoc; } } } } } // Returns the Scintilla Document ID for the visible document in the specified view. // ( MAIN_VIEW = 0, SUB_VIEW = 1 ) int getVisibleDocId_by_View( int view ) { // The tuple is composed of the HWND for the view and a bool for 'is visible' to lookup // the Doc ID based on the composite key from the index. DocTab _DocTab = *(visibleTab_index.find( boost::make_tuple( hViewByInt( view ), true ) ) ); return ( _DocTab._pDoc ); } // Returns the Scintilla Document ID matching a buffer ID. int getDocIdFromBufferId( int bufferID ) { return ( buff2doc_map[bufferID] ); } // Returns true if a document is currently open and ready. bool fileIsOpen( int pDoc ) { if ( open_docs.find( pDoc ) != open_docs.end() ) return ( true ); else return ( false ); } } // End namespace: doctabmap } // End namespace: npp_plugin