You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
			
		
		
		
		
			
		
			
				
					
					
						
							480 lines
						
					
					
						
							16 KiB
						
					
					
				
			
		
		
	
	
							480 lines
						
					
					
						
							16 KiB
						
					
					
				| /***************************************************************************
 | |
|  *   Copyright (C) 2005-2007 by Tarek Saidi                                *
 | |
|  *   tarek.saidi@arcor.de                                                  *
 | |
|  *                                                                         *
 | |
|  *   This program is free software; you can redistribute it and/or modify  *
 | |
|  *   it under the terms of the GNU General Public License as published by  *
 | |
|  *   the Free Software Foundation; either version 2 of the License, or     *
 | |
|  *   (at your option) any later version.                                   *
 | |
|  *                                                                         *
 | |
|  *   This program is distributed in the hope that it will be useful,       *
 | |
|  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 | |
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 | |
|  *   GNU General Public License for more details.                          *
 | |
|  *                                                                         *
 | |
|  *   You should have received a copy of the GNU General Public License     *
 | |
|  *   along with this program; if not, write to the                         *
 | |
|  *   Free Software Foundation, Inc.,                                       *
 | |
|  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 | |
|  ***************************************************************************/
 | |
| 
 | |
| #include <iostream>
 | |
| #include <qapplication.h>
 | |
| #include <qlibrary.h>
 | |
| #include <qlocale.h>
 | |
| #include <qdir.h>
 | |
| #include <QMessageBox>
 | |
| #include <QTranslator>
 | |
| #include <QPainter>
 | |
| #include <QImage>
 | |
| #include <QStyleFactory>
 | |
| #include <QProcess>
 | |
| #include <QLibraryInfo>
 | |
| #include <QPluginLoader>
 | |
| #include <QDesktopServices>
 | |
| #include <QUrl>
 | |
| 
 | |
| #include "plugins/interfaces/IFileDialog.h"
 | |
| #include "plugins/interfaces/IKdeInit.h"
 | |
| #include "plugins/interfaces/IGnomeInit.h"
 | |
| #include "plugins/interfaces/IIconTheme.h"
 | |
| #include "lib/FileDialogs.h"
 | |
| 
 | |
| #include "main.h"
 | |
| #include "lib/FileDialogs.h"
 | |
| #include "KpxConfig.h"
 | |
| #include "Kdb3Database.h"
 | |
| #include "mainwindow.h"
 | |
| #include "crypto/yarrow.h"
 | |
| using namespace std;
 | |
| 
 | |
| #ifdef Q_WS_X11
 | |
| 	#include <X11/extensions/XTest.h>
 | |
| 	#define XK_LATIN1
 | |
| 	#define XK_MISCELLANY
 | |
| 	#define XK_XKB_KEYS
 | |
| 	#include <X11/keysymdef.h>
 | |
| 	#include <X11/Xlib.h>
 | |
| #endif
 | |
| 
 | |
| #define CSTR(x)(x.toUtf8().data())
 | |
| 
 | |
| QHash<QString,QPixmap*>PixmapCache;
 | |
| QHash<QString,QIcon*>IconCache;
 | |
| 
 | |
| KpxConfig *config;
 | |
| QString  AppDir;
 | |
| QString PluginLoadError;
 | |
| bool TrActive;
 | |
| QString DetailViewTemplate;
 | |
| 
 | |
| QPixmap* EntryIcons;
 | |
| IIconTheme* IconLoader=NULL;
 | |
| 
 | |
| inline void loadImages();
 | |
| inline void parseCmdLineArgs(int argc, char** argv,QString &ArgFile,QString& ArgCfg,QString& ArgLang);
 | |
| bool loadTranslation(QTranslator* tr,const QString& prefix,const QString& LocaleCode,const QStringList& SearchPaths);
 | |
| 
 | |
| void test_getAllWindowTitles(){
 | |
| 	#ifdef Q_WS_X11
 | |
| 	Display* pDisplay = XOpenDisplay( NULL );
 | |
| 	Window r,p;
 | |
| 	Window* c;
 | |
| 	unsigned int num_ch=0;
 | |
| 	XQueryTree(pDisplay,DefaultRootWindow(pDisplay),&r,&p,&c,&num_ch);
 | |
| 	qDebug("%u",num_ch);
 | |
| 	for(int i=0;i<num_ch;i++){
 | |
| 		int num_prop=0;
 | |
| 		Atom* atom=XListProperties(pDisplay,c[i],&num_prop);
 | |
| 		for(int p=0;p<num_prop;p++){
 | |
| 			qDebug("%i %i: %s",i,p,XGetAtomName(pDisplay,atom[p]));
 | |
| 		}
 | |
| 		XFree(atom);
 | |
| 		
 | |
| 	}
 | |
| 	#endif	
 | |
| }
 | |
| 
 | |
| int main(int argc, char **argv)
 | |
| {
 | |
| 	//test_getAllWindowTitles();
 | |
| 	//exit(0);
 | |
| 	QString ArgFile,ArgCfg,ArgLang,IniFilename;
 | |
| 	QApplication* app=NULL;
 | |
| 	AppDir=QString(argv[0]);
 | |
| 	AppDir.truncate(AppDir.lastIndexOf("/"));
 | |
| 	parseCmdLineArgs(argc,argv,ArgFile,ArgCfg,ArgLang);
 | |
| 
 | |
| 	//Load Config
 | |
| 	if(ArgCfg.isEmpty()){
 | |
| 		if(!QDir(QDir::homePath()+"/.keepassx").exists()){
 | |
| 			QDir conf(QDir::homePath());
 | |
| 			if(!conf.mkdir(".keepassx")){
 | |
| 				cout << "Warning: Could not create directory '~/.keepassx'." << endl;}
 | |
| 		}
 | |
| 		IniFilename=QDir::homePath()+"/.keepassx/config";
 | |
| 	}
 | |
| 	else
 | |
| 		IniFilename=ArgCfg;
 | |
| 
 | |
| 
 | |
| 	config = new KpxConfig(IniFilename);
 | |
| 	fileDlgHistory.load();
 | |
| 
 | |
| 	//Plugins
 | |
| 	if(config->integrPlugin()!=KpxConfig::NoIntegr){
 | |
| 		QString LibName="libkeepassx-";
 | |
| 		if(config->integrPlugin()==KpxConfig::KDE)
 | |
| 			LibName+="kde.so";
 | |
| 		else if(config->integrPlugin()==KpxConfig::Gnome)
 | |
| 			LibName+="gnome.so";
 | |
| 		QString filename=findPlugin(LibName);
 | |
| 		if(filename!=QString()){
 | |
| 			QPluginLoader plugin(filename);
 | |
| 			if(!plugin.load()){
 | |
| 				PluginLoadError=plugin.errorString();
 | |
| 				qWarning("Could not load desktop integration plugin:");
 | |
| 				qWarning(CSTR(PluginLoadError));
 | |
| 			}
 | |
| 			else{	
 | |
| 				QObject *plugininstance=plugin.instance();
 | |
| 				IFileDialog* fdlg=qobject_cast<IFileDialog*>(plugininstance);
 | |
| 				IconLoader=qobject_cast<IIconTheme*>(plugininstance);
 | |
| 				if(IconLoader==NULL){
 | |
| 					qWarning("Error: Integration Plugin: Could not initialize IconTheme interface."); 
 | |
| 				}
 | |
| 				KpxFileDialogs::setPlugin(fdlg);
 | |
| 				if(config->integrPlugin()==KpxConfig::KDE){
 | |
| 					IKdeInit* kdeinit=qobject_cast<IKdeInit*>(plugin.instance());
 | |
| 					app=kdeinit->getMainAppObject(argc,argv);
 | |
| 					if(!app)PluginLoadError=QObject::tr("Initialization failed.");
 | |
| 				}
 | |
| 				if(config->integrPlugin()==KpxConfig::Gnome){
 | |
| 					IGnomeInit* ginit=qobject_cast<IGnomeInit*>(plugin.instance());
 | |
| 					if(!ginit->init(argc,argv)){
 | |
| 						KpxFileDialogs::setPlugin(NULL);
 | |
| 						qWarning("GtkIntegrPlugin: Gtk init failed.");
 | |
| 						PluginLoadError=QObject::tr("Initialization failed.");
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		else{
 | |
| 			qWarning(CSTR(QString("Could not load desktop integration plugin: File '%1' not found.").arg(LibName)));
 | |
| 			PluginLoadError=QObject::tr("Could not locate library file.");
 | |
| 		}
 | |
| 	}
 | |
| 	if(!app) QApplication* app=new QApplication(argc,argv);
 | |
| 
 | |
| 
 | |
| 	//Internationalization
 | |
| 	QLocale loc;
 | |
| 	if(!ArgLang.size())
 | |
| 		loc=QLocale::system();
 | |
| 	else
 | |
| 		loc=QLocale(ArgLang);
 | |
| 
 | |
| 	QTranslator* translator = NULL;
 | |
| 	QTranslator* qtTranslator=NULL;
 | |
| 	translator=new QTranslator;
 | |
| 	qtTranslator=new QTranslator;
 | |
| 
 | |
| 	if(loadTranslation(translator,"keepass-",loc.name(),QStringList()
 | |
| 						<< app->applicationDirPath()+"/../share/keepass/i18n/"
 | |
| 						<< QDir::homePath()+"/.keepassx/" ))
 | |
| 		{app->installTranslator(translator);
 | |
| 		TrActive=true;}
 | |
| 	else{
 | |
| 		if(loc.name()!="en_US")
 | |
| 		qWarning(QString("Kpx: No Translation found for '%1 (%2)'using 'English (UnitedStates)'")
 | |
| 				.arg(QLocale::languageToString(loc.language()))
 | |
| 				.arg(QLocale::countryToString(loc.country())).toAscii());
 | |
| 		delete translator;
 | |
| 		TrActive=false;
 | |
| 	}
 | |
| 
 | |
| 	if(loadTranslation(qtTranslator,"qt_",loc.name(),QStringList()
 | |
| 						<< QLibraryInfo::location(QLibraryInfo::TranslationsPath)
 | |
| 						<< app->applicationDirPath()+"/../share/keepass/i18n/"
 | |
| 						<< QDir::homePath()+"/.keepass/" ))
 | |
| 		app->installTranslator(qtTranslator);
 | |
| 	else{
 | |
| 		if(loc.name()!="en_US")
 | |
| 		qWarning(QString("Qt: No Translation found for '%1 (%2)'using 'English (UnitedStates)'")
 | |
| 				.arg(QLocale::languageToString(loc.language()))
 | |
| 				.arg(QLocale::countryToString(loc.country())).toAscii());
 | |
| 		delete qtTranslator;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	QFile templ(QDir::homePath()+"/.keepassx/detailview-template.html"); ///FIXME ArgCfg
 | |
| 	if(templ.open(QIODevice::ReadOnly)){
 | |
| 		DetailViewTemplate=QString::fromUtf8(templ.readAll());
 | |
| 		templ.close();
 | |
| 	}
 | |
| 	else loadDefaultDetailViewTemplate();
 | |
| 
 | |
| 	loadImages();
 | |
| 	initYarrow(); //init random number generator
 | |
| 	SecString::generateSessionKey();
 | |
| 
 | |
| 	int r=0;
 | |
| 	KeepassMainWindow *mainWin = new KeepassMainWindow(ArgFile);
 | |
| 	if(mainWin->Start){
 | |
| 		mainWin->show();
 | |
| 		r=app->exec();
 | |
| 	}
 | |
| 	delete mainWin;
 | |
| 
 | |
| 	if(templ.open(QIODevice::WriteOnly)){
 | |
| 		templ.write(DetailViewTemplate.toUtf8());
 | |
| 		templ.close();
 | |
| 	}
 | |
| 	else{
 | |
| 		qWarning("Failed to save detail view template: %s",decodeFileError(templ.error()).toUtf8().data());
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	fileDlgHistory.save();
 | |
| 	delete app;
 | |
| 	delete config;
 | |
| 	return r;
 | |
| }
 | |
| 
 | |
| 
 | |
| void loadDefaultDetailViewTemplate(){
 | |
| 		QFile templ(":/default-detailview.html");
 | |
| 		templ.open(QIODevice::ReadOnly);
 | |
| 		DetailViewTemplate=QString::fromUtf8(templ.readAll());
 | |
| 		templ.close();
 | |
| 		DetailViewTemplate.replace("Group",QCoreApplication::translate("DetailViewTemplate","Group"));
 | |
| 		DetailViewTemplate.replace("Title",QCoreApplication::translate("DetailViewTemplate","Title"));
 | |
| 		DetailViewTemplate.replace("Username",QCoreApplication::translate("DetailViewTemplate","Username"));
 | |
| 		DetailViewTemplate.replace("Password",QCoreApplication::translate("DetailViewTemplate","Password"));
 | |
| 		DetailViewTemplate.replace("URL",QCoreApplication::translate("DetailViewTemplate","URL"));
 | |
| 		DetailViewTemplate.replace("Creation",QCoreApplication::translate("DetailViewTemplate","Creation"));
 | |
| 		DetailViewTemplate.replace("Last Access",QCoreApplication::translate("DetailViewTemplate","Last Access"));
 | |
| 		DetailViewTemplate.replace("Last Modification",QCoreApplication::translate("DetailViewTemplate","Last Modification"));
 | |
| 		DetailViewTemplate.replace("Expiration",QCoreApplication::translate("DetailViewTemplate","Expiration"));
 | |
| 		DetailViewTemplate.replace("Comment",QCoreApplication::translate("DetailViewTemplate","Comment"));
 | |
| }
 | |
| 
 | |
| //obsolete
 | |
| void createBanner(QLabel *Banner,const QPixmap* symbol,QString text){
 | |
| 	QPixmap Pixmap;
 | |
| 	createBanner(&Pixmap,symbol,text
 | |
| 				   ,Banner->width()
 | |
| 				   ,config->bannerColor1()
 | |
| 			       ,config->bannerColor2()
 | |
| 			       ,config->bannerTextColor());
 | |
| 	Banner->setPixmap(Pixmap);
 | |
| }
 | |
| 
 | |
| void createBanner(QPixmap* Pixmap,const QPixmap* IconAlpha,const QString& Text,int Width){
 | |
| 	createBanner(Pixmap,IconAlpha,Text,Width,config->bannerColor1(),config->bannerColor2(),config->bannerTextColor());
 | |
| }
 | |
| 
 | |
| void createBanner(QPixmap* Pixmap,const QPixmap* IconAlpha,const QString& Text,int Width, QColor Color1, QColor Color2, QColor TextColor){
 | |
| 	*Pixmap=QPixmap(Width,50);
 | |
| 	QPainter painter(Pixmap);
 | |
| 	QLinearGradient grad(0,0,Width,0);
 | |
| 	grad.setColorAt(0,Color1);
 | |
| 	grad.setColorAt(1,Color2);
 | |
| 	painter.setPen(Qt::NoPen);
 | |
| 	painter.setBrush(grad);
 | |
| 	painter.drawRect(0,0,Width,50);
 | |
| 
 | |
| 	QPixmap Icon(32,32);
 | |
| 	if(IconAlpha){
 | |
| 		Icon.fill(TextColor);
 | |
| 		Icon.setAlphaChannel(*IconAlpha);
 | |
| 		painter.drawPixmap(10,10,Icon);
 | |
| 	}
 | |
| 
 | |
| 	painter.setPen(QPen(TextColor));
 | |
| 	painter.setFont(QFont(QApplication::font().family(),16));
 | |
| 	painter.drawText(50,35,Text);
 | |
| }
 | |
| 
 | |
| QString decodeFileError(QFile::FileError Code){
 | |
| 	switch(Code){
 | |
| 		case QFile::NoError: return QApplication::translate("FileErrors","No error occurred.");
 | |
| 		case QFile::ReadError: return QApplication::translate("FileErrors","An error occurred while reading from the file.");
 | |
| 		case QFile::WriteError: return QApplication::translate("FileErrors","An error occurred while writing to the file.");
 | |
| 		case QFile::FatalError: return QApplication::translate("FileErrors","A fatal error occurred.");
 | |
| 		case QFile::ResourceError: return QApplication::translate("FileErrors","An resource error occurred.");
 | |
| 		case QFile::OpenError: return QApplication::translate("FileErrors","The file could not be opened.");
 | |
| 		case QFile::AbortError: return QApplication::translate("FileErrors","The operation was aborted.");
 | |
| 		case QFile::TimeOutError: return QApplication::translate("FileErrors","A timeout occurred.");
 | |
| 		case QFile::UnspecifiedError: return QApplication::translate("FileErrors","An unspecified error occurred.");
 | |
| 		case QFile::RemoveError: return QApplication::translate("FileErrors","The file could not be removed.");
 | |
| 		case QFile::RenameError: return QApplication::translate("FileErrors","The file could not be renamed.");
 | |
| 		case QFile::PositionError: return QApplication::translate("FileErrors","The position in the file could not be changed.");
 | |
| 		case QFile::ResizeError: return QApplication::translate("FileErrors","The file could not be resized.");
 | |
| 		case QFile::PermissionsError: return QApplication::translate("FileErrors","The file could not be accessed.");
 | |
| 		case QFile::CopyError: return QApplication::translate("FileErrors","The file could not be copied.");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void openBrowser(QString UrlString){
 | |
| 	QUrl url(UrlString);
 | |
| 	if(url.scheme().isEmpty())
 | |
| 		url=QUrl("http://"+UrlString);
 | |
| 	if(config->urlCmd().isEmpty()){
 | |
| 		QDesktopServices::openUrl(url);
 | |
| 	}
 | |
| 	else{
 | |
| 		QStringList args=config->urlCmd().arg(url.toString()).split(' ');
 | |
| 		QString cmd=args.takeFirst();
 | |
| 		QProcess::startDetached(cmd,args);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| ///TODO 0.2.3 remove
 | |
| void loadImg(QString name,QPixmap& Img){
 | |
| if(Img.load(AppDir+"/../share/keepass/icons/"+name)==false){
 | |
|  if(Img.load(AppDir+"/share/"+name)==false){
 | |
|  QMessageBox::critical(0,QObject::tr("Error"),QObject::tr("File '%1' could not be found.")
 | |
| 				   .arg(name),QObject::tr("OK"),0,0,2,1);
 | |
|  exit(1);
 | |
| }}
 | |
| 
 | |
| }
 | |
| 
 | |
| ///TODO 0.2.3 remove
 | |
| void loadImages(){
 | |
| 	bool small=true;
 | |
| 	QString ThemeDir=AppDir+"/../share/keepass/icons/nuvola/32x32";
 | |
| 	QPixmap tmpImg;
 | |
| 	loadImg("clientic.png",tmpImg);
 | |
| 	EntryIcons=new QPixmap[BUILTIN_ICONS];
 | |
| 	for(int i=0;i<BUILTIN_ICONS;i++){
 | |
| 	EntryIcons[i]=tmpImg.copy(i*16,0,16,16);}
 | |
| 
 | |
| }
 | |
| 
 | |
| const QIcon& getIcon(const QString& name){
 | |
| 	QIcon* CachedIcon=IconCache.value(name);
 | |
| 	if(CachedIcon)
 | |
| 		return *CachedIcon;
 | |
| 	QIcon* NewIcon=NULL;
 | |
| 	if(IconLoader){
 | |
| 		NewIcon=new QIcon(IconLoader->getIcon(name));
 | |
| 		if(NewIcon->isNull()){
 | |
| 			delete NewIcon;
 | |
| 			NewIcon=NULL;	
 | |
| 		}
 | |
| 		else
 | |
| 			IconCache.insert(name,NewIcon);
 | |
| 	}
 | |
| 	if(!NewIcon)
 | |
| 	{
 | |
| 		QFileInfo IconFile(AppDir+"/../share/keepass/icons/"+name+".png");
 | |
| 		if(!IconFile.isFile() || !IconFile.exists() || !IconFile.isReadable()){
 | |
| 			///TODO 0.2.3 error handling
 | |
| 			qWarning("%s",CSTR(name));
 | |
| 		}
 | |
| 		NewIcon=new QIcon(AppDir+"/../share/keepass/icons/"+name+".png");
 | |
| 		IconCache.insert(name,NewIcon);
 | |
| 	} 
 | |
| 	return *NewIcon;
 | |
| }
 | |
| 
 | |
| const QPixmap* getPixmap(const QString& name){
 | |
| 	QPixmap* CachedPixmap=PixmapCache.value(name);
 | |
| 	if(CachedPixmap)
 | |
| 		return CachedPixmap;
 | |
| 	QImage img;
 | |
| 	if(!img.load(AppDir+"/../share/keepass/icons/"+name+".png")){
 | |
| 		///TODO 0.2.3 error handling
 | |
| 		qWarning("%s",CSTR(name));
 | |
| 	}
 | |
| 	QPixmap* NewPixmap=new QPixmap(QPixmap::fromImage(img));
 | |
| 	PixmapCache.insert(name,NewPixmap);
 | |
| 	return NewPixmap;
 | |
| }
 | |
| 
 | |
| 
 | |
| bool loadTranslation(QTranslator* tr,const QString& prefix,const QString& loc,const QStringList& paths){
 | |
| for(int i=0;i<paths.size();i++)
 | |
| 	if(tr->load(prefix+loc+".qm",paths[i])) return true;
 | |
| for(int i=0;i<paths.size();i++){
 | |
| 	QDir dir(paths[i]);
 | |
| 	QStringList TrFiles=dir.entryList(QStringList()<<"*.qm",QDir::Files);
 | |
| 	for(int j=0;j<TrFiles.size();j++){
 | |
| 		if(TrFiles[j].left(prefix.length()+2)==prefix+loc.left(2)){
 | |
| 			if(tr->load(TrFiles[j],paths[i]))return true;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| return false;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| void parseCmdLineArgs(int argc, char** argv,QString &ArgFile,QString& ArgCfg,QString& ArgLang){
 | |
| if(argc>1){
 | |
| int i=1;
 | |
| 	if(argv[i][0]!='-'){
 | |
| 		ArgFile=QString::fromUtf8(argv[i]);
 | |
| 		i++; }
 | |
| 	for(i; i<argc;i++){
 | |
| 		if(QString(argv[i])=="-help"){
 | |
| 			cout << "KeePassX" << KEEPASS_VERSION << endl;
 | |
| 			cout << "Usage: keepass [Filename] [Options]" << endl;
 | |
| 			cout << "  -help             This Help" << endl;
 | |
| 			cout << "  -cfg <CONFIG>     Use specified file for loading/saving the configuration." << endl;
 | |
| 			cout << "  -lang <LOCALE>    Use specified language instead of systems default." << endl;
 | |
| 			cout << "                    <LOCALE> is the ISO-639 language code with or without ISO-3166 country code" << endl;
 | |
| 			cout << "                    Examples: de     German" << endl;
 | |
| 			cout << "                              de_CH  German(Switzerland)"<<endl;
 | |
| 			cout << "                              pt_BR  Portuguese(Brazil)"<<endl;
 | |
| 			exit(0);
 | |
| 			}
 | |
| 		else if(QString(argv[i])=="-cfg"){
 | |
| 			if(i-1==argc){ cout << "Missing argument for -cfg" << endl; exit(1);}
 | |
| 			else{ArgCfg=QString::fromUtf8(argv[i+1]); i++;}
 | |
| 			}
 | |
| 		else if(QString(argv[i])=="-lang"){
 | |
| 			if(i-1==argc) cout << "Missing argument for -lang" << endl;
 | |
| 			else{ArgLang=QString::fromUtf8(argv[i+1]); i++;}
 | |
| 			}
 | |
| 			else if(QString(argv[i])=="-test"){/*
 | |
| 				if (testDatabase()) exit(0);
 | |
| 				else exit(1);*/
 | |
| 			}
 | |
| 		else{cout << "** Unrecognized argument: " << argv[i] <<  endl;
 | |
| 			exit(1);}
 | |
| 	}
 | |
|    }
 | |
| }
 | |
| 
 | |
| void showErrMsg(const QString& msg,QWidget* parent){
 | |
| QMessageBox::critical(parent,QObject::tr("Error"),msg,QObject::tr("OK"));
 | |
| }
 | |
| 
 | |
| QString findPlugin(const QString& filename){
 | |
| 	QFileInfo info;
 | |
| 
 | |
| 	info.setFile(AppDir+"/../lib/"+filename);
 | |
| 	if(info.exists() && info.isFile())
 | |
| 		return AppDir+"/../lib/"+filename;
 | |
| 
 | |
| 	return QString();
 | |
| }
 | |
| 
 | |
| 
 | |
| QString makePathRelative(const QString& AbsDir,const QString& CurDir){
 | |
| 	QStringList abs=AbsDir.split('/');
 | |
| 	QStringList cur=CurDir.split('/');
 | |
| 	QString rel="./";
 | |
| 	int common=0;
 | |
| 	for(common; common < abs.size() && common < cur.size(); common++){
 | |
| 		if(abs[common]!=cur[common])break;
 | |
| 	}
 | |
| 	for(int i=0;i<cur.size()-common;i++)
 | |
| 		rel.append("../");
 | |
| 	for(int i=common;i<abs.size();i++)
 | |
| 		rel.append(abs[i]+"/");
 | |
| 	return rel;
 | |
| }
 | |
| 
 |