1 /* 2 * Copyright (C) 2013, 2014 Nicolas Bonnefon and other contributors 3 * 4 * This file is part of glogg. 5 * 6 * glogg is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * glogg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with glogg. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "session.h" 21 22 #include "log.h" 23 24 #include <cassert> 25 #include <QFileInfo> 26 #include <algorithm> 27 28 #include "viewinterface.h" 29 #include "persistentinfo.h" 30 #include "savedsearches.h" 31 #include "sessioninfo.h" 32 #include "data/logdata.h" 33 #include "data/logfiltereddata.h" 34 35 Session::Session() 36 { 37 GetPersistentInfo().retrieve( QString( "savedSearches" ) ); 38 39 // Get the global search history (it remains the property 40 // of the Persistent) 41 savedSearches_ = Persistent<SavedSearches>( "savedSearches" ); 42 43 quickFindPattern_ = std::make_shared<QuickFindPattern>(); 44 } 45 46 Session::~Session() 47 { 48 // FIXME Clean up all the data objects... 49 } 50 51 ViewInterface* Session::getViewIfOpen( const std::string& file_name ) const 52 { 53 auto result = std::find_if( openFiles_.begin(), openFiles_.end(), 54 [&](const std::pair<const ViewInterface*, OpenFile>& o) 55 { return ( o.second.fileName == file_name ); } ); 56 57 if ( result != openFiles_.end() ) 58 return result->second.view; 59 else 60 return nullptr; 61 } 62 63 ViewInterface* Session::open( const std::string& file_name, 64 std::function<ViewInterface*()> view_factory ) 65 { 66 ViewInterface* view = nullptr; 67 68 QFileInfo fileInfo( file_name.c_str() ); 69 if ( fileInfo.isReadable() ) { 70 return openAlways( file_name, view_factory, nullptr ); 71 } 72 else { 73 throw FileUnreadableErr(); 74 } 75 76 return view; 77 } 78 79 void Session::close( const ViewInterface* view ) 80 { 81 openFiles_.erase( openFiles_.find( view ) ); 82 } 83 84 void Session::save( std::vector< 85 std::tuple<const ViewInterface*, 86 uint64_t, 87 std::shared_ptr<const ViewContextInterface>> 88 > view_list, 89 const QByteArray& geometry ) 90 { 91 LOG(logDEBUG) << "Session::save"; 92 93 std::vector<SessionInfo::OpenFile> session_files; 94 for ( auto view: view_list ) { 95 const ViewInterface* view_object; 96 uint64_t top_line; 97 std::shared_ptr<const ViewContextInterface> view_context; 98 99 std::tie( view_object, top_line, view_context ) = view; 100 101 const OpenFile* file = findOpenFileFromView( view_object ); 102 assert( file ); 103 104 LOG(logDEBUG) << "Saving " << file->fileName << " in session."; 105 session_files.push_back( { file->fileName, top_line, view_context->toString() } ); 106 } 107 108 std::shared_ptr<SessionInfo> session = 109 Persistent<SessionInfo>( "session" ); 110 session->setOpenFiles( session_files ); 111 session->setGeometry( geometry ); 112 GetPersistentInfo().save( QString( "session" ) ); 113 } 114 115 std::vector<std::pair<std::string, ViewInterface*>> Session::restore( 116 std::function<ViewInterface*()> view_factory, 117 int *current_file_index ) 118 { 119 GetPersistentInfo().retrieve( QString( "session" ) ); 120 std::shared_ptr<SessionInfo> session = 121 Persistent<SessionInfo>( "session" ); 122 123 std::vector<SessionInfo::OpenFile> session_files = session->openFiles(); 124 LOG(logDEBUG) << "Session returned " << session_files.size(); 125 std::vector<std::pair<std::string, ViewInterface*>> result; 126 127 for ( auto file: session_files ) 128 { 129 LOG(logDEBUG) << "Create view for " << file.fileName; 130 ViewInterface* view = openAlways( file.fileName, view_factory, file.viewContext.c_str() ); 131 result.push_back( { file.fileName, view } ); 132 } 133 134 *current_file_index = -1; 135 136 return result; 137 } 138 139 void Session::storedGeometry( QByteArray* geometry ) const 140 { 141 GetPersistentInfo().retrieve( QString( "session" ) ); 142 std::shared_ptr<SessionInfo> session = 143 Persistent<SessionInfo>( "session" ); 144 145 *geometry = session->geometry(); 146 } 147 148 std::string Session::getFilename( const ViewInterface* view ) const 149 { 150 const OpenFile* file = findOpenFileFromView( view ); 151 152 assert( file ); 153 154 return file->fileName; 155 } 156 157 void Session::getFileInfo( const ViewInterface* view, uint64_t* fileSize, 158 uint32_t* fileNbLine, QDateTime* lastModified ) const 159 { 160 const OpenFile* file = findOpenFileFromView( view ); 161 162 assert( file ); 163 164 *fileSize = file->logData->getFileSize(); 165 *fileNbLine = file->logData->getNbLine(); 166 *lastModified = file->logData->getLastModifiedDate(); 167 } 168 169 170 /* 171 * Private methods 172 */ 173 174 ViewInterface* Session::openAlways( const std::string& file_name, 175 std::function<ViewInterface*()> view_factory, 176 const char* view_context ) 177 { 178 // Create the data objects 179 auto log_data = std::make_shared<LogData>(); 180 auto log_filtered_data = 181 std::shared_ptr<LogFilteredData>( log_data->getNewFilteredData() ); 182 183 ViewInterface* view = view_factory(); 184 view->setData( log_data, log_filtered_data ); 185 view->setQuickFindPattern( quickFindPattern_ ); 186 view->setSavedSearches( savedSearches_ ); 187 188 if ( view_context ) 189 view->setViewContext( view_context ); 190 191 // Insert in the hash 192 openFiles_.insert( { view, 193 { file_name, 194 log_data, 195 log_filtered_data, 196 view } } ); 197 198 // Start loading the file 199 log_data->attachFile( QString( file_name.c_str() ) ); 200 201 return view; 202 } 203 204 Session::OpenFile* Session::findOpenFileFromView( const ViewInterface* view ) 205 { 206 assert( view ); 207 208 OpenFile* file = &( openFiles_.at( view ) ); 209 210 // OpenfileMap::at might throw out_of_range but since a view MUST always 211 // be attached to a file, we don't handle it! 212 213 return file; 214 } 215 216 const Session::OpenFile* Session::findOpenFileFromView( const ViewInterface* view ) const 217 { 218 assert( view ); 219 220 const OpenFile* file = &( openFiles_.at( view ) ); 221 222 // OpenfileMap::at might throw out_of_range but since a view MUST always 223 // be attached to a file, we don't handle it! 224 225 return file; 226 } 227