Release 0.4.3-3maemo with patches to disable menus/actions, add ScrollArea and fix...
[keepassx] / src / main.cpp
1 /***************************************************************************
2  *   Copyright (C) 1992-2007 Trolltech ASA                                                                 *
3  *                                                                         *
4  *   Copyright (C) 2005-2007 by Tarek Saidi                                *
5  *   tarek.saidi@arcor.de                                                  *
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General Public License as published by  *
9  *   the Free Software Foundation; version 2 of the License.               *
10  *                                                                         *
11  *   This program 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 this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20  ***************************************************************************/
21
22 #include "main.h"
23 #include "mainwindow.h"
24 #if defined(Q_WS_X11) && defined(GLOBAL_AUTOTYPE)
25         #include "Application_X11.h"
26 #endif
27
28 #include "plugins/interfaces/IFileDialog.h"
29 #include "plugins/interfaces/IKdeInit.h"
30 #include "plugins/interfaces/IGnomeInit.h"
31
32 //#include <QPluginLoader>
33 #include <iostream>
34
35 using namespace std;
36
37 KpxConfig *config;
38 QString  AppDir;
39 QString HomeDir;
40 QString DataDir;
41 QString PluginLoadError;
42 QString DetailViewTemplate;
43 bool EventOccurred;
44 bool EventOccurredBlock = false;
45
46 QPixmap* EntryIcons;
47 IIconTheme* IconLoader=NULL;
48
49
50 int main(int argc, char **argv)
51 {
52         setlocale(LC_CTYPE, "");
53         
54 #if defined(Q_WS_X11) && defined(AUTOTYPE)
55         QApplication* app = new KeepassApplication(argc,argv);
56 #else
57         QApplication* app = new QApplication(argc,argv);
58 #endif
59         EventListener* eventListener = new EventListener();
60         app->installEventFilter(eventListener);
61         
62         QApplication::setQuitOnLastWindowClosed(false);
63         
64         AppDir = QApplication::applicationFilePath();
65         AppDir.truncate(AppDir.lastIndexOf("/"));
66 #if defined(Q_WS_X11)
67         DataDir = AppDir+"/../share/keepassx";
68         if (!QFile::exists(DataDir) && QFile::exists(AppDir+"/share"))
69                 DataDir = AppDir+"/share";
70         const char* env = getenv("XDG_CONFIG_HOME");
71         if (!env) {
72                 HomeDir = QDir::homePath() + "/.config";
73         }
74         else {
75                 QString qenv = QTextCodec::codecForLocale()->toUnicode(env);
76                 if (qenv[0] == '/')
77                         HomeDir = qenv;
78                 else
79                         HomeDir = QDir::homePath() + '/' + qenv;
80         }
81         HomeDir += "/keepassx";
82 #elif defined(Q_WS_MAC)
83         HomeDir = QDir::homePath()+"/.keepassx";
84         DataDir = AppDir+"/../Resources/keepassx";
85 #else //Q_WS_WIN
86         HomeDir = qtWindowsConfigPath(CSIDL_APPDATA);
87         if(!HomeDir.isEmpty() && QFile::exists(HomeDir))
88                 HomeDir = QDir::fromNativeSeparators(HomeDir)+"/KeePassX";
89         else
90                 HomeDir = QDir::homePath()+"/KeePassX";
91         
92         DataDir = AppDir+"/share";
93 #endif
94         DataDir = QDir::cleanPath(DataDir);
95         
96         CmdLineArgs args;
97         if ( !args.parse(QApplication::arguments()) ){
98                 qCritical("%s\n", CSTR( args.error() ));
99                 args.printHelp();
100                 return 1;
101         }
102         if (args.help()){
103                 args.printHelp();
104                 return 1;
105         }
106
107         //Load Config
108         QString IniFilename;
109         if(args.configLocation().isEmpty()){
110                 if(!QDir(HomeDir).exists()){
111                         QDir conf(QDir::homePath());
112                         if(!QDir().mkpath(HomeDir))
113                                 qWarning("Warning: Could not create directory '%s'", CSTR(HomeDir));
114                 }
115                 IniFilename=HomeDir+"/config.ini";
116         }
117         else
118                 IniFilename=args.configLocation();
119
120 #ifdef Q_WS_X11
121         {
122                 QString OldHomeDir = QDir::homePath()+"/.keepassx";
123                 if (args.configLocation().isEmpty() && QFile::exists(OldHomeDir+"/config") && !QFile::exists(HomeDir+"/config")) {
124                         QFile::rename(OldHomeDir+"/config", HomeDir+"/config.ini");
125                         if (QDir(OldHomeDir).entryList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Hidden|QDir::System).count()==0)
126                                 QDir().rmdir(OldHomeDir);
127                 }
128         }
129 #else
130         if (args.configLocation().isEmpty() && QFile::exists(HomeDir+"/config") && !QFile::exists(HomeDir+"/config.ini"))
131                 QFile::rename(HomeDir+"/config", HomeDir+"/config.ini");
132 #endif
133         config = new KpxConfig(IniFilename);
134         fileDlgHistory.load();
135         
136         // PlugIns
137         /*
138 #ifdef Q_WS_X11
139         if(config->integrPlugin()!=KpxConfig::NoIntegr){
140                 QString LibName="libkeepassx-";
141                 if(config->integrPlugin()==KpxConfig::KDE)
142                         LibName+="kde.so";
143                 else if(config->integrPlugin()==KpxConfig::Gnome)
144                         LibName+="gnome.so";
145                 QString filename=findPlugin(LibName);
146                 if(filename!=QString()){
147                         QPluginLoader plugin(filename);
148                         if(!plugin.load()){
149                                 PluginLoadError=plugin.errorString();
150                                 qWarning("Could not load desktop integration plugin:");
151                                 qWarning("%s", CSTR(PluginLoadError));
152                         }
153                         else{
154                                 QObject *plugininstance=plugin.instance();
155                                 IFileDialog* fdlg=qobject_cast<IFileDialog*>(plugininstance);
156                                 IconLoader=qobject_cast<IIconTheme*>(plugininstance);
157                                 if(IconLoader==NULL){
158                                         qWarning("Error: Integration Plugin: Could not initialize IconTheme interface.");
159                                 }
160                                 KpxFileDialogs::setPlugin(fdlg);
161                                 if(config->integrPlugin()==KpxConfig::KDE){
162                                         IKdeInit* kdeinit=qobject_cast<IKdeInit*>(plugin.instance());
163                                         app=kdeinit->getMainAppObject(argc,argv);
164                                         if(!app) PluginLoadError = "Initialization failed.";
165                                 }
166                                 if(config->integrPlugin()==KpxConfig::Gnome){
167                                         IGnomeInit* ginit=qobject_cast<IGnomeInit*>(plugin.instance());
168                                         if(!ginit->init(argc,argv)){
169                                                 KpxFileDialogs::setPlugin(NULL);
170                                                 qWarning("GtkIntegrPlugin: Gtk init failed.");
171                                                 PluginLoadError = "Initialization failed.";
172                                         }
173                                 }
174                         }
175                 }
176                 else{
177                         qWarning(CSTR(QString("Could not load desktop integration plugin: File '%1' not found.").arg(LibName)));
178                         PluginLoadError=QApplication::translate("Main", "Could not locate library file.");
179                 }
180         }
181 #endif
182         */
183         
184         DetailViewTemplate=config->detailViewTemplate();
185
186         loadImages();
187         KpxBookmarks::load();
188         initYarrow(); //init random number generator
189         SecString::generateSessionKey();
190         
191         installTranslator();
192
193 #ifdef Q_WS_MAC
194         QApplication::processEvents();
195         if (args.file().isEmpty() && !eventListener->file().isEmpty()) {
196                 args.setFile(eventListener->file());
197         }
198 #endif
199
200         KeepassMainWindow *mainWin = new KeepassMainWindow(args.file(), args.startMinimized(), args.startLocked());
201 #ifdef Q_WS_MAC
202         eventListener->setMainWin(mainWin);
203 #endif
204
205         int r=app->exec();
206         delete mainWin;
207         delete eventListener;
208
209         fileDlgHistory.save();
210         SecString::deleteSessionKey();
211         delete app;
212         delete config;
213         return r;
214 }
215
216
217 ///TODO 0.2.3 remove
218 void loadImages(){
219         QPixmap tmpImg(getImageFile("clientic.png"));
220         EntryIcons=new QPixmap[BUILTIN_ICONS];
221         for(int i=0;i<BUILTIN_ICONS;i++){
222                 EntryIcons[i]=tmpImg.copy(i*16,0,16,16);
223         }
224 }
225
226
227
228
229
230 CmdLineArgs::CmdLineArgs(){
231         StartMinimized=false;
232         StartLocked=false;
233         Help=false;
234 }
235
236 bool CmdLineArgs::parse(const QStringList& argv){
237         for(int i=1;i<argv.size();i++){
238                 if(argv[i]=="-help" || argv[i]=="--help" || argv[i]=="-h"){
239                         Help=true;
240                         break; // break, because other arguments will be ignored anyway
241                 }
242                 if(argv[i]=="-cfg"){
243                         if(argv.size() == i+1){
244                                 Error="Missing argument for '-cfg'.";
245                                 return false;
246                         }
247                         if(argv[i+1].left(1)=="-"){
248                                 Error=QString("Expected a path as argument for '-cfg' but got '%1.'").arg(argv[i+1]);
249                                 return false;
250                         }
251                         QFileInfo file(argv[i+1]);
252                         ConfigLocation=file.absoluteFilePath();
253                         i++;
254                         continue;
255                 }
256                 if(argv[i]=="-min"){
257                         StartMinimized=true;
258                         continue;
259                 }
260                 if(argv[i]=="-lock"){
261                         StartLocked=true;
262                         continue;
263                 }
264                 if(i==1 && argv[i].left(1)!="-"){
265                         File=argv[1];
266                         continue;
267                 }
268                 Error=QString("** Unrecognized argument: '%1'").arg(argv[i]);
269                 return false;
270         }
271         return true;
272 }
273
274 void CmdLineArgs::printHelp(){
275         cerr << "KeePassX " << APP_VERSION << endl;
276         cerr << "Usage: keepassx [filename] [options]" << endl;
277         cerr << "  -help             This Help" << endl;
278         cerr << "  -cfg <CONFIG>     Use specified file for loading/saving the configuration." << endl;
279         cerr << "  -min              Start minimized." << endl;
280         cerr << "  -lock             Start locked." << endl;
281 }
282
283
284 /*QString findPlugin(const QString& filename){
285         QFileInfo info; 
286         info.setFile(AppDir+"/../lib/"+filename);
287         if(info.exists() && info.isFile())
288                 return AppDir+"/../lib/"+filename;      
289         return QString();
290 }*/
291
292
293 bool EventListener::eventFilter(QObject*, QEvent* event){
294         if (!EventOccurred){
295                 int t = event->type();
296                 if ( (t>=QEvent::MouseButtonPress && t<=QEvent::KeyRelease) || (t>=QEvent::HoverEnter && t<=QEvent::HoverMove) )
297                         EventOccurred = true;
298         }
299         
300 #ifdef Q_WS_MAC
301         if (event->type() == QEvent::FileOpen) {
302                 QString filename = static_cast<QFileOpenEvent*>(event)->file();
303                 if (pMainWindow) {
304                         if (QApplication::activeModalWidget() == NULL)
305                                 pMainWindow->openFile(filename);
306                         else
307                                 return true; // ignore file open events while a modal dialog is displayed
308                 }
309                 else {
310                         pFile = filename;
311                 }
312         }
313 #endif
314         
315         return false;
316 }