1 /***************************************************************************
2 * Copyright (C) 2005-2008 by Tarek Saidi *
3 * tarek.saidi@arcor.de *
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; version 2 of the License. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
20 #include <QDesktopServices>
21 #include <QLibraryInfo>
23 #include <QTranslator>
25 #if defined(Q_WS_X11) || defined(Q_WS_MAC)
28 #elif defined(Q_WS_WIN)
34 void createBanner(QPixmap* Pixmap,const QPixmap* IconAlpha,const QString& Text,int Width){
35 createBanner(Pixmap,IconAlpha,Text,Width,config->bannerColor1(),config->bannerColor2(),config->bannerTextColor());
38 void createBanner(QPixmap* Pixmap,const QPixmap* IconAlpha,const QString& Text,int Width, QColor Color1, QColor Color2, QColor TextColor){
39 *Pixmap=QPixmap(Width,50);
40 QPainter painter(Pixmap);
41 QLinearGradient grad(0,0,Width,0);
42 grad.setColorAt(0,Color1);
43 grad.setColorAt(1,Color2);
44 painter.setPen(Qt::NoPen);
45 painter.setBrush(grad);
46 painter.drawRect(0,0,Width,50);
51 Icon.setAlphaChannel(*IconAlpha);
52 painter.drawPixmap(10,10,Icon);
55 painter.setPen(QPen(TextColor));
56 painter.setFont(QFont(QApplication::font().family(),16));
57 painter.drawText(50,35,Text);
60 QString decodeFileError(QFile::FileError Code){
62 case QFile::NoError: return QApplication::translate("FileErrors","No error occurred.");
63 case QFile::ReadError: return QApplication::translate("FileErrors","An error occurred while reading from the file.");
64 case QFile::WriteError: return QApplication::translate("FileErrors","An error occurred while writing to the file.");
65 case QFile::FatalError: return QApplication::translate("FileErrors","A fatal error occurred.");
66 case QFile::ResourceError: return QApplication::translate("FileErrors","An resource error occurred.");
67 case QFile::OpenError: return QApplication::translate("FileErrors","The file could not be opened.");
68 case QFile::AbortError: return QApplication::translate("FileErrors","The operation was aborted.");
69 case QFile::TimeOutError: return QApplication::translate("FileErrors","A timeout occurred.");
70 case QFile::UnspecifiedError: return QApplication::translate("FileErrors","An unspecified error occurred.");
71 case QFile::RemoveError: return QApplication::translate("FileErrors","The file could not be removed.");
72 case QFile::RenameError: return QApplication::translate("FileErrors","The file could not be renamed.");
73 case QFile::PositionError: return QApplication::translate("FileErrors","The position in the file could not be changed.");
74 case QFile::ResizeError: return QApplication::translate("FileErrors","The file could not be resized.");
75 case QFile::PermissionsError: return QApplication::translate("FileErrors","The file could not be accessed.");
76 case QFile::CopyError: return QApplication::translate("FileErrors","The file could not be copied.");
81 void openBrowser(IEntryHandle* entry){
82 QString url = entry->url();
83 url.replace("{TITLE}", entry->title(), Qt::CaseInsensitive);
84 url.replace("{USERNAME}", entry->username(), Qt::CaseInsensitive);
86 if (url.contains("{PASSWORD}",Qt::CaseInsensitive)){
87 SecString password=entry->password();
89 url.replace("{PASSWORD}", password, Qt::CaseInsensitive);
95 void openBrowser(const QString& UrlString){
96 if (UrlString.trimmed().isEmpty())
99 if (UrlString.startsWith("cmd://") && UrlString.length()>6){
100 QProcess::startDetached(UrlString.right(UrlString.length()-6));
105 if(url.scheme().isEmpty())
106 url=QUrl("http://"+UrlString);
107 if(config->urlCmdDef() || url.scheme()=="mailto"){
108 QDesktopServices::openUrl(url);
111 QByteArray UrlEncoded = url.toEncoded();
112 QString browser = config->urlCmd();
113 if (browser.contains("%u", Qt::CaseInsensitive))
114 browser.replace("%u", UrlEncoded, Qt::CaseInsensitive);
115 else if (browser.contains("%1"))
116 browser.replace("%1", UrlEncoded);
118 browser.append(" ").append(UrlEncoded);
119 QProcess::startDetached(browser);
124 QString makePathRelative(const QString& AbsDir,const QString& CurDir){
125 QStringList abs=AbsDir.split('/');
126 QStringList cur=CurDir.split('/');
129 for(common=0; common < abs.size() && common < cur.size(); common++){
130 if(abs[common]!=cur[common])break;
132 for(int i=0;i<cur.size()-common;i++)
134 for(int i=common;i<abs.size();i++)
135 rel.append(abs[i]+"/");
139 void showErrMsg(const QString& msg,QWidget* parent){
140 QMessageBox::critical(parent, QApplication::translate("Main","Error"), msg);
143 QString getImageFile(const QString& name){
144 if (QFile::exists(DataDir+"/icons/"+name))
145 return DataDir+"/icons/"+name;
147 QString errMsg = QApplication::translate("Main","File '%1' could not be found.").arg(name);
149 qFatal("File '%s' could not be found.", CSTR(errMsg));
154 const QIcon& getIcon(const QString& name){
155 static QHash<QString,QIcon*>IconCache;
156 QIcon* CachedIcon=IconCache.value(name);
161 NewIcon=new QIcon(IconLoader->getIcon(name));
162 if(NewIcon->isNull()){
167 IconCache.insert(name,NewIcon);
171 NewIcon=new QIcon(getImageFile(name+".png"));
172 IconCache.insert(name,NewIcon);
177 const QPixmap* getPixmap(const QString& name){
178 static QHash<QString,QPixmap*>PixmapCache;
179 QPixmap* CachedPixmap=PixmapCache.value(name);
182 QImage img(getImageFile(name+".png"));
183 QPixmap* NewPixmap=new QPixmap(QPixmap::fromImage(img));
184 PixmapCache.insert(name,NewPixmap);
189 bool createKeyFile(const QString& filename,QString* error,int length, bool Hex){
190 QFile file(filename);
191 if(!file.open(QIODevice::WriteOnly|QIODevice::Truncate|QIODevice::Unbuffered)){
192 *error=decodeFileError(file.error());
196 unsigned char* key=new unsigned char[length];
197 randomize(key,length);
199 // convert binary data to hex code (8 bit ==> 2 digits)
200 for(int i=0; i<length; i+=2){
201 unsigned char dig1,dig2;
205 if(dig1>9)key[i]='A'+dig1-10;
206 else key[i]='0'+dig1;
207 if(dig2>9)key[i+1]='A'+dig2-10;
208 else key[i+1]='0'+dig2;
211 if(file.write((char*)key,length)==-1){
213 *error=decodeFileError(file.error());
222 bool lockPage(void* addr, int len){
223 #if defined(Q_WS_X11) || defined(Q_WS_MAC)
224 return (mlock(addr, len)==0);
225 #elif defined(Q_WS_WIN)
226 return VirtualLock(addr, len);
232 bool unlockPage(void* addr, int len){
233 #if defined(Q_WS_X11) || defined(Q_WS_MAC)
234 return (munlock(addr, len)==0);
235 #elif defined(Q_WS_WIN)
236 return VirtualUnlock(addr, len);
242 bool syncFile(QFile* file) {
245 #if defined(Q_WS_X11) || defined(Q_WS_MAC)
246 return (fsync(file->handle())==0);
247 #elif defined(Q_WS_WIN)
248 return (_commit(file->handle())==0);
254 QTranslator* translator = new QTranslator();
255 QTranslator* qtTranslator = new QTranslator();
256 bool translatorActive = false;
257 bool qtTranslatorActive = false;
259 bool loadTranslation(QTranslator* tr,const QString& prefix,const QString& loc,const QStringList& paths){
260 for (int i=0;i<paths.size();i++){
261 if(tr->load(prefix+loc+".qm",paths[i]))
265 for (int i=0;i<paths.size();i++){
267 QStringList TrFiles=dir.entryList(QStringList()<<"*.qm",QDir::Files);
268 for (int j=0;j<TrFiles.size();j++){
269 if (TrFiles[j].left(prefix.length()+2)==prefix+loc.left(2)){
270 if (tr->load(TrFiles[j],paths[i]))
278 void deactivateTranslators(bool qtOnly=false){
279 if (translatorActive && !qtOnly){
280 QApplication::removeTranslator(translator);
281 translatorActive = false;
284 if (qtTranslatorActive){
285 QApplication::removeTranslator(qtTranslator);
286 qtTranslatorActive = false;
290 void installTranslator(){
291 QString language = config->language();
292 if (language=="auto")
293 language = QLocale::system().name();
295 if (language.isEmpty() || language=="en_US"){
296 deactivateTranslators();
300 if (loadTranslation(translator,"keepassx-",language,QStringList()
301 << HomeDir << DataDir+"/i18n/"))
303 if (!translatorActive){
304 QApplication::installTranslator(translator);
305 translatorActive = true;
309 deactivateTranslators();
313 if (loadTranslation(qtTranslator,"qt_",language,QStringList()
314 << HomeDir << DataDir+"/i18n/"
315 << QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
317 if (!qtTranslatorActive){
318 QApplication::installTranslator(qtTranslator);
319 qtTranslatorActive = true;
323 deactivateTranslators(true);
327 bool isTranslationActive(){
328 return translatorActive;
331 bool operator<(const Translation& t1, const Translation& t2){
332 return t1.nameLong < t2.nameLong;
335 QList<Translation> getAllTranslations(){
336 QTranslator tmpTranslator;
337 QList<Translation> translations;
340 QStringList paths = QStringList() << DataDir+"/i18n/" << HomeDir;
341 QRegExp filename("keepassx-([^_]{2}_[^\\.]{2}|[^\\.]{2})\\.qm");
342 for (int i=0;i<paths.size();i++){
344 QStringList TrFiles=dir.entryList(QStringList()<<"*.qm",QDir::Files);
345 for (int j=0;j<TrFiles.size();j++){
346 if (filename.exactMatch(TrFiles[j]) && TrFiles[j]!="keepassx-xx_XX.qm" &&
347 tmpTranslator.load(TrFiles[j],paths[i]) && !names.contains(filename.cap(1)))
350 t.nameCode = filename.cap(1);
351 t.nameLong = tmpTranslator.translate("Translation", "$LANGUAGE_NAME", "Insert your language name in the format: English (United States)");
352 t.author = tmpTranslator.translate("Translation", "$TRANSLATION_AUTHOR");
354 QLocale l(t.nameCode);
355 t.nameEnglish = QLocale::languageToString(l.language());
356 if (t.nameCode.size()==5){
357 QString country = QLocale::countryToString(l.country());
358 int size = country.size();
359 for (int k=1; k<size; k++){
360 if (country[k].isUpper()){
361 country.insert(k, " ");
366 t.nameEnglish.append(" (").append(country).append(")");
369 if (t.nameLong.isEmpty())
370 t.nameLong = t.nameEnglish;
378 qSort(translations.begin(), translations.end());
382 // from src/corelib/qsettings.cpp:
384 QString qtWindowsConfigPath(int type)
388 QLibrary library(QLatin1String("shell32"));
390 typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL);
391 GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
392 if (SHGetSpecialFolderPath) {
393 TCHAR path[MAX_PATH];
394 SHGetSpecialFolderPath(0, path, type, FALSE);
395 result = QString::fromUtf16((ushort*)path);
398 typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL);
399 GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathA");
400 if (SHGetSpecialFolderPath) {
402 SHGetSpecialFolderPath(0, path, type, FALSE);
403 result = QString::fromLocal8Bit(path);