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
Session()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
~Session()46 Session::~Session()
47 {
48 // FIXME Clean up all the data objects...
49 }
50
getViewIfOpen(const std::string & file_name) const51 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
open(const std::string & file_name,std::function<ViewInterface * ()> view_factory)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
close(const ViewInterface * view)79 void Session::close( const ViewInterface* view )
80 {
81 openFiles_.erase( openFiles_.find( view ) );
82 }
83
save(std::vector<std::tuple<const ViewInterface *,uint64_t,std::shared_ptr<const ViewContextInterface>>> view_list,const QByteArray & geometry)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
restore(std::function<ViewInterface * ()> view_factory,int * current_file_index)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
storedGeometry(QByteArray * geometry) const139 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
getFilename(const ViewInterface * view) const148 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
getFileInfo(const ViewInterface * view,uint64_t * fileSize,uint32_t * fileNbLine,QDateTime * lastModified) const157 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
openAlways(const std::string & file_name,std::function<ViewInterface * ()> view_factory,const char * view_context)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
findOpenFileFromView(const ViewInterface * view)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
findOpenFileFromView(const ViewInterface * view) const216 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