xref: /glogg/src/main.cpp (revision 2489511975eb13c9bffc134bb3b6a7efad1abe50)
1 /*
2  * Copyright (C) 2009, 2010, 2011, 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 <QApplication>
21 
22 #include <memory>
23 
24 #include <boost/program_options.hpp>
25 namespace po = boost::program_options;
26 
27 #include <iostream>
28 #include <iomanip>
29 using namespace std;
30 
31 #include "persistentinfo.h"
32 #include "sessioninfo.h"
33 #include "configuration.h"
34 #include "filterset.h"
35 #include "recentfiles.h"
36 #include "session.h"
37 #include "mainwindow.h"
38 #include "savedsearches.h"
39 #include "loadingstatus.h"
40 
41 #include "externalcom.h"
42 #ifdef GLOGG_SUPPORTS_DBUS
43 #include "dbusexternalcom.h"
44 #elif GLOGG_SUPPORTS_WINIPC
45 #include "winexternalcom.h"
46 #endif
47 
48 
49 #include "log.h"
50 
51 static void print_version();
52 
53 int main(int argc, char *argv[])
54 {
55     QApplication app(argc, argv);
56 
57     string filename = "";
58 
59     // Configuration
60     bool new_session = false;
61     bool multi_instance = false;
62 
63     TLogLevel logLevel = logWARNING;
64 
65     try {
66         po::options_description desc("Usage: glogg [options] [file]");
67         desc.add_options()
68             ("help,h", "print out program usage (this message)")
69             ("version,v", "print glogg's version information")
70             ("multi,m", "allow multiple instance of glogg to run simultaneously (use together with -s)")
71             ("new-session,s", "do not load the previous session")
72             ("debug,d", "output more debug (include multiple times for more verbosity e.g. -dddd")
73             ;
74         po::options_description desc_hidden("Hidden options");
75         // For -dd, -ddd...
76         for ( string s = "dd"; s.length() <= 10; s.append("d") )
77             desc_hidden.add_options()(s.c_str(), "debug");
78 
79         desc_hidden.add_options()
80             ("input-file", po::value<string>(), "input file")
81             ;
82 
83         po::options_description all_options("all options");
84         all_options.add(desc).add(desc_hidden);
85 
86         po::positional_options_description positional;
87         positional.add("input-file", 1);
88 
89         int command_line_style = (((po::command_line_style::unix_style ^
90                 po::command_line_style::allow_guessing) |
91                 po::command_line_style::allow_long_disguise) ^
92                 po::command_line_style::allow_sticky);
93 
94         po::variables_map vm;
95         po::store(po::command_line_parser(argc, argv).
96                 options(all_options).
97                 positional(positional).
98                 style(command_line_style).run(),
99                 vm);
100         po::notify(vm);
101 
102         if ( vm.count("help") ) {
103             desc.print(cout);
104             return 0;
105         }
106 
107         if ( vm.count("version") ) {
108             print_version();
109             return 0;
110         }
111 
112         if ( vm.count( "debug" ) )
113             logLevel = logINFO;
114 
115         if ( vm.count( "multi" ) )
116             multi_instance = true;
117 
118         if ( vm.count( "new-session" ) )
119             new_session = true;
120 
121         for ( string s = "dd"; s.length() <= 10; s.append("d") )
122             if ( vm.count( s ) )
123                 logLevel = (TLogLevel) (logWARNING + s.length());
124 
125         if ( vm.count("input-file") )
126             filename = vm["input-file"].as<string>();
127     }
128     catch(exception& e) {
129         cerr << "Option processing error: " << e.what() << endl;
130         return 1;
131     }
132     catch(...) {
133         cerr << "Exception of unknown type!\n";
134     }
135 
136 #if 0
137     FILE* file = fopen("glogg.log", "w");
138     Output2FILE::Stream() = file;
139 #endif
140 
141     FILELog::setReportingLevel( logLevel );
142 
143     // External communicator
144     shared_ptr<ExternalCommunicator> externalCommunicator = nullptr;
145     shared_ptr<ExternalInstance> externalInstance = nullptr;
146 
147     try {
148 #ifdef GLOGG_SUPPORTS_DBUS
149         externalCommunicator = make_shared<DBusExternalCommunicator>();
150         externalInstance = shared_ptr<ExternalInstance>(
151                 externalCommunicator->otherInstance() );
152 #elif GLOGG_SUPPORTS_WINIPC
153         externalCommunicator = make_shared<WinExternalCommunicator>();
154         externalInstance = shared_ptr<ExternalInstance>(
155                 externalCommunicator->otherInstance() );
156 #endif
157     }
158     catch(CantCreateExternalErr& e) {
159         LOG(logWARNING) << "Cannot initialise external communication.";
160     }
161 
162     LOG(logDEBUG) << "externalInstance = " << externalInstance;
163     if ( ( ! multi_instance ) && externalInstance ) {
164         uint32_t version = externalInstance->getVersion();
165         LOG(logINFO) << "Found another glogg (version = "
166             << std::setbase(16) << version << ")";
167 
168         externalInstance->loadFile( QString::fromStdString( filename ) );
169 
170         return 0;
171     }
172     else {
173         // FIXME: there is a race condition here. One glogg could start
174         // between the declaration of externalInstance and here,
175         // is it a problem?
176         if ( externalCommunicator )
177             externalCommunicator->startListening();
178     }
179 
180     // Register types for Qt
181     qRegisterMetaType<LoadingStatus>("LoadingStatus");
182 
183     // Register the configuration items
184     GetPersistentInfo().migrateAndInit();
185     GetPersistentInfo().registerPersistable(
186             std::make_shared<SessionInfo>(), QString( "session" ) );
187     GetPersistentInfo().registerPersistable(
188             std::make_shared<Configuration>(), QString( "settings" ) );
189     GetPersistentInfo().registerPersistable(
190             std::make_shared<FilterSet>(), QString( "filterSet" ) );
191     GetPersistentInfo().registerPersistable(
192             std::make_shared<SavedSearches>(), QString( "savedSearches" ) );
193     GetPersistentInfo().registerPersistable(
194             std::make_shared<RecentFiles>(), QString( "recentFiles" ) );
195 
196     // FIXME: should be replaced by a two staged init of MainWindow
197     GetPersistentInfo().retrieve( QString( "settings" ) );
198 
199     std::unique_ptr<Session> session( new Session() );
200     MainWindow mw( std::move( session ), externalCommunicator );
201 
202     LOG(logDEBUG) << "MainWindow created.";
203     mw.show();
204     if ( ! new_session )
205         mw.reloadSession();
206     mw.loadInitialFile( QString::fromStdString( filename ) );
207     return app.exec();
208 }
209 
210 static void print_version()
211 {
212     cout << "glogg " GLOGG_VERSION "\n";
213 #ifdef GLOGG_COMMIT
214     cout << "Built " GLOGG_DATE " from " GLOGG_COMMIT "\n";
215 #endif
216     cout << "Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicolas Bonnefon and other contributors\n";
217     cout << "This is free software.  You may redistribute copies of it under the terms of\n";
218     cout << "the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n";
219     cout << "There is NO WARRANTY, to the extent permitted by law.\n";
220 }
221