Switch to unified view

a/src/qtgui/main.cpp b/src/qtgui/main.cpp
1
#ifndef lint
1
#ifndef lint
2
static char rcsid[] = "@(#$Id: main.cpp,v 1.33 2006-01-22 18:46:41 dockes Exp $ (C) 2005 J.F.Dockes";
2
static char rcsid[] = "@(#$Id: main.cpp,v 1.34 2006-01-23 13:32:05 dockes Exp $ (C) 2005 J.F.Dockes";
3
#endif
3
#endif
4
/*
5
 *   This program is free software; you can redistribute it and/or modify
6
 *   it under the terms of the GNU General Public License as published by
7
 *   the Free Software Foundation; either version 2 of the License, or
8
 *   (at your option) any later version.
9
 *
10
 *   This program is distributed in the hope that it will be useful,
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *   GNU General Public License for more details.
14
 *
15
 *   You should have received a copy of the GNU General Public License
16
 *   along with this program; if not, write to the
17
 *   Free Software Foundation, Inc.,
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
 */
4
20
5
#include <unistd.h>
21
#include <unistd.h>
6
22
23
//#define WITH_KDE
24
#ifdef WITH_KDE
25
#include <kapplication.h>
26
#include <kmainwindow.h>
27
#include <kaboutdata.h>
28
#include <kcmdlineargs.h>
29
#include <klocale.h>
30
#else
7
#include <qapplication.h>
31
#include <qapplication.h>
8
//#define WITH_KDE
9
#ifdef WITH_KDE
10
#include <kapplication.h>
11
#endif
12
#include <qtranslator.h>
32
#include <qtranslator.h>
33
#endif
34
13
#include <qtextcodec.h> 
35
#include <qtextcodec.h> 
14
#include <qthread.h>
36
#include <qthread.h>
15
#include <qtimer.h>
37
#include <qtimer.h>
16
#include <qmessagebox.h>
38
#include <qmessagebox.h>
17
#include <qsettings.h>
18
#include <qcheckbox.h>
39
#include <qcheckbox.h>
19
40
20
41
21
#include "rcldb.h"
42
#include "rcldb.h"
22
#ifndef NO_NAMESPACES
43
#ifndef NO_NAMESPACES
...
...
26
#include "pathut.h"
47
#include "pathut.h"
27
#include "recoll.h"
48
#include "recoll.h"
28
#include "smallut.h"
49
#include "smallut.h"
29
#include "rclinit.h"
50
#include "rclinit.h"
30
#include "debuglog.h"
51
#include "debuglog.h"
31
52
#include "rclversion.h"
32
#include "rclmain.h"
53
#include "rclmain.h"
54
#include "guiutils.h"
33
55
56
#ifdef WITH_KDE
57
static const char description[] =
58
    I18N_NOOP("A KDE fulltext search application");
59
60
static KCmdLineOptions options[] =
61
{
62
//    { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
63
    KCmdLineLastOption
64
};
65
#endif
66
67
34
static const char *recoll_datadir = RECOLL_DATADIR;
68
const string recoll_datadir = RECOLL_DATADIR;
35
69
36
RclConfig *rclconfig;
70
RclConfig *rclconfig;
37
Rcl::Db *rcldb;
71
Rcl::Db *rcldb;
38
int recollNeedsExit;
72
int recollNeedsExit;
39
static string dbdir;
73
static string dbdir;
40
static RclMainBase *mainWindow;
74
static RclMainBase *mainWindow;
41
static string recollsharedir;
75
static string recollsharedir;
42
76
43
///////////////////////// 
44
// Global variables for user preferences. These are set in the user preference
45
// dialog and saved restored to the appropriate place in the qt settings
46
bool prefs_showicons;
47
int prefs_respagesize = 8;
48
QString prefs_reslistfontfamily;
49
int prefs_reslistfontsize;
50
QString prefs_queryStemLang;
51
int prefs_mainwidth;
52
int prefs_mainheight;
53
bool prefs_ssall;
54
QString prefs_htmlBrowser;
55
56
#define SETTING_RW(var, nm, tp, def)          \
57
    if (writing) {                    \
58
  settings.writeEntry(nm , var);          \
59
    } else {                      \
60
  var = settings.read##tp##Entry(nm, def);    \
61
    }                     
62
63
static void rwSettings(bool writing)
64
{
65
    if (writing) {
66
  if (!mainWindow) 
67
      return;
68
  prefs_mainwidth = mainWindow->width();
69
  prefs_mainheight = mainWindow->height();
70
  prefs_ssall = mainWindow->sSearch->allTermsCB->isChecked();
71
    }
72
73
    QSettings settings;
74
    settings.setPath("Recoll.org", "Recoll");
75
76
    SETTING_RW(prefs_mainwidth, "/Recoll/geometry/width", Num, 590);
77
    SETTING_RW(prefs_mainheight, "/Recoll/geometry/height", Num, 810);
78
    SETTING_RW(prefs_ssall, "/Recoll/prefs/simpleSearchAll", Bool, false);
79
    SETTING_RW(prefs_showicons, "/Recoll/prefs/reslist/showicons", Bool, true);
80
    SETTING_RW(prefs_respagesize, "/Recoll/prefs/reslist/pagelen", Num, 8);
81
    SETTING_RW(prefs_reslistfontfamily, "/Recoll/prefs/reslist/fontFamily", ,
82
         "");
83
    SETTING_RW(prefs_reslistfontsize, "/Recoll/prefs/reslist/fontSize", Num, 
84
         0);
85
    SETTING_RW(prefs_queryStemLang, "/Recoll/prefs/query/stemLang", ,
86
         "english");
87
}
88
89
bool maybeOpenDb(string &reason)
77
bool maybeOpenDb(string &reason)
90
{
78
{
91
    if (!rcldb) {
79
    if (!rcldb) {
92
    reason = "Internal error: db not created";
80
    reason = "Internal error: db not created";
93
    return false;
81
    return false;
...
...
100
    return true;
88
    return true;
101
}
89
}
102
90
103
static void recollCleanup()
91
static void recollCleanup()
104
{
92
{
93
    if (mainWindow) {
94
  prefs.mainwidth = mainWindow->width();
95
  prefs.mainheight = mainWindow->height();
96
  prefs.ssall = mainWindow->sSearch->allTermsCB->isChecked();
97
    }
105
    rwSettings(true);
98
    rwSettings(true);
106
    stop_idxthread();
99
    stop_idxthread();
107
    delete rcldb;
100
    delete rcldb;
108
    rcldb = 0;
101
    rcldb = 0;
109
    delete rclconfig;
102
    delete rclconfig;
...
...
117
    // thread stuff that we can't do from signal context.
110
    // thread stuff that we can't do from signal context.
118
    // Just set a flag and let the watchdog timer do the work
111
    // Just set a flag and let the watchdog timer do the work
119
    recollNeedsExit = 1;
112
    recollNeedsExit = 1;
120
}
113
}
121
114
115
extern void qInitImages_recoll();
122
116
123
int main( int argc, char ** argv )
117
int main( int argc, char ** argv )
124
{
118
{
125
#ifdef WITH_KDE
119
#ifdef WITH_KDE
126
    KApplication a(argc, argv, "recoll");
120
    KAboutData about("recoll", I18N_NOOP("Recoll"), rclversion, description,
121
                     KAboutData::License_GPL, "(C) 2006 Jean-Francois Dockes", 0, 0, "jean-francois.dockes@wanadoo.fr");
122
    about.addAuthor( "Jean-Francois Dockes", 0, 
123
           "jean-francois.dockes@wanadoo.fr" );
124
    KCmdLineArgs::init(argc, argv, &about);
125
    KCmdLineArgs::addCmdLineOptions( options );
126
    KApplication app;
127
#else
127
#else
128
    QApplication a(argc, argv);
128
    QApplication app(argc, argv);
129
#endif
129
#endif
130
130
131
    // translation file for Qt
131
    // Translation file for Qt
132
    QTranslator qt( 0 );
132
    QTranslator qt( 0 );
133
    qt.load( QString( "qt_" ) + QTextCodec::locale(), "." );
133
    qt.load( QString( "qt_" ) + QTextCodec::locale(), "." );
134
    a.installTranslator( &qt );
134
    app.installTranslator( &qt );
135
135
136
    // Translations for Recoll
136
    // Translations for Recoll
137
    string translatdir = path_cat(recoll_datadir, "translations");
137
    string translatdir = path_cat(recoll_datadir, "translations");
138
    QTranslator translator( 0 );
138
    QTranslator translator( 0 );
139
    // QTextCodec::locale() returns $LANG
139
    // QTextCodec::locale() returns $LANG
140
    translator.load( QString("recoll_") + QTextCodec::locale(), 
140
    translator.load( QString("recoll_") + QTextCodec::locale(), 
141
             translatdir.c_str() );
141
             translatdir.c_str() );
142
    a.installTranslator( &translator );
142
    app.installTranslator( &translator );
143
143
144
    rwSettings(false);
144
    rwSettings(false);
145
145
146
    string reason;
146
    string reason;
147
    rclconfig = recollinit(recollCleanup, sigcleanup, reason);
147
    rclconfig = recollinit(recollCleanup, sigcleanup, reason);
148
    if (!rclconfig || !rclconfig->ok()) {
148
    if (!rclconfig || !rclconfig->ok()) {
149
    QString msg = a.translate("Main", "Configuration problem: ");
149
    QString msg = app.translate("Main", "Configuration problem: ");
150
    msg += reason;
150
    msg += reason;
151
    QMessageBox::critical(0, "Recoll",  msg);
151
    QMessageBox::critical(0, "Recoll",  msg);
152
    exit(1);
152
    exit(1);
153
    }
153
    }
154
154
155
    // Create main window and set its size to previous session's
155
    // Create main window and set its size to previous session's
156
#ifdef WITH_KDE
157
#if 0
158
    if (app.isRestored()) {
159
  RESTORE(RclMain);
160
    } else {
161
#endif
162
        // no session.. just start up normally
163
        KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
164
        /// @todo do something with the command line args here
165
  qInitImages_recoll();
166
        mainWindow = new RclMain;
167
        app.setMainWidget( mainWindow );
168
        mainWindow->show();
169
170
        args->clear();
171
172
  //    }
173
#else
156
    RclMain w;
174
    RclMain w;
157
    mainWindow = &w;
175
    mainWindow = &w;
176
#endif
158
    QSize s(prefs_mainwidth, prefs_mainheight);
177
    QSize s(prefs.mainwidth, prefs.mainheight);
159
    w.resize(s);
178
    mainWindow->resize(s);
160
179
180
161
    w.sSearch->allTermsCB->setChecked(prefs_ssall);
181
    mainWindow->sSearch->allTermsCB->setChecked(prefs.ssall);
162
182
163
    if (rclconfig->getConfParam(string("dbdir"), dbdir) == 0) {
183
    if (rclconfig->getConfParam(string("dbdir"), dbdir) == 0) {
164
    // Note: this will have to be replaced by a call to a
184
    // Note: this will have to be replaced by a call to a
165
    // configuration buildin dialog for initial configuration
185
    // configuration buildin dialog for initial configuration
166
    QMessageBox::critical(0, "Recoll",
186
    QMessageBox::critical(0, "Recoll",
167
                  a.translate("Main", 
187
                  app.translate("Main", 
168
                      "No db directory in configuration"));
188
                      "No db directory in configuration"));
169
    exit(1);
189
    exit(1);
170
    }
190
    }
171
    dbdir = path_tildexpand(dbdir);
191
    dbdir = path_tildexpand(dbdir);
172
192
173
    rcldb = new Rcl::Db;
193
    rcldb = new Rcl::Db;
174
194
175
    // Connect exit handlers etc..
195
    // Connect exit handlers etc..
176
    a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
196
    app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
177
    QTimer *timer = new QTimer(&a);
197
    QTimer *timer = new QTimer(&app);
178
    w.connect(timer, SIGNAL(timeout()), &w, SLOT(periodic100()));
198
    mainWindow->connect(timer, SIGNAL(timeout()), 
199
          mainWindow, SLOT(periodic100()));
179
    timer->start(100);
200
    timer->start(100);
180
201
181
    if (!rcldb->open(dbdir, Rcl::Db::DbRO)) {
202
    if (!rcldb->open(dbdir, Rcl::Db::DbRO)) {
182
    startindexing = 1;
203
    startindexing = 1;
183
    switch (QMessageBox::
204
    switch (QMessageBox::
184
        question(0, "Recoll",
205
        question(0, "Recoll",
185
             a.translate("Main", "Could not open database in ")+
206
             app.translate("Main", "Could not open database in ")+
186
             QString(dbdir) +
207
             QString(dbdir) +
187
             a.translate("Main", 
208
             app.translate("Main", 
188
                     ".\n"
209
                     ".\n"
189
                     "Click Cancel if you want to edit the configuration file before indexation starts, or Ok to let it proceed."),
210
                     "Click Cancel if you want to edit the configuration file before indexation starts, or Ok to let it proceed."),
190
                      "Ok",
211
                      "Ok",
191
                      "Cancel", 0, 0, 1 )) {
212
                      "Cancel", 0, 0, 1 )) {
192
    case 0: // Ok
213
    case 0: // Ok
...
...
194
    case 1: // Cancel
215
    case 1: // Cancel
195
        exit(0);
216
        exit(0);
196
    }
217
    }
197
    }
218
    }
198
219
220
    mainWindow->show();
199
    start_idxthread(*rclconfig);
221
    start_idxthread(*rclconfig);
200
222
201
    // Let's go
223
    // Let's go
202
    w.show();
203
    return a.exec();
224
    return app.exec();
204
}
205
206
const static char *htmlbrowserlist = 
207
    "opera konqueror firefox mozilla netscape";
208
// Search for and launch an html browser for the documentation. If the
209
// user has set a preference, we use it directly instead of guessing.
210
bool startHelpBrowser(const string &iurl)
211
{
212
    string url;
213
    if (iurl.empty()) {
214
  url = path_cat(recoll_datadir, "doc");
215
  url = path_cat(url, "usermanual.html");
216
  url = string("file://") + url;
217
    } else
218
  url = iurl;
219
220
221
    // If the user set a preference with an absolute path then things are
222
    // simple
223
    if (!prefs_htmlBrowser.isEmpty() && prefs_htmlBrowser.find('/') != -1) {
224
  if (access(prefs_htmlBrowser.ascii(), X_OK) != 0) {
225
      LOGERR(("startHelpBrowser: %s not found or not executable\n",
226
          prefs_htmlBrowser.ascii()));
227
  }
225
}
228
  string cmd = string(prefs_htmlBrowser.ascii()) + " " + url + "&";
229
  if (system(cmd.c_str()) == 0)
230
      return true;
231
  else 
232
      return false;
233
    }
234
226
235
    string searched;
236
    if (prefs_htmlBrowser.isEmpty()) {
237
  searched = htmlbrowserlist;
238
    } else {
239
  searched = prefs_htmlBrowser.ascii();
240
    }
241
    list<string> blist;
242
    stringToTokens(searched, blist, " ");
243
244
    const char *path = getenv("PATH");
245
    if (path == 0)
246
  path = "/bin:/usr/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/local/bin";
247
248
    list<string> pathl;
249
    stringToTokens(path, pathl, ":");
250
    
251
    // For each browser name, search path and exec/stop if found
252
    for (list<string>::const_iterator bit = blist.begin(); 
253
   bit != blist.end(); bit++) {
254
  for (list<string>::const_iterator pit = pathl.begin(); 
255
       pit != pathl.end(); pit++) {
256
      string exefile = path_cat(*pit, *bit);
257
      LOGDEB1(("startHelpBrowser: trying %s\n", exefile.c_str()));
258
      if (access(exefile.c_str(), X_OK) == 0) {
259
      string cmd = exefile + " " + url + "&";
260
      if (system(cmd.c_str()) == 0) {
261
          return true;
262
      }
263
      }
264
  }
265
    }
266
267
    LOGERR(("startHelpBrowser: no html browser found. Looked for: %s\n", 
268
      searched.c_str()));
269
    return false;
270
}