diff --git a/keepassx.pro b/keepassx.pro index 6844e23..23a9d0b 100644 --- a/keepassx.pro +++ b/keepassx.pro @@ -25,4 +25,4 @@ SUBDIRS += src message("Install Prefix:" $$PREFIX) #message("KDE Prefix:" $$KDEDIR) message("*** Makefile successfully generated.") -message("*** Start make now.") \ No newline at end of file +message("*** Start make now.") diff --git a/src/Application_X11.cpp b/src/Application_X11.cpp index e8c6870..05c5b9c 100644 --- a/src/Application_X11.cpp +++ b/src/Application_X11.cpp @@ -28,9 +28,12 @@ KeepassApplication::KeepassApplication(int& argc, char** argv) : QApplication(ar } bool KeepassApplication::x11EventFilter(XEvent* event){ - if (event->type==KeyPress && AutoType::shortcut.key!=0u && event->xkey.keycode==XKeysymToKeycode(event->xkey.display,HelperX11::getKeysym(AutoType::shortcut.key)) && (event->xkey.state&remove_invalid)==HelperX11::getShortcutModifierMask(AutoType::shortcut) && focusWidget()==NULL ){ + if (event->type==KeyPress && autoType->getShortcut().key!=0u && + event->xkey.keycode==XKeysymToKeycode(event->xkey.display,HelperX11::getKeysym(autoType->getShortcut().key)) && + (event->xkey.state&remove_invalid)==HelperX11::getShortcutModifierMask(autoType->getShortcut()) && focusWidget()==NULL ) + { EventOccurred = true; - AutoType::performGlobal(); + autoType->performGlobal(); return true; } else{ diff --git a/src/Database.h b/src/Database.h index dbb2939..8eb07d0 100644 --- a/src/Database.h +++ b/src/Database.h @@ -23,7 +23,7 @@ extern const QDateTime Date_Never; -typedef enum CryptAlgorithm{ +enum CryptAlgorithm{ Rijndael_Cipher=0, Twofish_Cipher=1 }; @@ -371,7 +371,7 @@ public: */ virtual QPixmap& icon(int index)=0; //! \return the number of icons provided by the database. This number can vary at runtime if the database supports custom icons. - virtual int numIcons()=0; + virtual int numIcons()=0; /*! Deletes all old invalid handles of the database. Make sure that there are no pointers to those handles which are still in use before calling this function.*/ @@ -395,16 +395,8 @@ public: \param Fields A pointer to a six element bool array. It defines which fields are included into the search. The order is: title, username, url, password, comment, attachment description. The pointer can also be NULL, than the default pattern is used instead. \return the search results as a list of pointers to the entry handles.*/ virtual QList search(IGroupHandle* Group,const QString& SearchString, bool CaseSensitve, bool RegExp,bool Recursive,bool* Fields)=0; - - //! Moves an entry to the recycle bin. - virtual void moveToTrash(IEntryHandle* entry)=0; - - //! \returns all entries of the recycle bin. - virtual QList trashEntries()=0; - - //! Empty the recycle bin. - virtual void emptyTrash()=0; - + + //virtual IDatabase* groupToNewDb(IGroupHandle* group)=0; }; class IKdbSettings{ diff --git a/src/Kdb3Database.cpp b/src/Kdb3Database.cpp index 2d03f86..d4e483e 100644 --- a/src/Kdb3Database.cpp +++ b/src/Kdb3Database.cpp @@ -247,10 +247,16 @@ void Kdb3Database::parseCustomIconsMetaStreamV3(const QByteArray& dta){ } void Kdb3Database::parseGroupTreeStateMetaStream(const QByteArray& dta){ - if(dta.size()<4){qWarning("Discarded metastream KPX_GROUP_TREE_STATE because of a parsing error."); return;} + if(dta.size()<4){ + qWarning("Discarded metastream KPX_GROUP_TREE_STATE because of a parsing error."); + return; + } quint32 Num; memcpyFromLEnd32(&Num,dta.data()); - if(Num*5!=dta.size()-4){qWarning("Discarded metastream KPX_GROUP_TREE_STATE because of a parsing error."); return;} + if(Num*5!=dta.size()-4){ + qWarning("Discarded metastream KPX_GROUP_TREE_STATE because of a parsing error."); + return; + } TreeStateMetaStream.clear(); for(int i=0;i Kdb3Database::groups(){ quint32 Kdb3Database::getNewGroupId(){ quint32 id; bool used; - while(1){ + do{ used=false; randomize(&id,4); if(!id)continue; //group IDs must not be 0 for(int j=0;jTitle!="Backup" && RootGroup.Children.size() && RootGroup.Children.last()->Title=="Backup"){ + RootGroup.Children.last()->Index = Groups.back().Index; + Groups.back().Index--; + } Groups.back().Parent->Children.append(&Groups.back()); } return &GroupHandles.back(); @@ -1256,7 +1269,7 @@ bool Kdb3Database::save(){ } if(!File->isOpen()){ if(!File->open(QIODevice::ReadWrite)){ - error= tr("Could not open file for writing."); + error = tr("Could not open file for writing."); return false; } } @@ -1376,14 +1389,16 @@ bool Kdb3Database::save(){ delete [] buffer; return false; } - - if(!File->resize(EncryptedPartSize+DB_HEADER_SIZE)){ + + int size = EncryptedPartSize+DB_HEADER_SIZE; + + if(!File->resize(size)){ delete [] buffer; error=decodeFileError(File->error()); return false; } File->seek(0); - if(File->write(buffer,EncryptedPartSize+DB_HEADER_SIZE)!=EncryptedPartSize+DB_HEADER_SIZE){ + if(File->write(buffer,size)!=size){ delete [] buffer; error=decodeFileError(File->error()); return false; @@ -1824,34 +1839,6 @@ bool Kdb3Database::changeFile(const QString& filename){ return true; } -void Kdb3Database::moveToTrash(IEntryHandle* entry){ - TrashEntry trash=*((TrashEntry*)dynamic_cast(entry)->Entry); - IGroupHandle* CurGroup=entry->group(); - while(CurGroup){ - trash.GroupPath << CurGroup->title(); - CurGroup=CurGroup->parent(); - } - deleteEntry(entry); - trash.Group=NULL; - TrashEntries.append(trash); - TrashHandles.append(EntryHandle(this)); - TrashHandles.back().Entry=&TrashEntries.back(); - TrashEntries.back().Handle=&TrashHandles.back(); -} - -void Kdb3Database::emptyTrash(){ - TrashEntries.clear(); - TrashHandles.clear(); -} - -QList Kdb3Database::trashEntries(){ - QList handles; - for(int i=0; iaddGroup(orgGroup->Group, parent); + + QList entryList = entries(orgGroup); + for (int i=0; i(entryList[i]); + db->addEntry(entry->Entry, newParent); + } + + QList children = orgGroup->children(); + for (int i=0; i(children[i]); + copyTree(db, child, newParent); + } +} + +IDatabase* Kdb3Database::groupToNewDb(IGroupHandle* group){ + Kdb3Database* db = new Kdb3Database(); + db->create(); + copyTree(db, static_cast(group), NULL); + + db->changeFile("/ramtmp/test.kdb"); + if (!db->save()) + qWarning("%s", CSTR(db->error)); + + return db; +}*/ + void KeyTransform::transform(quint8* src, quint8* dst, quint8* KeySeed, int rounds){ KeyTransform* ktLeft = new KeyTransform(&src[0], &dst[0], KeySeed, rounds); @@ -1896,9 +1911,8 @@ int KeyTransformBenchmark::benchmark(int pMSecs){ KeyTransformBenchmark* ktbRight = new KeyTransformBenchmark(pMSecs); ktbLeft->start(); ktbRight->start(); - while (ktbLeft->isRunning() || ktbRight->isRunning()){ - QThread::msleep(100); - } + ktbLeft->wait(); + ktbRight->wait(); int num = ktbLeft->rounds + ktbRight->rounds; delete ktbLeft; delete ktbRight; diff --git a/src/Kdb3Database.h b/src/Kdb3Database.h index f4129d7..c60e48e 100644 --- a/src/Kdb3Database.h +++ b/src/Kdb3Database.h @@ -133,11 +133,6 @@ public: QList Entries; }; - class TrashEntry: public StdEntry{ - public: - QStringList GroupPath; - }; - Kdb3Database(); virtual ~Kdb3Database(){}; virtual bool load(QString identifier); @@ -150,7 +145,7 @@ public: virtual bool isKeyError(); virtual void cleanUpHandles(); virtual QPixmap& icon(int index); - virtual int numIcons(); + virtual int numIcons(); virtual void addIcon(const QPixmap& icon); virtual void removeIcon(int index); virtual void replaceIcon(int index,const QPixmap& icon); @@ -178,9 +173,6 @@ public: virtual IEntryHandle* addEntry(const CEntry* NewEntry, IGroupHandle* group); virtual void moveEntry(IEntryHandle* entry, IGroupHandle* group); virtual void deleteLastEntry(); - virtual void moveToTrash(IEntryHandle* entry); - virtual QList trashEntries(); - virtual void emptyTrash(); virtual QList groups(); @@ -192,8 +184,7 @@ public: virtual bool isParent(IGroupHandle* parent, IGroupHandle* child); virtual void generateMasterKey(); - - + //virtual IDatabase* groupToNewDb(IGroupHandle* group); private: QDateTime dateFromPackedStruct5(const unsigned char* pBytes); @@ -220,6 +211,7 @@ private: void getEntriesRecursive(IGroupHandle* Group, QList& EntryList); void rebuildIndices(QList& list); void restoreGroupTreeState(); + //void copyTree(Kdb3Database* db, GroupHandle* orgGroup, IGroupHandle* parent); StdEntry* getEntry(const KpxUuid& uuid); StdEntry* getEntry(EntryHandle* handle); @@ -231,10 +223,8 @@ private: QList EntryHandles; QList GroupHandles; - QList TrashHandles; QList Entries; QList Groups; - QList TrashEntries; StdGroup RootGroup; QListCustomIcons; QFile* File; diff --git a/src/crypto/twofish.cpp b/src/crypto/twofish.cpp index ef1d402..f39d6e6 100644 --- a/src/crypto/twofish.cpp +++ b/src/crypto/twofish.cpp @@ -365,7 +365,7 @@ * This default definition of SWAP works, but on many platforms there is a * more efficient implementation. */ -#define BSWAP(x) (ROL32((x),8)&0x00ff00ff | ROR32((x),8) & 0xff00ff00) +#define BSWAP(x) ( (ROL32((x),8) & 0x00ff00ff) | (ROR32((x),8) & 0xff00ff00) ) /* diff --git a/src/dialogs/AutoTypeDlg.cpp b/src/dialogs/AutoTypeDlg.cpp index 820bcc3..1bc712f 100644 --- a/src/dialogs/AutoTypeDlg.cpp +++ b/src/dialogs/AutoTypeDlg.cpp @@ -92,7 +92,7 @@ void AutoTypeDlg::resizeEvent(QResizeEvent* event){ bool AutoTypeDlg::event(QEvent* event){ if (!EventOccurred){ int t = event->type(); - if ( t>=QEvent::MouseButtonPress&&t<=QEvent::KeyRelease || t>=QEvent::HoverEnter&&t<=QEvent::HoverMove ) + if ( (t>=QEvent::MouseButtonPress && t<=QEvent::KeyRelease) || (t>=QEvent::HoverEnter && t<=QEvent::HoverMove) ) EventOccurred = true; } return QWidget::event(event); @@ -100,6 +100,5 @@ bool AutoTypeDlg::event(QEvent* event){ void AutoTypeDlg::itemSelected(QTreeWidgetItem* item){ close(); - QString err; - AutoType::perform(itemToEntry[item].dbHandle, err, pWasLocked, itemToEntry[item].nr, pWasLocked); + autoType->perform(itemToEntry[item].dbHandle, pWasLocked, itemToEntry[item].nr, pWasLocked); } diff --git a/src/dialogs/SelectIconDlg.cpp b/src/dialogs/SelectIconDlg.cpp index 229a25f..2877315 100644 --- a/src/dialogs/SelectIconDlg.cpp +++ b/src/dialogs/SelectIconDlg.cpp @@ -60,8 +60,9 @@ void CSelectIconDlg::OnAddIcon(){ QPixmap icon; if(!icon.load(filenames[i])){ errors+=tr("%1: File could not be loaded.").arg(filenames[i].section("/",-1)).append("\n"); - continue;} - dynamic_cast(db)->addIcon(icon.scaled(16,16,Qt::KeepAspectRatio,Qt::SmoothTransformation)); + continue; + } + dynamic_cast(db)->addIcon(icon.scaled(16,16,Qt::KeepAspectRatio,Qt::SmoothTransformation)); } if(errors.size()) QMessageBox::warning(this,tr("Error"),tr("An error occured while loading the icon(s):").append("\n").append(errors)); diff --git a/src/dialogs/SettingsDlg.cpp b/src/dialogs/SettingsDlg.cpp index ee4c0b4..f04674e 100644 --- a/src/dialogs/SettingsDlg.cpp +++ b/src/dialogs/SettingsDlg.cpp @@ -72,7 +72,7 @@ CSettingsDlg::CSettingsDlg(QWidget* parent):QDialog(parent,Qt::Dialog) #endif #ifdef GLOBAL_AUTOTYPE - pShortcut = AutoType::shortcut; + pShortcut = autoType->getShortcut(); connect(this,SIGNAL(rejected()),SLOT(resetGlobalShortcut())); #endif @@ -417,7 +417,7 @@ void CSettingsDlg::OnSelectLanguage(int index){ #ifdef GLOBAL_AUTOTYPE void CSettingsDlg::resetGlobalShortcut(){ - AutoType::unregisterGlobalShortcut(); - AutoType::registerGlobalShortcut(pShortcut); + autoType->unregisterGlobalShortcut(); + autoType->registerGlobalShortcut(pShortcut); } #endif diff --git a/src/dialogs/TargetWindowDlg.cpp b/src/dialogs/TargetWindowDlg.cpp index 19aa38a..15c3a62 100644 --- a/src/dialogs/TargetWindowDlg.cpp +++ b/src/dialogs/TargetWindowDlg.cpp @@ -22,7 +22,7 @@ TargetWindowDlg::TargetWindowDlg(QWidget* parent) : QDialog(parent){ setupUi(this); - QStringList windowTitles = AutoType::getAllWindowTitles(); + QStringList windowTitles = autoType->getAllWindowTitles(); windowTitles.sort(); for (QStringList::const_iterator i = windowTitles.constBegin(); i != windowTitles.constEnd(); ++i) comboWindow->addItem(*i); diff --git a/src/export/Export.cpp b/src/export/Export.cpp index f04035a..67f9112 100644 --- a/src/export/Export.cpp +++ b/src/export/Export.cpp @@ -23,7 +23,7 @@ #include "dialogs/SimplePasswordDlg.h" QFile* ExporterBase::openFile(QWidget* parent, QString id, QStringList Filters){ - QString filename=KpxFileDialogs::saveFile(parent,id,tr("Import File..."),Filters); + QString filename=KpxFileDialogs::saveFile(parent,id,tr("Export File..."),Filters); if(filename.isEmpty())return NULL; QFile* file=new QFile(filename); if(!file->open(QIODevice::ReadWrite|QIODevice::Truncate)){ diff --git a/src/import/Import_KWalletXml.cpp b/src/import/Import_KWalletXml.cpp index 0153928..36be0bd 100644 --- a/src/import/Import_KWalletXml.cpp +++ b/src/import/Import_KWalletXml.cpp @@ -34,7 +34,7 @@ bool Import_KWalletXml::importDatabase(QWidget* GuiParent, IDatabase* db){ int col,line; if(!doc.setContent(QString::fromUtf8((char*)buffer,len),false,&xmlerr,&line,&col)){ qWarning("Import_PwManager::parseXmlContent():\n"); - qWarning(((xmlerr+" (Line:%1 Column:%2)").arg(line).arg(col)+QString('\n')).toAscii()); + qWarning("%s (Line:%d Column:%d)\n",CSTR(xmlerr), line, col); QMessageBox::critical(GuiParent,tr("Import Failed"),tr("Invalid XML data (see stdout for details).")); delete [] buffer; return false;} diff --git a/src/import/Import_KeePassX_Xml.cpp b/src/import/Import_KeePassX_Xml.cpp index 6525910..788691d 100644 --- a/src/import/Import_KeePassX_Xml.cpp +++ b/src/import/Import_KeePassX_Xml.cpp @@ -45,7 +45,7 @@ bool Import_KeePassX_Xml::importDatabase(QWidget* Parent, IDatabase* database){ QStringList GroupNames; for(int i=0;i + +AutoTypeGlobal* autoType = NULL; + +void initAutoType(KeepassMainWindow* mainWin) { + autoType = new AutoTypeGlobalX11(mainWin); +} + +AutoTypeGlobalX11::AutoTypeGlobalX11(KeepassMainWindow* mainWin) : AutoTypeX11(mainWin) { + wm_state = XInternAtom(dpy, "WM_STATE", true); + windowRoot = XRootWindow(dpy, mainWin->x11Info().screen()); + focusedWindow = NULL; + //windowBlacklist << "kicker" << "KDE Desktop"; + classBlacklist << "desktop_window" << "gnome-panel"; // Gnome + classBlacklist << "kdesktop" << "kicker"; // KDE 3 + classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4 +} + +void AutoTypeGlobalX11::perform(IEntryHandle* entry, bool hideWindow, int nr, bool wasLocked){ + if (focusedWindow && (!hideWindow || wasLocked)) { // detect if global auto-type + XSetInputFocus(dpy, focusedWindow, RevertToPointerRoot, CurrentTime); + focusedWindow = NULL; + } + AutoTypeX11::perform(entry, hideWindow, nr, wasLocked); +} + +void AutoTypeGlobalX11::windowTitles(Window window, QStringList& titleList){ + Atom type = None; + int format; + unsigned long nitems, after; + unsigned char* data; + XGetWindowProperty(dpy, window, wm_state, 0, 0, false, AnyPropertyType, &type, &format, &nitems, &after, &data); + if (type){ + XTextProperty textProp; + if (XGetWMName(dpy, window, &textProp) != 0) { + char** list = NULL; + int count; + if (Xutf8TextPropertyToTextList(dpy, &textProp, &list, &count)>=0 && list){ + QString title = QString::fromUtf8(list[0]); + + QString className; + XClassHint* wmClass = XAllocClassHint(); + if (XGetClassHint(dpy, window, wmClass)!=0 && wmClass->res_name!=NULL) + className = QString::fromLocal8Bit(wmClass->res_name); + XFree(wmClass); + + if (window!=windowRoot && window!=mainWin->winId() && + (QApplication::activeWindow()==NULL || window!=QApplication::activeWindow()->winId()) && + // !windowBlacklist.contains(title) && + (className.isNull() || !classBlacklist.contains(className)) + ){ + titleList.append(title); + } + XFreeStringList(list); + } + } + } + + Window root; + Window parent; + Window* children = NULL; + unsigned int num_children; + int tree = XQueryTree(dpy, window, &root, &parent, &children, &num_children); + if (tree && children){ + for (int i=0; iisLocked(); + if (wasLocked) + mainWin->OnUnLockWorkspace(); + + if (!mainWin->isOpened()) + return; + + Window w; + int revert_to_return; + XGetInputFocus(dpy, &w, &revert_to_return); + char** list = NULL; + int tree; + do { + XTextProperty textProp; + if (XGetWMName(dpy, w, &textProp) != 0) { + int count; + if (Xutf8TextPropertyToTextList(dpy, &textProp, &list, &count)<0) return; + if (list) break; + } + Window root = 0; + Window parent = 0; + Window* children = NULL; + unsigned int num_children; + tree = XQueryTree(dpy, w, &root, &parent, &children, &num_children); + w = parent; + if (children) XFree(children); + } while (tree && w); + if (!list) return; + QString title = QString::fromUtf8(list[0]).toLower(); + XFreeStringList(list); + + QList validEntries; + QList entryNumbers; + QList entries = mainWin->db->entries(); + QRegExp lineMatch("Auto-Type-Window(?:-(\\d+)|):([^\\n]+)", Qt::CaseInsensitive, QRegExp::RegExp2); + QDateTime now = QDateTime::currentDateTime(); + for (int i=0; iexpire()!=Date_Never && entries[i]->expire()comment(); + int offset = 0; + while ( (offset=lineMatch.indexIn(comment, offset))!=-1 ){ + QStringList captured = lineMatch.capturedTexts(); + offset += captured[0].length(); + int nr; + QString entryWindow; + bool valid; + if (captured.size()==2){ + nr = 0; + entryWindow = captured[1].trimmed().toLower(); + } + else{ + nr = captured[1].toInt(); + entryWindow = captured[2].trimmed().toLower(); + } + if (entryWindow.length()==0) continue; + + hasWindowEntry = true; + bool wildStart = (entryWindow[0]=='*'); + bool wildEnd = (entryWindow[entryWindow.size()-1]=='*'); + if (wildStart&&wildEnd){ + entryWindow.remove(0,1); + if (entryWindow.length()!=0){ + entryWindow.remove(entryWindow.size()-1,1); + valid = title.contains(entryWindow); + } + else + valid = true; + } + else if (wildStart){ + entryWindow.remove(0,1); + valid = title.endsWith(entryWindow); + } + else if (wildEnd){ + entryWindow.remove(entryWindow.size()-1,1); + valid = title.startsWith(entryWindow); + } + else { + valid = (title==entryWindow); + } + + if (valid){ + validEntries << entries[i]; + entryNumbers << nr; + break; + } + } + + if (!hasWindowEntry && config->entryTitlesMatch()){ + QString entryTitle = entries[i]->title().toLower(); + if (!entryTitle.isEmpty() && title.contains(entryTitle)){ + validEntries << entries[i]; + entryNumbers << 0; + } + } + } + + if (validEntries.size()==1){ + focusedWindow = NULL; + perform(validEntries[0],wasLocked,entryNumbers[0],wasLocked); + } + else if (validEntries.size()>1){ + focusedWindow = w; + AutoTypeDlg* dlg = new AutoTypeDlg(validEntries, entryNumbers, wasLocked); + dlg->show(); + } +} + +bool AutoTypeGlobalX11::registerGlobalShortcut(const Shortcut& s){ + if (s.key==shortcut.key && s.ctrl==shortcut.ctrl && s.shift==shortcut.shift && s.alt==shortcut.alt && s.altgr==shortcut.altgr && s.win==shortcut.win) + return true; + + int code=XKeysymToKeycode(dpy, HelperX11::getKeysym(s.key)); + int mod=HelperX11::getShortcutModifierMask(s); + + HelperX11::startCatchErrors(); + XGrabKey(dpy, code, mod, windowRoot, true, GrabModeAsync, GrabModeAsync); + XGrabKey(dpy, code, mod | Mod2Mask, windowRoot, true, GrabModeAsync, GrabModeAsync); + XGrabKey(dpy, code, mod | LockMask, windowRoot, true, GrabModeAsync, GrabModeAsync); + XGrabKey(dpy, code, mod | Mod2Mask | LockMask, windowRoot, true, GrabModeAsync, GrabModeAsync); + HelperX11::stopCatchErrors(); + + if (HelperX11::errorOccurred()){ + XUngrabKey(dpy, code, mod, windowRoot); + XUngrabKey(dpy, code, mod | Mod2Mask, windowRoot); + XUngrabKey(dpy, code, mod | LockMask, windowRoot); + XUngrabKey(dpy, code, mod | Mod2Mask | LockMask, windowRoot); + return false; + } + else { + unregisterGlobalShortcut(); + shortcut = s; + return true; + } +} + +void AutoTypeGlobalX11::unregisterGlobalShortcut(){ + if (shortcut.key==0) return; + + int code=XKeysymToKeycode(dpy, HelperX11::getKeysym(shortcut.key)); + int mod=HelperX11::getShortcutModifierMask(shortcut); + + XUngrabKey(dpy, code, mod, windowRoot); + XUngrabKey(dpy, code, mod | Mod2Mask, windowRoot); + XUngrabKey(dpy, code, mod | LockMask, windowRoot); + XUngrabKey(dpy, code, mod | Mod2Mask | LockMask, windowRoot); + + shortcut.key = 0; +} + +QString AutoTypeGlobalX11::getRootGroupName(IEntryHandle* entry){ + IGroupHandle* group = entry->group(); + int level = group->level(); + for (int i=0; iparent(); + + return group->title(); +} diff --git a/src/lib/AutoTypeGlobalX11.h b/src/lib/AutoTypeGlobalX11.h new file mode 100644 index 0000000..409743f --- /dev/null +++ b/src/lib/AutoTypeGlobalX11.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by Tarek Saidi, Felix Geyer * + * 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; version 2 of the License. * + + * * + * 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. * + ***************************************************************************/ + +#ifndef _AUTOTYPEGLOBALX11_H_ +#define _AUTOTYPEGLOBALX11_H_ + +#include "AutoTypeX11.h" + +class AutoTypeGlobalX11 : public AutoTypeX11, public AutoTypeGlobal { + public: + AutoTypeGlobalX11(KeepassMainWindow* mainWin); + void perform(IEntryHandle* entry, bool hideWindow=true, int nr=0, bool wasLocked=false); + void performGlobal(); + bool registerGlobalShortcut(const Shortcut& s); + void unregisterGlobalShortcut(); + QStringList getAllWindowTitles(); + + private: + void windowTitles(Window window, QStringList& titleList); + QString getRootGroupName(IEntryHandle* entry); + + Window windowRoot; + //QSet windowBlacklist; + QSet classBlacklist; + Atom wm_state; + Window focusedWindow; +}; + +#endif // _AUTOTYPEGLOBALX11_H_ diff --git a/src/lib/AutoTypeX11.cpp b/src/lib/AutoTypeX11.cpp new file mode 100644 index 0000000..3241f85 --- /dev/null +++ b/src/lib/AutoTypeX11.cpp @@ -0,0 +1,866 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by Tarek Saidi, Felix Geyer * + * 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; version 2 of the License. * + + * * + * 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 "AutoTypeX11.h" + +#include "mainwindow.h" +#include "lib/HelperX11.h" +#include + +#ifndef GLOBAL_AUTOTYPE +AutoType* autoType = NULL; + +void initAutoType(KeepassMainWindow* mainWin) { + autoType = new AutoTypeX11(mainWin); +} +#endif + +AutoTypeAction::AutoTypeAction(AutoTypeActionType t, quint16 d) : type(t), data(d){ +} + +bool AutoTypeX11::error_detected = false; + +AutoTypeX11::AutoTypeX11(KeepassMainWindow* mainWin) { + this->mainWin = mainWin; + dpy = mainWin->x11Info().display(); + + keysym_table = NULL; + alt_mask = 0; + meta_mask = 0; + altgr_mask = 0; + altgr_keysym = NoSymbol; + focused_window = None; + focused_subwindow = None; + + ReadKeymap(); + if (!altgr_mask) + AddModifier(XK_Mode_switch); +} + +void AutoTypeX11::perform(IEntryHandle* entry, bool hideWindow, int nr, bool wasLocked){ + QString indexStr; + if (nr==0) + indexStr = "Auto-Type:"; + else + indexStr = QString("Auto-Type-%1:").arg(nr); + QString str; + QString comment=entry->comment(); + int c=comment.count(indexStr, Qt::CaseInsensitive); + if(c>1) { + qWarning("More than one 'Auto-Type:' key sequence found.\nAllowed is only one per entry."); + return; + } + else if (c==1) { + int start = comment.indexOf(indexStr,0,Qt::CaseInsensitive) + indexStr.length(); + int end = comment.indexOf("\n", start); + if (end == -1) + end = comment.length(); + + str=comment.mid(start,end-start).trimmed(); + if (str.isEmpty()) + return; + } + else { + bool usernameEmpty = entry->username().trimmed().isEmpty(); + SecString password=entry->password(); + password.unlock(); + bool passwordEmpty = password.string().trimmed().isEmpty(); + if (usernameEmpty && passwordEmpty) + return; + else if (usernameEmpty) + str="{PASSWORD}{ENTER}"; + else if (passwordEmpty) + str="{USERNAME}{ENTER}"; + else + str="{USERNAME}{TAB}{PASSWORD}{ENTER}"; + } + + QList Keys; + for(int i=0;i=str.size()){ + qWarning("Syntax Error in Auto-Type sequence near character %d\nFound '{' without closing '}'", i+10); + return; + } + templateToKeysyms(tmpl.toLower(),Keys,entry); + continue; + } + else{ + Keys << AutoTypeAction(TypeKey, str[i].unicode()); + } + } + + if (hideWindow) + mainWin->hide(); + + QApplication::processEvents(); + sleepTime(config->autoTypePreGap()); + + QString type; + for(int i=0;ilockOnMinimize()){ + if (hideWindow || wasLocked){ + if ( !(config->showSysTrayIcon() && config->minimizeTray()) ) + mainWin->showMinimized(); + else + mainWin->OnUnLockWorkspace(); + } + } + else{ + if (hideWindow && !(config->showSysTrayIcon() && config->minimizeTray()) ) + mainWin->showMinimized(); + if (wasLocked) + mainWin->OnUnLockWorkspace(); + } +} + +void AutoTypeX11::sleepTime(int msec){ + if (msec==0) return; + timespec timeOut, remains; + timeOut.tv_sec = msec/1000; + timeOut.tv_nsec = (msec%1000)*1000000; + nanosleep(&timeOut, &remains); +} + +void AutoTypeX11::templateToKeysyms(const QString& tmpl, QList& keys,IEntryHandle* entry){ + //tmpl must be lower case!!! + if(!tmpl.compare("title")){ + stringToKeysyms(entry->title(),keys); + return; + } + if(!tmpl.compare("username")){ + stringToKeysyms(entry->username(),keys); + return; + } + if(!tmpl.compare("url")){ + stringToKeysyms(entry->url(),keys); + return; + } + if(!tmpl.compare("password")){ + SecString password=entry->password(); + password.unlock(); + stringToKeysyms(password,keys); + return; + } + if(!tmpl.compare("space")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym(' ')); + return; + } + + if(!tmpl.compare("backspace") || !tmpl.compare("bs") || !tmpl.compare("bksp")){ + keys << AutoTypeAction(TypeKey, XK_BackSpace); + return; + } + + if(!tmpl.compare("break")){ + keys << AutoTypeAction(TypeKey, XK_Break); + return; + } + + if(!tmpl.compare("capslock")){ + keys << AutoTypeAction(TypeKey, XK_Caps_Lock); + return; + } + + if(!tmpl.compare("del") || !tmpl.compare("delete")){ + keys << AutoTypeAction(TypeKey, XK_Delete); + return; + } + + if(!tmpl.compare("end")){ + keys << AutoTypeAction(TypeKey, XK_End); + return; + } + + if(!tmpl.compare("enter")){ + keys << AutoTypeAction(TypeKey, XK_Return); + return; + } + + if(!tmpl.compare("esc")){ + keys << AutoTypeAction(TypeKey, XK_Escape); + return; + } + + if(!tmpl.compare("help")){ + keys << AutoTypeAction(TypeKey, XK_Help); + return; + } + + if(!tmpl.compare("home")){ + keys << AutoTypeAction(TypeKey, XK_Home); + return; + } + + if(!tmpl.compare("insert") || !tmpl.compare("ins")){ + keys << AutoTypeAction(TypeKey, XK_Insert); + return; + } + + if(!tmpl.compare("numlock")){ + keys << AutoTypeAction(TypeKey, XK_Num_Lock); + return; + } + + if(!tmpl.compare("scroll")){ + keys << AutoTypeAction(TypeKey, XK_Scroll_Lock); + return; + } + + if(!tmpl.compare("pgdn")){ + keys << AutoTypeAction(TypeKey, XK_Page_Down); + return; + } + + if(!tmpl.compare("pgup")){ + keys << AutoTypeAction(TypeKey, XK_Page_Up); + return; + } + + if(!tmpl.compare("prtsc")){ + keys << AutoTypeAction(TypeKey, XK_3270_PrintScreen); + return; + } + + if(!tmpl.compare("up")){ + keys << AutoTypeAction(TypeKey, XK_Up); + return; + } + + if(!tmpl.compare("down")){ + keys << AutoTypeAction(TypeKey, XK_Down); + return; + } + + if(!tmpl.compare("left")){ + keys << AutoTypeAction(TypeKey, XK_Left); + return; + } + + if(!tmpl.compare("right")){ + keys << AutoTypeAction(TypeKey, XK_Right); + return; + } + + if(!tmpl.compare("f1")){ + keys << AutoTypeAction(TypeKey, XK_F1); + return; + } + + if(!tmpl.compare("f2")){ + keys << AutoTypeAction(TypeKey, XK_F2); + return; + } + + if(!tmpl.compare("f3")){ + keys << AutoTypeAction(TypeKey, XK_F3); + return; + } + + if(!tmpl.compare("f4")){ + keys << AutoTypeAction(TypeKey, XK_F4); + return; + } + + if(!tmpl.compare("f5")){ + keys << AutoTypeAction(TypeKey, XK_F5); + return; + } + + if(!tmpl.compare("f6")){ + keys << AutoTypeAction(TypeKey, XK_F6); + return; + } + + if(!tmpl.compare("f7")){ + keys << AutoTypeAction(TypeKey, XK_F7); + return; + } + + if(!tmpl.compare("f8")){ + keys << AutoTypeAction(TypeKey, XK_F8); + return; + } + + if(!tmpl.compare("f9")){ + keys << AutoTypeAction(TypeKey, XK_F9); + return; + } + + if(!tmpl.compare("f10")){ + keys << AutoTypeAction(TypeKey, XK_F10); + return; + } + + if(!tmpl.compare("f11")){ + keys << AutoTypeAction(TypeKey, XK_F11); + return; + } + + if(!tmpl.compare("f12")){ + keys << AutoTypeAction(TypeKey, XK_F12); + return; + } + + if(!tmpl.compare("f13")){ + keys << AutoTypeAction(TypeKey, XK_F13); + return; + } + + if(!tmpl.compare("f14")){ + keys << AutoTypeAction(TypeKey, XK_F14); + return; + } + + if(!tmpl.compare("f15")){ + keys << AutoTypeAction(TypeKey, XK_F15); + return; + } + + if(!tmpl.compare("f16")){ + keys << AutoTypeAction(TypeKey, XK_F16); + return; + } + + if(!tmpl.compare("add") || !tmpl.compare("plus")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('+')); + return; + } + + if(!tmpl.compare("subtract")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('-')); + return; + } + + if(!tmpl.compare("multiply")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('+')); + return; + } + + if(!tmpl.compare("divide")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('/')); + return; + } + + if(!tmpl.compare("at")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('@')); + return; + } + + if(!tmpl.compare("percent")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('%')); + return; + } + + if(!tmpl.compare("caret")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('^')); + return; + } + + if(!tmpl.compare("tilde")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('~')); + return; + } + + if(!tmpl.compare("leftbrace")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('{')); + return; + } + + if(!tmpl.compare("rightbrace")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('}')); + return; + } + + if(!tmpl.compare("leftparen")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('(')); + return; + } + + if(!tmpl.compare("rightparen")){ + keys << AutoTypeAction(TypeKey, HelperX11::getKeysym(')')); + return; + } + + if(!tmpl.compare("winl")){ + keys << AutoTypeAction(TypeKey, XK_Super_L); + return; + } + + if(!tmpl.compare("winr")){ + keys << AutoTypeAction(TypeKey, XK_Super_R); + return; + } + + if(!tmpl.compare("win")){ + keys << AutoTypeAction(TypeKey, XK_Super_L); + return; + } + + if(!tmpl.compare("tab")){ + keys << AutoTypeAction(TypeKey, XK_Tab); + return; + } + + if(tmpl.startsWith("delay ") && tmpl.length()>6){ + bool ok; + quint16 delay = tmpl.right(tmpl.length()-6).toInt(&ok); + if (ok && delay>0 && delay<=10000) + keys << AutoTypeAction(Delay, delay); + } +} + +void AutoTypeX11::stringToKeysyms(const QString& string,QList& KeySymList){ + for(int i=0; i + * http://homepage3.nifty.com/tsato/ + * + * 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 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. + */ + +/* + * Insert a specified keysym to unused position in the keymap table. + * This will be called to add required keysyms on-the-fly. + * if the second parameter is TRUE, the keysym will be added to the + * non-shifted position - this may be required for modifier keys + * (e.g. Mode_switch) and some special keys (e.g. F20). + */ +int AutoTypeX11::AddKeysym(KeySym keysym, bool top) +{ + int keycode, pos, max_pos, inx, phase; + + if (top) { + max_pos = 0; + } else { + max_pos = keysym_per_keycode - 1; + if (4 <= max_pos) max_pos = 3; + if (2 <= max_pos && altgr_keysym != XK_Mode_switch) max_pos = 1; + } + + for (phase = 0; phase < 2; phase++) { + for (keycode = max_keycode; min_keycode <= keycode; keycode--) { + for (pos = max_pos; 0 <= pos; pos--) { + inx = (keycode - min_keycode) * keysym_per_keycode; + if ((phase != 0 || keysym_table[inx] == NoSymbol) && keysym_table[inx] < 0xFF00) { + /* In the first phase, to avoid modifing existing keys, */ + /* add the keysym only to the keys which has no keysym in the first position. */ + /* If no place fuond in the first phase, add the keysym for any keys except */ + /* for modifier keys and other special keys */ + if (keysym_table[inx + pos] == NoSymbol) { + keysym_table[inx + pos] = keysym; + XChangeKeyboardMapping(dpy, keycode, keysym_per_keycode, &keysym_table[inx], 1); + XFlush(dpy); + return keycode; + } + } + } + } + } + qWarning("Couldn't add \"%s\" to keymap", XKeysymToString(keysym)); + return NoSymbol; +} + +/* + * Add the specified key as a new modifier. + * This is used to use Mode_switch (AltGr) as a modifier. + */ +void AutoTypeX11::AddModifier(KeySym keysym) +{ + XModifierKeymap *modifiers; + int keycode, i, pos; + + keycode = XKeysymToKeycode(dpy, keysym); + if (keycode == NoSymbol) keycode = AddKeysym(keysym, TRUE); + + modifiers = XGetModifierMapping(dpy); + for (i = 7; 3 < i; i--) { + if (modifiers->modifiermap[i * modifiers->max_keypermod] == NoSymbol + || ((keysym_table[(modifiers->modifiermap[i * modifiers->max_keypermod] + - min_keycode) * keysym_per_keycode]) == XK_ISO_Level3_Shift + && keysym == XK_Mode_switch)) + { + for (pos = 0; pos < modifiers->max_keypermod; pos++) { + if (modifiers->modifiermap[i * modifiers->max_keypermod + pos] == NoSymbol) { + modifiers->modifiermap[i * modifiers->max_keypermod + pos] = keycode; + XSetModifierMapping(dpy, modifiers); + return; + } + } + } + } + qWarning("Couldn't add \"%s\" as modifier", XKeysymToString(keysym)); +} + +/* + * Read keyboard mapping and modifier mapping. + * Keyboard mapping is used to know what keys are in shifted position. + * Modifier mapping is required because we should know Alt and Meta + * key are used as which modifier. + */ +void AutoTypeX11::ReadKeymap() +{ + int i; + int keycode, inx, pos; + KeySym keysym; + XModifierKeymap *modifiers; + int last_altgr_mask; + + XDisplayKeycodes(dpy, &min_keycode, &max_keycode); + if (keysym_table != NULL) XFree(keysym_table); + keysym_table = XGetKeyboardMapping(dpy, + min_keycode, max_keycode - min_keycode + 1, + &keysym_per_keycode); + for (keycode = min_keycode; keycode <= max_keycode; keycode++) { + /* if the first keysym is alphabet and the second keysym is NoSymbol, + it is equivalent to pair of lowercase and uppercase alphabet */ + inx = (keycode - min_keycode) * keysym_per_keycode; + if (keysym_table[inx + 1] == NoSymbol + && ((XK_A <= keysym_table[inx] && keysym_table[inx] <= XK_Z) + || (XK_a <= keysym_table[inx] && keysym_table[inx] <= XK_z))) + { + if (XK_A <= keysym_table[inx] && keysym_table[inx] <= XK_Z) + keysym_table[inx] = keysym_table[inx] - XK_A + XK_a; + keysym_table[inx + 1] = keysym_table[inx] - XK_a + XK_A; + } + } + + last_altgr_mask = altgr_mask; + alt_mask = 0; + meta_mask = 0; + altgr_mask = 0; + altgr_keysym = NoSymbol; + modifiers = XGetModifierMapping(dpy); + for (i = 0; i < 8; i++) { + for (pos = 0; pos < modifiers->max_keypermod; pos++) { + keycode = modifiers->modifiermap[i * modifiers->max_keypermod + pos]; + if (keycode < min_keycode || max_keycode < keycode) continue; + + keysym = keysym_table[(keycode - min_keycode) * keysym_per_keycode]; + if (keysym == XK_Alt_L || keysym == XK_Alt_R) { + alt_mask = 1 << i; + } else if (keysym == XK_Meta_L || keysym == XK_Meta_R) { + meta_mask = 1 << i; + } else if (keysym == XK_Mode_switch) { + if (altgr_keysym == XK_ISO_Level3_Shift) { + } else { + altgr_mask = 0x0101 << i; + /* I don't know why, but 0x2000 was required for mod3 on my Linux box */ + altgr_keysym = keysym; + } + } else if (keysym == XK_ISO_Level3_Shift) { + /* if no Mode_switch, try to use ISO_Level3_Shift instead */ + /* however, it may not work as intended - I don't know why */ + altgr_mask = 1 << i; + altgr_keysym = keysym; + } + } + } + XFreeModifiermap(modifiers); +} + +/* + * Send event to the focused window. + * If input focus is specified explicitly, select the window + * before send event to the window. + */ +void AutoTypeX11::SendEvent(XKeyEvent *event) +{ + static bool first = TRUE; + + XSync(event->display, FALSE); + int (*oldHandler) (Display*, XErrorEvent*) = XSetErrorHandler(MyErrorHandler); + + error_detected = FALSE; + if (focused_window != None) { + /* set input focus if input focus is set explicitly */ + XSetInputFocus(event->display, focused_window, RevertToParent, CurrentTime); + XSync(event->display, FALSE); + } + if (!error_detected) { + Window root, child, w; + int root_x, root_y, x, y; + unsigned int mask; + int revert_to; + + w = None; + first = FALSE; + + w = focused_subwindow; + if (w == None) + XGetInputFocus(event->display, &w, &revert_to); + + if (w != None) { + XQueryPointer(event->display, w, + &root, &child, &root_x, &root_y, &x, &y, &mask); + XWarpPointer(event->display, None, w, 0, 0, 0, 0, 1, 1); + XFlush(event->display); + } + + XTestFakeKeyEvent(event->display, event->keycode, event->type == KeyPress, 0); + XFlush(event->display); + + if (w != None) { + XWarpPointer(event->display, None, root, 0, 0, 0, 0, root_x, root_y); + XFlush(event->display); + } + } else { + XTestFakeKeyEvent(event->display, event->keycode, event->type == KeyPress, 0); + XFlush(event->display); + } + + if (error_detected) { + /* reset focus because focused window is (probably) no longer exist */ + focused_window = None; + focused_subwindow = None; + } + + XSetErrorHandler(oldHandler); +} + +/* + * Send sequence of KeyPressed/KeyReleased events to the focused + * window to simulate keyboard. If modifiers (shift, control, etc) + * are set ON, many events will be sent. + */ +void AutoTypeX11::SendKeyPressedEvent(KeySym keysym, unsigned int shift) +{ + Window cur_focus; + int revert_to; + XKeyEvent event; + int keycode; + int phase, inx; + bool found; + + if (focused_subwindow != None) + cur_focus = focused_subwindow; + else + XGetInputFocus(dpy, &cur_focus, &revert_to); + + found = FALSE; + keycode = 0; + if (keysym != NoSymbol) { + for (phase = 0; phase < 2; phase++) { + for (keycode = min_keycode; !found && (keycode <= max_keycode); keycode++) { + /* Determine keycode for the keysym: we use this instead + of XKeysymToKeycode() because we must know shift_state, too */ + inx = (keycode - min_keycode) * keysym_per_keycode; + if (keysym_table[inx] == keysym) { + shift &= ~altgr_mask; + if (keysym_table[inx + 1] != NoSymbol) shift &= ~ShiftMask; + found = TRUE; + break; + } else if (keysym_table[inx + 1] == keysym) { + shift &= ~altgr_mask; + shift |= ShiftMask; + found = TRUE; + break; + } + } + if (!found && altgr_mask && 3 <= keysym_per_keycode) { + for (keycode = min_keycode; !found && (keycode <= max_keycode); keycode++) { + inx = (keycode - min_keycode) * keysym_per_keycode; + if (keysym_table[inx + 2] == keysym) { + shift &= ~ShiftMask; + shift |= altgr_mask; + found = TRUE; + break; + } else if (4 <= keysym_per_keycode && keysym_table[inx + 3] == keysym) { + shift |= ShiftMask | altgr_mask; + found = TRUE; + break; + } + } + } + if (found) break; + + if (0xF000 <= keysym) { + /* for special keys such as function keys, + first try to add it in the non-shifted position of the keymap */ + if (AddKeysym(keysym, TRUE) == NoSymbol) AddKeysym(keysym, FALSE); + } else { + AddKeysym(keysym, FALSE); + } + } + } + + event.display = dpy; + event.window = cur_focus; + event.root = RootWindow(event.display, DefaultScreen(event.display)); + event.subwindow = None; + event.time = CurrentTime; + event.x = 1; + event.y = 1; + event.x_root = 1; + event.y_root = 1; + event.same_screen = TRUE; + + Window root, child; + int root_x, root_y, x, y; + unsigned int mask; + + XQueryPointer(dpy, event.root, &root, &child, &root_x, &root_y, &x, &y, &mask); + + event.type = KeyRelease; + event.state = 0; + if (mask & ControlMask) { + event.keycode = XKeysymToKeycode(dpy, XK_Control_L); + SendEvent(&event); + } + if (mask & alt_mask) { + event.keycode = XKeysymToKeycode(dpy, XK_Alt_L); + SendEvent(&event); + } + if (mask & meta_mask) { + event.keycode = XKeysymToKeycode(dpy, XK_Meta_L); + SendEvent(&event); + } + if (mask & altgr_mask) { + event.keycode = XKeysymToKeycode(dpy, altgr_keysym); + SendEvent(&event); + } + if (mask & ShiftMask) { + event.keycode = XKeysymToKeycode(dpy, XK_Shift_L); + SendEvent(&event); + } + if (mask & LockMask) { + event.keycode = XKeysymToKeycode(dpy, XK_Caps_Lock); + SendEvent(&event); + } + + event.type = KeyPress; + event.state = 0; + if (shift & ControlMask) { + event.keycode = XKeysymToKeycode(dpy, XK_Control_L); + SendEvent(&event); + event.state |= ControlMask; + } + if (shift & alt_mask) { + event.keycode = XKeysymToKeycode(dpy, XK_Alt_L); + SendEvent(&event); + event.state |= alt_mask; + } + if (shift & meta_mask) { + event.keycode = XKeysymToKeycode(dpy, XK_Meta_L); + SendEvent(&event); + event.state |= meta_mask; + } + if (shift & altgr_mask) { + event.keycode = XKeysymToKeycode(dpy, altgr_keysym); + SendEvent(&event); + event.state |= altgr_mask; + } + if (shift & ShiftMask) { + event.keycode = XKeysymToKeycode(dpy, XK_Shift_L); + SendEvent(&event); + event.state |= ShiftMask; + } + + if (keysym != NoSymbol) { /* send event for the key itself */ + event.keycode = found ? keycode : XKeysymToKeycode(dpy, keysym); + if (event.keycode == NoSymbol) { + if ((keysym & ~0x7f) == 0 && isprint(keysym)) + qWarning("No such key: %c", (char)keysym); + else if (XKeysymToString(keysym) != NULL) + qWarning("No such key: keysym=%s (0x%lX)", XKeysymToString(keysym), (long)keysym); + else + qWarning("No such key: keysym=0x%lX", (long)keysym); + } else { + SendEvent(&event); + event.type = KeyRelease; + SendEvent(&event); + } + } + + event.type = KeyRelease; + if (shift & ShiftMask) { + event.keycode = XKeysymToKeycode(dpy, XK_Shift_L); + SendEvent(&event); + event.state &= ~ShiftMask; + } + if (shift & altgr_mask) { + event.keycode = XKeysymToKeycode(dpy, altgr_keysym); + SendEvent(&event); + event.state &= ~altgr_mask; + } + if (shift & meta_mask) { + event.keycode = XKeysymToKeycode(dpy, XK_Meta_L); + SendEvent(&event); + event.state &= ~meta_mask; + } + if (shift & alt_mask) { + event.keycode = XKeysymToKeycode(dpy, XK_Alt_L); + SendEvent(&event); + event.state &= ~alt_mask; + } + if (shift & ControlMask) { + event.keycode = XKeysymToKeycode(dpy, XK_Control_L); + SendEvent(&event); + event.state &= ~ControlMask; + } +} + +int AutoTypeX11::MyErrorHandler(Display *my_dpy, XErrorEvent *event) +{ + char msg[200]; + + error_detected = TRUE; + if (event->error_code == BadWindow) { + return 0; + } + XGetErrorText(my_dpy, event->error_code, msg, sizeof(msg) - 1); + qWarning("X error trapped: %s, request-code=%d\n", msg, event->request_code); + return 0; +} diff --git a/src/lib/AutoTypeX11.h b/src/lib/AutoTypeX11.h new file mode 100644 index 0000000..df60f54 --- /dev/null +++ b/src/lib/AutoTypeX11.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by Tarek Saidi, Felix Geyer * + * 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; version 2 of the License. * + + * * + * 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. * + ***************************************************************************/ + +#ifndef _AUTOTYPEX11_H_ +#define _AUTOTYPEX11_H_ + +#include "AutoType.h" + +#include + +enum AutoTypeActionType{ + TypeKey, Delay +}; + +struct AutoTypeAction{ + AutoTypeAction(AutoTypeActionType t, quint16 d); + AutoTypeActionType type; + quint16 data; +}; + +class AutoTypeX11 : public AutoType { + public: + AutoTypeX11(KeepassMainWindow* mainWin); + void perform(IEntryHandle* entry, bool hideWindow=true, int nr=0, bool wasLocked=false); + + protected: + void sleepTime(int msec); + inline void sleepKeyStrokeDelay(){ sleep(config->autoTypeKeyStrokeDelay()); }; + void templateToKeysyms(const QString& Template, QList& KeySymList,IEntryHandle* entry); + void stringToKeysyms(const QString& string,QList& KeySymList); + + int AddKeysym(KeySym keysym, bool top); + void AddModifier(KeySym keysym); + void ReadKeymap(); + void SendKeyPressedEvent(KeySym keysym, unsigned int shift); + void SendEvent(XKeyEvent *event); + static int MyErrorHandler(Display *my_dpy, XErrorEvent *event); + + KeepassMainWindow* mainWin; + Display* dpy; + + KeySym *keysym_table; + int min_keycode, max_keycode; + int keysym_per_keycode; + static bool error_detected; + int alt_mask; + int meta_mask; + int altgr_mask; + KeySym altgr_keysym; + Window focused_window; + Window focused_subwindow; +}; + +#endif // _AUTOTYPEX11_H_ diff --git a/src/lib/AutoType_X11.cpp b/src/lib/AutoType_X11.cpp deleted file mode 100644 index 87e528d..0000000 --- a/src/lib/AutoType_X11.cpp +++ /dev/null @@ -1,665 +0,0 @@ - /*************************************************************************** - * Copyright (C) 2005-2006 by Tarek Saidi, Felix Geyer * - * 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; version 2 of the License. * - - * * - * 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 -#include -#include "mainwindow.h" -#include "HelperX11.h" -#include "AutoType.h" - -#ifdef GLOBAL_AUTOTYPE - #include "dialogs/AutoTypeDlg.h" -#endif - -enum AutoTypeActionType{ - TypeKey, Delay -}; - -struct AutoTypeAction{ - AutoTypeAction(AutoTypeActionType t, quint16 d); - AutoTypeActionType type; - quint16 data; -}; - -class AutoTypePrivate{ - public: - static void sleep(int msec); - inline static void sleepKeyStrokeDelay(){ sleep(config->autoTypeKeyStrokeDelay()); }; - static void templateToKeysyms(const QString& Template, QList& KeySymList,IEntryHandle* entry); - static void stringToKeysyms(const QString& string,QList& KeySymList); - static QString getRootGroupName(IEntryHandle* entry); -}; - - -// AutoType - -KeepassMainWindow* AutoType::MainWin=NULL; -#ifdef GLOBAL_AUTOTYPE -Shortcut AutoType::shortcut; -#endif - -void AutoType::perform(IEntryHandle* entry, QString& err,bool hideWindow,int nr,bool wasLocked){ - QString indexStr; - if (nr==0) - indexStr = "Auto-Type:"; - else - indexStr = QString("Auto-Type-%1:").arg(nr); - QString str; - QString comment=entry->comment(); - int c=comment.count(indexStr, Qt::CaseInsensitive); - if(c>1){ - err=QCoreApplication::translate("AutoType","More than one 'Auto-Type:' key sequence found.\nAllowed is only one per entry."); - return; - } - else if(c==1){ - int start = comment.indexOf(indexStr,0,Qt::CaseInsensitive) + indexStr.length(); - int end = comment.indexOf("\n", start); - if (end == -1) - end = comment.length(); - - str=comment.mid(start,end-start).trimmed(); - if (str.isEmpty()) - return; - } - else - str="{USERNAME}{TAB}{PASSWORD}{ENTER}"; - - QList Keys; - for(int i=0;i=str.size()){ - err=QCoreApplication::translate("AutoType","Syntax Error in Auto-Type sequence near character %1\n\ - Found '{' without closing '}'").arg(i+10); - return; - } - AutoTypePrivate::templateToKeysyms(tmpl.toLower(),Keys,entry); - continue; - } - else{ - Keys << AutoTypeAction(TypeKey, HelperX11::getKeysym(str[i])); - } - } - - if (hideWindow) - MainWin->hide(); - - AutoTypePrivate::sleep(config->autoTypePreGap()); - - Display* pDisplay = QX11Info::display(); - - bool capsEnabled = HelperX11::keyboardModifiers(pDisplay)&LockMask; - if (capsEnabled){ - XTestFakeKeyEvent(pDisplay,XKeysymToKeycode(pDisplay,XK_Caps_Lock),true,0); - XTestFakeKeyEvent(pDisplay,XKeysymToKeycode(pDisplay,XK_Caps_Lock),false,0); - AutoTypePrivate::sleepKeyStrokeDelay(); - } - - char keys_return[32]; - XQueryKeymap(pDisplay, keys_return); - for (int i=0; i<32; i++) - for (int j=0; j<8; j++) - if ( keys_return[i] & (1<lockOnMinimize()){ - if (hideWindow || wasLocked){ - if ( !(config->showSysTrayIcon() && config->minimizeTray()) ) - MainWin->showMinimized(); - else - MainWin->OnUnLockWorkspace(); - } - } - else{ - if (hideWindow && !(config->showSysTrayIcon() && config->minimizeTray()) ) - MainWin->showMinimized(); - if (wasLocked) - MainWin->OnUnLockWorkspace(); - } -} - -#ifdef GLOBAL_AUTOTYPE - -Window windowRoot; -//QSet windowBlacklist; -QSet classBlacklist; -Atom wm_state; - -void windowTitles(Window window, QStringList& titleList){ - Display* d = QX11Info::display(); - - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char* data; - XGetWindowProperty(d, window, wm_state, 0, 0, false, AnyPropertyType, &type, &format, &nitems, &after, &data); - if (type){ - XTextProperty textProp; - if (XGetWMName(d, window, &textProp) != 0) { - char** list = NULL; - int count; - if (Xutf8TextPropertyToTextList(d, &textProp, &list, &count)>=0 && list){ - QString title = QString::fromUtf8(list[0]); - - QString className; - XClassHint* wmClass = XAllocClassHint(); - if (XGetClassHint(d, window, wmClass)!=0 && wmClass->res_name!=NULL) - className = QString::fromLocal8Bit(wmClass->res_name); - XFree(wmClass); - - if (window!=windowRoot && window!=AutoType::MainWin->winId() && - (QApplication::activeWindow()==NULL || window!=QApplication::activeWindow()->winId()) && - // !windowBlacklist.contains(title) && - (className.isNull() || !classBlacklist.contains(className)) - ){ - titleList.append(title); - } - XFreeStringList(list); - } - } - } - - Window root; - Window parent; - Window* children = NULL; - unsigned int num_children; - int tree = XQueryTree(d, window, &root, &parent, &children, &num_children); - if (tree && children){ - for (int i=0; ix11Info().screen()); - //windowBlacklist << "kicker" << "KDE Desktop"; - classBlacklist << "desktop_window" << "gnome-panel"; // Gnome - classBlacklist << "kdesktop" << "kicker"; // KDE 3 - classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4 -} - -QStringList AutoType::getAllWindowTitles(){ - QStringList titleList; - if (wm_state) // don't do anything if WM_STATE doesn't exist - windowTitles(windowRoot, titleList); - return titleList; -} - -void AutoType::performGlobal(){ - bool wasLocked = MainWin->isLocked(); - if (wasLocked) - MainWin->OnUnLockWorkspace(); - - if (!MainWin->isOpened()) - return; - - Display* d = QX11Info::display(); - Window w; - int revert_to_return; - XGetInputFocus(d, &w, &revert_to_return); - char** list = NULL; - int tree; - do { - XTextProperty textProp; - if (XGetWMName(d, w, &textProp) != 0) { - int count; - if (Xutf8TextPropertyToTextList(d, &textProp, &list, &count)<0) return; - if (list) break; - } - Window root = 0; - Window parent = 0; - Window* children = NULL; - unsigned int num_children; - tree = XQueryTree(d, w, &root, &parent, &children, &num_children); - w = parent; - if (children) XFree(children); - } while (tree && w); - if (!list) return; - QString title = QString::fromUtf8(list[0]).toLower(); - XFreeStringList(list); - - QList validEntries; - QList entryNumbers; - QList entries = MainWin->db->entries(); - QRegExp lineMatch("Auto-Type-Window(?:-(\\d+)|):([^\\n]+)", Qt::CaseInsensitive, QRegExp::RegExp2); - QDateTime now = QDateTime::currentDateTime(); - for (int i=0; iexpire()!=Date_Never && entries[i]->expire()comment(); - int offset = 0; - while ( (offset=lineMatch.indexIn(comment, offset))!=-1 ){ - QStringList captured = lineMatch.capturedTexts(); - offset += captured[0].length(); - int nr; - QString entryWindow; - bool valid; - if (captured.size()==2){ - nr = 0; - entryWindow = captured[1].trimmed().toLower(); - } - else{ - nr = captured[1].toInt(); - entryWindow = captured[2].trimmed().toLower(); - } - if (entryWindow.length()==0) continue; - - hasWindowEntry = true; - bool wildStart = (entryWindow[0]=='*'); - bool wildEnd = (entryWindow[entryWindow.size()-1]=='*'); - if (wildStart&&wildEnd){ - entryWindow.remove(0,1); - if (entryWindow.length()!=0){ - entryWindow.remove(entryWindow.size()-1,1); - valid = title.contains(entryWindow); - } - else - valid = true; - } - else if (wildStart){ - entryWindow.remove(0,1); - valid = title.endsWith(entryWindow); - } - else if (wildEnd){ - entryWindow.remove(entryWindow.size()-1,1); - valid = title.startsWith(entryWindow); - } - else { - valid = (title==entryWindow); - } - - if (valid){ - validEntries << entries[i]; - entryNumbers << nr; - break; - } - } - - if (!hasWindowEntry && config->entryTitlesMatch()){ - QString entryTitle = entries[i]->title().toLower(); - if (!entryTitle.isEmpty() && title.contains(entryTitle)){ - validEntries << entries[i]; - entryNumbers << 0; - } - } - } - - if (validEntries.size()==1){ - QString err; - perform(validEntries[0],err,wasLocked,entryNumbers[0],wasLocked); - } - else if (validEntries.size()>1){ - AutoTypeDlg* dlg = new AutoTypeDlg(validEntries, entryNumbers, wasLocked); - dlg->show(); - } -} - -bool AutoType::registerGlobalShortcut(const Shortcut& s){ - if (s.key==shortcut.key && s.ctrl==shortcut.ctrl && s.shift==shortcut.shift && s.alt==shortcut.alt && s.altgr==shortcut.altgr && s.win==shortcut.win) - return true; - - Display* display = QX11Info::display(); - Window root = XRootWindow(display, MainWin->x11Info().screen()); - int code=XKeysymToKeycode(display, HelperX11::getKeysym(s.key)); - int mod=HelperX11::getShortcutModifierMask(s); - - HelperX11::startCatchErrors(); - XGrabKey(display, code, mod, root, True, GrabModeAsync, GrabModeAsync); - XGrabKey(display, code, mod | Mod2Mask, root, True, GrabModeAsync, GrabModeAsync); - XGrabKey(display, code, mod | LockMask, root, True, GrabModeAsync, GrabModeAsync); - XGrabKey(display, code, mod | Mod2Mask | LockMask, root, True, GrabModeAsync, GrabModeAsync); - HelperX11::stopCatchErrors(); - - if (HelperX11::errorOccurred()){ - XUngrabKey(display, code, mod, root); - XUngrabKey(display, code, mod | Mod2Mask, root); - XUngrabKey(display, code, mod | LockMask, root); - XUngrabKey(display, code, mod | Mod2Mask | LockMask, root); - return false; - } - else { - unregisterGlobalShortcut(); - shortcut = s; - return true; - } -} - -void AutoType::unregisterGlobalShortcut(){ - if (shortcut.key==0) return; - - Display* display = QX11Info::display(); - Window root = XDefaultRootWindow(display); - int code=XKeysymToKeycode(display, HelperX11::getKeysym(shortcut.key)); - int mod=HelperX11::getShortcutModifierMask(shortcut); - - XUngrabKey(display, code, mod, root); - XUngrabKey(display, code, mod | Mod2Mask, root); - XUngrabKey(display, code, mod | LockMask, root); - XUngrabKey(display, code, mod | Mod2Mask | LockMask, root); - - shortcut.key = 0; -} - -#endif // GLOBAL_AUTOTYPE - -AutoTypeAction::AutoTypeAction(AutoTypeActionType t, quint16 d) : type(t), data(d){ -} - - -// AutoTypePrivate - -void AutoTypePrivate::sleep(int msec){ - if (msec==0) return; - timespec timeOut, remains; - timeOut.tv_sec = msec/1000; - timeOut.tv_nsec = (msec%1000)*1000000; - nanosleep(&timeOut, &remains); -} - -void AutoTypePrivate::templateToKeysyms(const QString& tmpl, QList& keys,IEntryHandle* entry){ - //tmpl must be lower case!!! - if(!tmpl.compare("title")){ - stringToKeysyms(entry->title(),keys); - return;} - if(!tmpl.compare("username")){ - stringToKeysyms(entry->username(),keys); - return;} - if(!tmpl.compare("url")){ - stringToKeysyms(entry->url(),keys); - return;} - if(!tmpl.compare("password")){ - SecString password=entry->password(); - password.unlock(); - stringToKeysyms(password,keys); - return; - } - if(!tmpl.compare("space")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym(' ')); - return;} - - if(!tmpl.compare("backspace") || !tmpl.compare("bs") || !tmpl.compare("bksp")){ - keys << AutoTypeAction(TypeKey, XK_BackSpace); - return;} - - if(!tmpl.compare("break")){ - keys << AutoTypeAction(TypeKey, XK_Break); - return;} - - if(!tmpl.compare("capslock")){ - keys << AutoTypeAction(TypeKey, XK_Caps_Lock); - return;} - - if(!tmpl.compare("del") || !tmpl.compare("delete")){ - keys << AutoTypeAction(TypeKey, XK_Delete); - return;} - - if(!tmpl.compare("end")){ - keys << AutoTypeAction(TypeKey, XK_End); - return;} - - if(!tmpl.compare("enter")){ - keys << AutoTypeAction(TypeKey, XK_Return); - return;} - - if(!tmpl.compare("esc")){ - keys << AutoTypeAction(TypeKey, XK_Escape); - return;} - - if(!tmpl.compare("help")){ - keys << AutoTypeAction(TypeKey, XK_Help); - return;} - - if(!tmpl.compare("home")){ - keys << AutoTypeAction(TypeKey, XK_Home); - return;} - - if(!tmpl.compare("insert") || !tmpl.compare("ins")){ - keys << AutoTypeAction(TypeKey, XK_Insert); - return;} - - if(!tmpl.compare("numlock")){ - keys << AutoTypeAction(TypeKey, XK_Num_Lock); - return;} - - if(!tmpl.compare("scroll")){ - keys << AutoTypeAction(TypeKey, XK_Scroll_Lock); - return;} - - if(!tmpl.compare("pgdn")){ - keys << AutoTypeAction(TypeKey, XK_Page_Down); - return;} - - if(!tmpl.compare("pgup")){ - keys << AutoTypeAction(TypeKey, XK_Page_Up); - return;} - - if(!tmpl.compare("prtsc")){ - keys << AutoTypeAction(TypeKey, XK_3270_PrintScreen); - return;} - - if(!tmpl.compare("up")){ - keys << AutoTypeAction(TypeKey, XK_Up); - return;} - - if(!tmpl.compare("down")){ - keys << AutoTypeAction(TypeKey, XK_Down); - return;} - - if(!tmpl.compare("left")){ - keys << AutoTypeAction(TypeKey, XK_Left); - return;} - - if(!tmpl.compare("right")){ - keys << AutoTypeAction(TypeKey, XK_Right); - return;} - - if(!tmpl.compare("f1")){ - keys << AutoTypeAction(TypeKey, XK_F1); - return;} - - if(!tmpl.compare("f2")){ - keys << AutoTypeAction(TypeKey, XK_F2); - return;} - - if(!tmpl.compare("f3")){ - keys << AutoTypeAction(TypeKey, XK_F3); - return;} - - if(!tmpl.compare("f4")){ - keys << AutoTypeAction(TypeKey, XK_F4); - return;} - - if(!tmpl.compare("f5")){ - keys << AutoTypeAction(TypeKey, XK_F5); - return;} - - if(!tmpl.compare("f6")){ - keys << AutoTypeAction(TypeKey, XK_F6); - return;} - - if(!tmpl.compare("f7")){ - keys << AutoTypeAction(TypeKey, XK_F7); - return;} - - if(!tmpl.compare("f8")){ - keys << AutoTypeAction(TypeKey, XK_F8); - return;} - - if(!tmpl.compare("f9")){ - keys << AutoTypeAction(TypeKey, XK_F9); - return;} - - if(!tmpl.compare("f10")){ - keys << AutoTypeAction(TypeKey, XK_F10); - return;} - - if(!tmpl.compare("f11")){ - keys << AutoTypeAction(TypeKey, XK_F11); - return;} - - if(!tmpl.compare("f12")){ - keys << AutoTypeAction(TypeKey, XK_F12); - return;} - - if(!tmpl.compare("f13")){ - keys << AutoTypeAction(TypeKey, XK_F13); - return;} - - if(!tmpl.compare("f14")){ - keys << AutoTypeAction(TypeKey, XK_F14); - return;} - - if(!tmpl.compare("f15")){ - keys << AutoTypeAction(TypeKey, XK_F15); - return;} - - if(!tmpl.compare("f16")){ - keys << AutoTypeAction(TypeKey, XK_F16); - return;} - - if(!tmpl.compare("add") || !tmpl.compare("plus")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('+')); - return;} - - if(!tmpl.compare("subtract")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('-')); - return;} - - if(!tmpl.compare("multiply")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('+')); - return;} - - if(!tmpl.compare("divide")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('/')); - return;} - - if(!tmpl.compare("at")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('@')); - return;} - - if(!tmpl.compare("percent")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('%')); - return;} - - if(!tmpl.compare("caret")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('^')); - return;} - - if(!tmpl.compare("tilde")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('~')); - return;} - - if(!tmpl.compare("leftbrace")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('{')); - return;} - - if(!tmpl.compare("rightbrace")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('}')); - return;} - - if(!tmpl.compare("leftparen")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym('(')); - return;} - - if(!tmpl.compare("rightparen")){ - keys << AutoTypeAction(TypeKey, HelperX11::getKeysym(')')); - return;} - - if(!tmpl.compare("winl")){ - keys << AutoTypeAction(TypeKey, XK_Super_L); - return;} - - if(!tmpl.compare("winr")){ - keys << AutoTypeAction(TypeKey, XK_Super_R); - return;} - - if(!tmpl.compare("win")){ - keys << AutoTypeAction(TypeKey, XK_Super_L); - return;} - - if(!tmpl.compare("tab")){ - keys << AutoTypeAction(TypeKey, XK_Tab); - return;} - - if(tmpl.startsWith("delay ") && tmpl.length()>6){ - bool ok; - quint16 delay = tmpl.right(tmpl.length()-6).toInt(&ok); - if (ok && delay>0 && delay<=10000) - keys << AutoTypeAction(Delay, delay); - } -} - -void AutoTypePrivate::stringToKeysyms(const QString& string,QList& KeySymList){ - for(int i=0; igroup(); - int level = group->level(); - for (int i=0; iparent(); - - return group->title(); -} diff --git a/src/lib/EntryView.cpp b/src/lib/EntryView.cpp index 4e95daf..ec73c36 100644 --- a/src/lib/EntryView.cpp +++ b/src/lib/EntryView.cpp @@ -536,9 +536,12 @@ void KeepassEntryView::OnColumnMoved(int LogIndex,int OldVisIndex,int NewVisInde int KeepassEntryView::logicalColIndex(int LstIndex){ int c=-1; for(int i=0;icount();i++){ ColumnSizes[columnListIndex(i)]=header()->sectionSize(i); @@ -611,15 +617,20 @@ void KeepassEntryView::mouseMoveEvent(QMouseEvent *event){ EntryViewItem* DragStartItem=(EntryViewItem*)itemAt(DragStartPos); if(!DragStartItem){ while(selectedItems().size()){ - setItemSelected(selectedItems().first(),false);} + setItemSelected(selectedItems().first(),false); + } return; } if(selectedItems().isEmpty()){ - setItemSelected(DragStartItem,true);} + setItemSelected(DragStartItem,true); + } else{ bool AlreadySelected=false; for(int i=0;iEntryHandle,error); + autoType->perform(((EntryViewItem*)selectedItems().first())->EntryHandle); } #endif diff --git a/src/lib/GroupView.cpp b/src/lib/GroupView.cpp index 71511fa..f0f8a54 100644 --- a/src/lib/GroupView.cpp +++ b/src/lib/GroupView.cpp @@ -60,7 +60,7 @@ void KeepassGroupView::createItems(){ void KeepassGroupView::updateIcons(){ for(int i=0;isetIcon(0,db->icon(Items[i]->GroupHandle->image())); - } + } } void KeepassGroupView::showSearchResults(){ @@ -86,7 +86,7 @@ void KeepassGroupView::addChildren(GroupViewItem* item){ void KeepassGroupView::OnDeleteGroup(){ if(config->askBeforeDelete()){ if(QMessageBox::question(this,tr("Delete?"), - tr("Are you sure you want to delete this group, all it's child groups and all their entries?"), + tr("Are you sure you want to delete this group, all its child groups and all their entries?"), QMessageBox::Yes | QMessageBox::No,QMessageBox::No) == QMessageBox::No) return; } diff --git a/src/lib/HelperX11.cpp b/src/lib/HelperX11.cpp index 221b2ac..41db943 100644 --- a/src/lib/HelperX11.cpp +++ b/src/lib/HelperX11.cpp @@ -21,40 +21,6 @@ #include "HelperX11.h" #include -int HelperX11::getModifiers(Display *d,KeySym keysym, int keycode){ - int SymsPerKey; - KeySym* Syms=XGetKeyboardMapping(d,keycode,1,&SymsPerKey); - int c=-1; - for(int i=0;i<4;i++) - if(Syms[i]==keysym){ - c=i; break; - } - Q_ASSERT(c!=-1); - XFree(Syms); - return c; -} - -void HelperX11::pressModifiers(Display* d,int mods,bool press){ - switch(mods){ - case 0: //no modifier - break; - case 1: //Shift - XTestFakeKeyEvent(d,XKeysymToKeycode(d,XK_Shift_L),press,2); - break; - case 2: //AltGr - XTestFakeKeyEvent(d,XKeysymToKeycode(d,XK_ISO_Level3_Shift),press,2); - break; - case 3: //Shift+AltGr - XTestFakeKeyEvent(d,XKeysymToKeycode(d,XK_Shift_L),press,2); - XTestFakeKeyEvent(d,XKeysymToKeycode(d,XK_ISO_Level3_Shift),press,2); - break; - } -} - -void HelperX11::releaseModifiers(Display* d,int mods){ - pressModifiers(d,mods,False); -} - #ifdef GLOBAL_AUTOTYPE int HelperX11::getShortcutModifierMask(const Shortcut& s){ int mod=0; @@ -889,8 +855,8 @@ quint16 HelperX11::getKeysym(const QChar& c){ int MapSize = sizeof(KeysymMap) / sizeof(quint16) / 2; for (int i=0; iregisterGlobalShortcut(pShortcut); if (!failed) setBackgroundColor(QColor(255, 150, 150)); else diff --git a/src/lib/tools.h b/src/lib/tools.h index ead053a..175b24b 100644 --- a/src/lib/tools.h +++ b/src/lib/tools.h @@ -23,7 +23,7 @@ class IEntryHandle; -typedef enum tKeyType {PASSWORD=0,KEYFILE=1,BOTH=2}; +enum tKeyType {PASSWORD=0,KEYFILE=1,BOTH=2}; struct Translation { QString nameCode; QString nameLong; diff --git a/src/main.cpp b/src/main.cpp index 7de99e7..0e203bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,7 +52,7 @@ int main(int argc, char **argv) initAppPaths(argc,argv); CmdLineArgs args; if(!args.preparse(argc,argv)){ // searches only for the -cfg parameter - qCritical(CSTR( args.error().append("\n") )); + qCritical("%s", CSTR( args.error().append("\n") )); args.printHelp(); return 1; } @@ -88,7 +88,7 @@ int main(int argc, char **argv) if(!plugin.load()){ PluginLoadError=plugin.errorString(); qWarning("Could not load desktop integration plugin:"); - qWarning(CSTR(PluginLoadError)); + qWarning("%s", CSTR(PluginLoadError)); } else{ QObject *plugininstance=plugin.instance(); @@ -128,7 +128,7 @@ int main(int argc, char **argv) #endif } if ( !args.parse(QApplication::arguments()) ){ - qCritical(CSTR( args.error().append("\n") )); + qCritical("%s", CSTR( args.error().append("\n") )); args.printHelp(); return 1; } @@ -151,9 +151,7 @@ int main(int argc, char **argv) QApplication::setQuitOnLastWindowClosed(false); KeepassMainWindow *mainWin = new KeepassMainWindow(args.file(), args.startMinimized(), args.startLocked()); -#ifdef GLOBAL_AUTOTYPE - AutoType::init(); -#endif + int r=app->exec(); delete mainWin; delete eventListener; @@ -255,7 +253,7 @@ QString findPlugin(const QString& filename){ bool EventListener::eventFilter(QObject*, QEvent* event){ if (!EventOccurred){ int t = event->type(); - if ( t>=QEvent::MouseButtonPress&&t<=QEvent::KeyRelease || t>=QEvent::HoverEnter&&t<=QEvent::HoverMove ) + if ( (t>=QEvent::MouseButtonPress && t<=QEvent::KeyRelease) || (t>=QEvent::HoverEnter && t<=QEvent::HoverMove) ) EventOccurred = true; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 038f2c5..a3690fe 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -61,10 +61,10 @@ KeepassMainWindow::KeepassMainWindow(const QString& ArgFile,bool ArgMin,bool Arg setUnifiedTitleAndToolBarOnMac(true); #endif #ifdef AUTOTYPE - AutoType::MainWin=this; + initAutoType(this); #endif #ifdef GLOBAL_AUTOTYPE - AutoType::registerGlobalShortcut(config->globalShortcut()); + autoType->registerGlobalShortcut(config->globalShortcut()); #endif setWindowModified(false); setGeometry(config->mainWindowGeometry(geometry())); @@ -1016,7 +1016,7 @@ void KeepassMainWindow::closeEvent(QCloseEvent* e){ } #ifdef GLOBAL_AUTOTYPE - AutoType::unregisterGlobalShortcut(); + autoType->unregisterGlobalShortcut(); #endif config->setMainWindowGeometry(geometry()); diff --git a/src/src.pro b/src/src.pro index 0079b15..cefd8ff 100644 --- a/src/src.pro +++ b/src/src.pro @@ -45,12 +45,12 @@ unix : !macx : !isEqual(QMAKE_WIN32,1){ INSTALLS += share contains(DEFINES,AUTOTYPE){ LIBS += -lXtst - SOURCES += lib/HelperX11.cpp lib/AutoType_X11.cpp - HEADERS += lib/HelperX11.h + SOURCES += lib/HelperX11.cpp lib/AutoTypeX11.cpp + HEADERS += lib/HelperX11.h lib/AutoTypeX11.h } contains(DEFINES,GLOBAL_AUTOTYPE){ - SOURCES += Application_X11.cpp - HEADERS += Application_X11.h + SOURCES += Application_X11.cpp lib/AutoTypeGlobalX11.cpp + HEADERS += Application_X11.h lib/AutoTypeGlobalX11.h } SOURCES += main_unix.cpp } @@ -93,7 +93,7 @@ macx { #------------------------------------------------------------------------------- isEqual(QMAKE_WIN32,1){ CONFIG += windows - isEmpty(PREFIX): PREFIX = "C:/Program files/KeePassX" + isEmpty(PREFIX): PREFIX = "C:/Program\ files/KeePassX" TARGET = ../bin/KeePassX target.path = $${PREFIX} data.files += ../share/keepassx/* diff --git a/src/translations/keepassx-it_IT.ts b/src/translations/keepassx-it_IT.ts new file mode 100644 index 0000000..876e1a4 --- /dev/null +++ b/src/translations/keepassx-it_IT.ts @@ -0,0 +1,2929 @@ + + + + + AboutDialog + + + $TRANSLATION_AUTHOR + Diego Pierotto + + + + $TRANSLATION_AUTHOR_EMAIL + Here you can enter your email or homepage if you want. + ita.translations@tiscali.it + + + + Information on how to translate KeePassX can be found under: + Informazioni su come tradurre KeePassX si possono trovare qui: + + + + Team + Gruppo + + + + Developer, Project Admin + Sviluppatore, Amministratore progetto + + + + Web Designer + Disegnatore Web + + + + Developer + Sviluppatore + + + + Thanks To + Ringraziamenti + + + + Patches for better MacOS X support + Patches per migliorie a MacOS X + + + + Main Application Icon + Icona applicazione principale + + + + Various fixes and improvements + Alcune correzioni e migliorie + + + + Error + Errore + + + + File '%1' could not be found. + Impossibile trovare il file '%1'. + + + + Make sure that the program is installed correctly. + Assicurati che il programma sia installato correttamente. + + + + OK + OK + + + + Current Translation + Traduzione attuale + + + + None + Please replace 'None' with the language of your translation + Italiano + + + + Author + Autore + + + + AboutDlg + + + About + Informazioni su + + + + AppName + AppName + + + + AppFunc + AppFunc + + + + http://keepassx.sourceforge.net + http://keepassx.sourceforge.net + + + + keepassx@gmail.com + keepassx@gmail.com + + + + Credits + Crediti + + + + Translation + Traduzione + + + + License + Licenza + + + + Copyright (C) 2005 - 2008 KeePassX Team +KeePassX is distributed under the terms of the +General Public License (GPL) version 2. + Copyright (C) 2005 - 2008 KeePassX Team +KeePassX è distribuito sotto i termini della +General Public License (GPL) versione 2. + + + + AddBookmarkDlg + + + Add Bookmark + Aggiungi ai Segnalibri + + + + Title: + Titolo: + + + + File: + File: + + + + Browse... + Sfoglia... + + + + Edit Bookmark + Modifica i Segnalibri + + + + KeePass Databases (*.kdb) + Database KeePass (*.kdb) + + + + All Files (*) + Tutti i files (*) + + + + AutoType + + + More than one 'Auto-Type:' key sequence found. +Allowed is only one per entry. + Trovate più di una sequenza chiave di 'Auto Digitazione:'. +E' permessa solo una per voce. + + + + Syntax Error in Auto-Type sequence near character %1 +Found '{' without closing '}' + Errore sintassi nella sequenza Auto Digitazione vicina al carattere %1 +Trovati '{' senza chiusura '}' + + + + Auto-Type string contains invalid characters + La stringa di Auto Digitazione contiene caratteri non validi + + + + AutoTypeDlg + + + KeePassX - Auto-Type + KeePassX - Auto Digitazione + + + + Click on an entry to auto-type it. + Clicca su una voce per Auto digitarlo. + + + + Group + Gruppo + + + + Title + Titolo + + + + Username + Nome utente + + + + Auto-Type + Auto Digitazione + + + + CDbSettingsDlg + + + Settings + Impostazioni + + + + AES(Rijndael): 256 Bit (default) + AES(Rijndael): 256 Bit (predefinito) + + + + Twofish: 256 Bit + Twofish: 256 Bit + + + + Warning + Attenzione + + + + Please determine the number of encryption rounds. + Determina il numero di passaggi di cifratura. + + + + OK + OK + + + + Error + Errore + + + + '%1' is not valid integer value. + '%1' non è un valore integer valido. + + + + The number of encryption rounds have to be greater than 0. + Il numero di passaggi di cifratura deve essere maggiore di 0. + + + + CEditEntryDlg + + + Today + Oggi + + + + 1 Week + 1 Settimana + + + + 2 Weeks + 2 Settimane + + + + 3 Weeks + 3 Settimane + + + + 1 Month + 1 Mese + + + + 3 Months + 3 Mesi + + + + 6 Months + 6 Mesi + + + + 1 Year + 1 Anno + + + + Calendar... + Calendario... + + + + %1 Bit + %1 Bit + + + + Edit Entry + Modifica voce + + + + Warning + Attenzione + + + + Password and password repetition are not equal. +Please check your input. + La password e la conferma password non sono uguali. +Verifica i valori inseriti. + + + + OK + OK + + + + [Untitled Entry] + [Voce senza titolo] + + + + Add Attachment... + Aggiungi allegato... + + + + Error + Errore + + + + Could not open file. + Impossibile aprire il file. + + + + The chosen entry has no attachment or it is empty. + La voce scelta non ha allegati oppure è vuota. + + + + Save Attachment... + Salva allegato... + + + + Error while writing the file. + Errore durante la scrittura del file. + + + + Delete Attachment? + Eliminare allegato? + + + + You are about to delete the attachment of this entry. +Are you sure? + Stai per eliminare l'allegato di questa voce. +Sei sicuro? + + + + Yes + + + + + No, Cancel + No, Annulla + + + + New Entry + Nuova voce + + + + CGenPwDialog + + + Password Generator + Generatore di password + + + + Notice + Avviso + + + + You need to enter at least one character + Devi inserire almeno un carattere + + + + OK + OK + + + + %1 Bits + %1 Bits + + + + CSelectIconDlg + + + Replace... + Sostituisci... + + + + Delete + Elimina + + + + Add Custom Icon + Aggiungi icona personalizzata + + + + Pick + Seleziona + + + + Add Icons... + Aggiungi icone... + + + + Images (%1) + Immagini (%1) + + + + %1: File could not be loaded. + %1: Impossibile caricare il file. + + + + Error + Errore + + + + An error occured while loading the icon(s): + Errore durante il caricamento dell'icona(e): + + + + An error occured while loading the icon. + Errore durante il caricamento dell'icona. + + + + CSettingsDlg + + + Settings + Impostazioni + + + + Select a directory... + Seleziona una directory... + + + + Select an executable... + Seleziona un eseguibile... + + + + CalendarDialog + + + Calendar + Calendario + + + + CollectEntropyDlg + + + Random Number Generator + Generatore numero casuale + + + + Collecting entropy... +Please move the mouse and/or press some keys until enought entropy for a reseed of the random number generator is collected. + Impostazione entropia... +Sposta il mouse e/o premi alcuni tasti finché ci sia sufficiente entropia affinché il generatore imposti un numero casuale. + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Verdana'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#006400;">Random pool successfully reseeded!</span></p></body></html> + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Verdana'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#006400;">Insieme casuale generato correttamente!</span></p></body></html> + + + + Entropy Collection + Accumulazione entropia + + + + CustomizeDetailViewDialog + + + Dialog + Finestra di dialogo + + + + Rich Text Editor + Editor Rich Text + + + + Bold + Grassetto + + + + B + G + + + + Italic + Corsivo + + + + I + C + + + + Underlined + Sottolineato + + + + U + S + + + + Left-Aligned + Allineato a sinistra + + + + L + S + + + + Centered + Centrato + + + + C + C + + + + Right-Aligned + Allineato a destra + + + + R + D + + + + Justified + Giustificato + + + + Text Color + Colore testo + + + + Font Size + Dimensione carattere + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + 10 + 10 + + + + 11 + 11 + + + + 12 + 12 + + + + 14 + 14 + + + + 16 + 16 + + + + 18 + 18 + + + + 20 + 20 + + + + 22 + 22 + + + + 24 + 24 + + + + 26 + 26 + + + + 28 + 28 + + + + 36 + 36 + + + + 42 + 42 + + + + 78 + 78 + + + + Templates + Modelli + + + + T + M + + + + HTML + HTML + + + + Group + Gruppo + + + + Title + Titolo + + + + Username + Nome utente + + + + Password + Password + + + + Url + Url + + + + Comment + Commento + + + + Attachment Name + Nome allegato + + + + Creation Date + Data creazione + + + + Last Access Date + Data ultimo accesso + + + + Last Modification Date + Data ultima modifica + + + + Expiration Date + Data scadenza + + + + Time till Expiration + Tempo fino alla scadenza + + + + Database + + + Never + Mai + + + + DatabaseSettingsDlg + + + Database Settings + Impostazioni Database + + + + Encryption + Cifratura + + + + Algorithm: + Algoritmo: + + + + Encryption Rounds: + Passaggi di cifratura: + + + + Calculate rounds for a 1-second delay on this computer + Calcola passaggi con ritardo di un secondo su questo computer + + + + DetailViewTemplate + + + Group + Gruppo + + + + Title + Titolo + + + + Username + Nome utente + + + + Password + Password + + + + URL + URL + + + + Creation + Creazione + + + + Last Access + Ultimo accesso + + + + Last Modification + Ultima modifica + + + + Expiration + Scadenza + + + + Comment + Commento + + + + EditEntryDialog + + + Edit Entry + Modifica voce + + + + Ge&n. + Ge&n. + + + + Quality: + Qualità: + + + + Attachment: + Allegato: + + + + Title: + Titolo: + + + + Username: + Nome utente: + + + + Comment: + Commento: + + + + %1 + %1 + + + + URL: + URL: + + + + Group: + Gruppo: + + + + Password Repet.: + Ripetizione password: + + + + Password: + Password: + + + + Expires: + Scade: + + + + Never + Mai + + + + %1 Bit + %1 Bit + + + + Icon: + Icona: + + + + EditGroupDialog + + + Group Properties + Proprietà gruppo + + + + Icon: + Icona: + + + + Title: + Titolo: + + + + > + > + + + + ExpiredEntriesDialog + + + Expired Entries + Voce scaduta + + + + Double click on an entry to jump to it. + Doppio click sulla voce per aprirla. + + + + Group + Gruppo + + + + Title + Titolo + + + + Username + Nome utente + + + + Expired + Scaduta + + + + Expired Entries in the Database + Voci scadute nel Database + + + + Export_KeePassX_Xml + + + KeePassX XML File + File XML KeePassX + + + + XML Files (*.xml) + Files XML (*.xml) + + + + All Files (*) + Tutti i files (*) + + + + Export_Txt + + + Text File + File di testo + + + + All Files (*) + Tutti i files (*) + + + + Text Files (*.txt) + File di testo (*.txt) + + + + ExporterBase + + + Import File... + Importa file... + + + + Export Failed + Esportazione fallita + + + + FileErrors + + + No error occurred. + Non si è verificato alcun errore. + + + + An error occurred while reading from the file. + Si è verificato un errore durante la lettura del file. + + + + An error occurred while writing to the file. + Si è verificato un errore durante la scrittura del file. + + + + A fatal error occurred. + Si è verificato un errore fatale. + + + + An resource error occurred. + Si è verificato un errore di risorsa. + + + + The file could not be opened. + Impossibile aprire il file. + + + + The operation was aborted. + L'operazione è stata terminata. + + + + A timeout occurred. + Si è verificata una scadenza. + + + + An unspecified error occurred. + Si è verificato un errore non specificato. + + + + The file could not be removed. + Impossibile rimuovere il file. + + + + The file could not be renamed. + Impossibile rinominare il file. + + + + The position in the file could not be changed. + La posizione nel file non può essere modificata. + + + + The file could not be resized. + Impossibile ridimensionare il file. + + + + The file could not be accessed. + Impossibile accedere al file. + + + + The file could not be copied. + Impossibile copiare il file. + + + + GenPwDlg + + + Password Generator + Generatore di password + + + + Options + Opzioni + + + + Use follo&wing character groups: + Utilizza i se&guenti gruppi di carattere: + + + + Alt+W + Alt+G + + + + &Lower Letters + Lettere M&inuscole + + + + Alt+L + Alt+I + + + + U&nderline + So&ttolineato + + + + Alt+N + Alt+T + + + + &Numbers + &Numeri + + + + White &Spaces + &Spazi vuoti + + + + Alt+S + Alt+S + + + + &Upper Letters + Lettere M&aiuscole + + + + Alt+U + Alt+A + + + + Minus + Meno + + + + &Special Characters + Caratteri &Speciali + + + + Use &only following characters: + Utilizza s&olo i seguenti caratteri: + + + + Alt+O + Alt+O + + + + Length: + Lunghezza: + + + + Quality: + Qualità: + + + + Enable entropy collection + Abilita accumulazione entropia + + + + Alt+M + Alt+M + + + + Collect only once per session + Imposta solo una volta per sessione + + + + New Password: + Nuova password: + + + + Generate + Genera + + + + Import_KWalletXml + + + XML Files (*.xml) + Files XML (*.xml) + + + + All Files (*) + Tutti i files (*) + + + + Import Failed + Importazione fallita + + + + Invalid XML data (see stdout for details). + Dati XML non validi (vedi stdout per dettagli). + + + + Invalid XML file. + File XML non valido. + + + + Document does not contain data. + Il documento non contiene dati. + + + + Import_KeePassX_Xml + + + KeePass XML Files (*.xml) + File XML KeePass (*.xml) + + + + All Files (*) + Tutti i files (*) + + + + Import Failed + Importazione fallita + + + + XML parsing error on line %1 column %2: +%3 + Errore analisi XML nella riga %1 colonna %2: +%3 + + + + Parsing error: File is no valid KeePassX XML file. + Errore analisi: Il file non è un valido file XML di KeePassX. + + + + Import_PwManager + + + PwManager Files (*.pwm) + Files PwManager (*.pwm) + + + + All Files (*) + Tutti i files (*) + + + + Import Failed + Importazione fallita + + + + File is empty. + Il fIle è vuoto. + + + + File is no valid PwManager file. + Il file non è un valido file PwManager. + + + + Unsupported file version. + Versione file non supportata. + + + + Unsupported hash algorithm. + Algoritmo di hash non supportato. + + + + Unsupported encryption algorithm. + Algoritmo di cifratura non supportato. + + + + Compressed files are not supported yet. + I file compressi non sono ancora supportati. + + + + Wrong password. + Password errata. + + + + File is damaged (hash test failed). + Il file è danneggiato (prova di hash fallita). + + + + Invalid XML data (see stdout for details). + Dati XML non validi (vedi stdout per dettagli). + + + + ImporterBase + + + Import File... + Importa file... + + + + Import Failed + Importazione fallita + + + + Kdb3Database + + + Could not open file. + Impossibile aprire il file. + + + + Unexpected file size (DB_TOTAL_SIZE < DB_HEADER_SIZE) + Dimensione file inattesa (DB_TOTAL_SIZE < DB_HEADER_SIZE) + + + + Wrong Signature + Firma errata + + + + Unsupported File Version. + Versione file non supportata. + + + + Unknown Encryption Algorithm. + Algoritmo di cifratura sconosciuto. + + + + Decryption failed. +The key is wrong or the file is damaged. + Decifratura fallita. +La chiave è errata oppure il file è danneggiato. + + + + Hash test failed. +The key is wrong or the file is damaged. + Prova di hash fallita. +La chiave è errata oppure il file è danneggiato. + + + + Unexpected error: Offset is out of range. + Errore inatteso: La posizione è fuori campo. + + + + Invalid group tree. + Albero del gruppo non valido. + + + + Key file is empty. + Il fIle chiave è vuoto. + + + + The database must contain at least one group. + Il database deve contenere almeno un gruppo. + + + + Could not open file for writing. + Impossibile aprire il file per la scrittura. + + + + Kdb3Database::EntryHandle + + + Bytes + Bytes + + + + KiB + KB + + + + MiB + MB + + + + GiB + GB + + + + KeepassEntryView + + + Delete? + Eliminare? + + + + Error + Errore + + + + At least one group must exist before adding an entry. + Deve esistere almeno un gruppo prima di aggiungere una voce. + + + + OK + OK + + + + Title + Titolo + + + + Username + Nome utente + + + + URL + URL + + + + Password + Password + + + + Comments + Commenti + + + + Expires + Scade + + + + Creation + Creazione + + + + Last Change + Ultima modifica + + + + Last Access + Ultimo accesso + + + + Attachment + Allegato + + + + Group + Gruppo + + + + Are you sure you want to delete this entry? + Sei sicuro di voler eliminare questa voce? + + + + Are you sure you want to delete these %1 entries? + Sei sicuro di voler eliminare queste %1 voci? + + + + KeepassGroupView + + + Search Results + Risultati della ricerca + + + + Delete? + Eliminare? + + + + Are you sure you want to delete this group, all it's child groups and all their entries? + Sei sicuro di voler eliminare questo gruppo, tutti i suoi sottogruppi e le loro voci? + + + + KeepassMainWindow + + + Ready + Pronto + + + + Locked + Bloccato + + + + Unlocked + Sbloccato + + + + Ctrl+O + Ctrl+O + + + + Ctrl+S + Ctrl+S + + + + Ctrl+L + Ctrl+L + + + + Ctrl+Q + Ctrl+Q + + + + Ctrl+G + Ctrl+G + + + + Ctrl+C + Ctrl+C + + + + Ctrl+B + Ctrl+B + + + + Ctrl+U + Ctrl+U + + + + Ctrl+Y + Ctrl+Y + + + + Ctrl+E + Ctrl+E + + + + Ctrl+D + Ctrl+D + + + + Ctrl+K + Ctrl+K + + + + Ctrl+F + Ctrl+F + + + + Ctrl+V + Ctrl+V + + + + Ctrl+W + Ctrl+W + + + + Shift+Ctrl+S + Shift+Ctrl+S + + + + Shift+Ctrl+F + Shift+Ctrl+F + + + + Error + Errore + + + + The database file does not exist. + Il file di database non esiste. + + + + Loading Database... + Caricamento Database... + + + + Loading Failed + Caricamento fallito + + + + Unknown error while loading database. + Errore sconosciuto durante il caricamento del database. + + + + The following error occured while opening the database: + Si è verificato il seguente errore durante l'apertura del database: + + + + Save modified file? + Salvare il file modificato? + + + + The current file was modified. Do you want +to save the changes? + Il file attuale è stato modificato. Vuoi +salvare le modifiche? + + + + new + nuovo + + + + Open Database... + Apri Database... + + + + KeePass Databases (*.kdb) + Database KeePass (*.kdb) + + + + All Files (*) + Tutti i files (*) + + + + Expired + Scaduta + + + + 1 Month + 1 Mese + + + + %1 Months + %1 Mesi + + + + 1 Year + 1 Anno + + + + %1 Years + %1 Anni + + + + 1 Day + 1 Giorno + + + + %1 Days + %1 Giorni + + + + less than 1 day + meno di 1 giorno + + + + Clone Entry + Duplica voce + + + + Delete Entry + Elimina voce + + + + Clone Entries + Duplica voci + + + + Delete Entries + Elimina voci + + + + File could not be saved. + Impossibile salvare il file. + + + + Save Database... + Salva Database... + + + + Un&lock Workspace + Sb&locca l'area di lavoro + + + + &Lock Workspace + &Blocca l'area di lavoro + + + + Show &Toolbar + Mostra barra degli &strumenti + + + + Ctrl+N + Ctrl+N + + + + Ctrl+P + Ctrl+P + + + + Ctrl+X + Ctrl+X + + + + Main + + + Error + Errore + + + + File '%1' could not be found. + Impossibile trovare il file '%1'. + + + + OK + OK + + + + MainWindow + + + KeePassX + KeePassX + + + + Groups + Gruppi + + + + &Help + &Guida + + + + &File + &File + + + + &Export to... + Esp&orta in... + + + + &Import from... + Im&porta da... + + + + &Edit + &Modifica + + + + &View + &Visualizza + + + + E&xtras + &Utilità + + + + &Open Database... + &Apri Database... + + + + &Close Database + &Chiudi Database + + + + &Save Database + &Salva Database + + + + Save Database &As... + Save Database &come... + + + + &Database Settings... + Impostazioni &Database... + + + + Change &Master Key... + Cambia la chiave &principale... + + + + &Lock Workspace + &Blocca l'area di lavoro + + + + &Settings... + &Impostazioni... + + + + &About... + &Informazioni su... + + + + &KeePassX Handbook... + Manuale &KeePassX... + + + + Hide + Nascondi + + + + Standard KeePass Single User Database (*.kdb) + Database KeePass standard a singolo utente (*.kdb) + + + + Advanced KeePassX Database (*.kxdb) + Database KeePassX avanzato (*.kxdb) + + + + Recycle Bin... + Cestino... + + + + &Bookmarks + &Segnalibri + + + + Toolbar &Icon Size + Dimensione &icona barra degli strumenti + + + + &Columns + &Colonne + + + + &Manage Bookmarks... + Gestisci i Se&gnalibri... + + + + &Quit + E&sci + + + + &Add New Group... + &Aggiungi nuovo gruppo... + + + + &Edit Group... + Modi&fica gruppo... + + + + &Delete Group + Elimina &gruppo + + + + Copy Password &to Clipboard + Copia la password negli &Appunti + + + + Copy &Username to Clipboard + Copia il nome &utente negli Appunti + + + + &Open URL + &Apri URL + + + + &Save Attachment As... + &Salva allegato come... + + + + Add &New Entry... + Aggiungi &nuova voce... + + + + &View/Edit Entry... + &Visualizza/Modifica voce... + + + + De&lete Entry + E&limina voce + + + + &Clone Entry + &Duplica voce + + + + Search &in Database... + Cerca &nel Database... + + + + Search in this &Group... + Cerca in questo &gruppo... + + + + Show &Entry Details + Mostra d&ettagli voce + + + + Hide &Usernames + Nascondi nomi &utente + + + + Hide &Passwords + Nascondi &password + + + + &Title + &Titolo + + + + User&name + &Nome utente + + + + &URL + &URL + + + + &Password + &Password + + + + &Comment + &Commento + + + + E&xpires + &Scade + + + + C&reation + C&reazione + + + + &Last Change + U&ltima modifica + + + + Last &Access + Ultimo &accesso + + + + A&ttachment + Allega&to + + + + Show &Statusbar + Mostra la barra di &stato + + + + &Perform AutoType + Esegui Auto &Digitazione + + + + &16x16 + &16x16 + + + + &22x22 + &22x22 + + + + 2&8x28 + 2&8x28 + + + + &New Database... + &Nuovo Database... + + + + &Password Generator... + Generatore di &password... + + + + &Group (search results only) + &Gruppo (ricerca solo di risultati) + + + + Show &Expired Entries... + Mostra voci scadut&e... + + + + &Add Bookmark... + &Aggiungi ai Segnalibri... + + + + Bookmark &this Database... + Imposta il Database come &Segnalibro... + + + + ManageBookmarksDlg + + + Manage Bookmarks + Gestisci Segnalibri + + + + PasswordDialog + + + Enter Master Key + Inserisci la chiave principale + + + + Set Master Key + Imposta la chiave principale + + + + Change Master Key + Cambia chiave principale + + + + Database Key + Chiave Database + + + + Last File + Ultimo file + + + + Select a Key File + Seleziona un file chiave + + + + All Files (*) + Tutti i files (*) + + + + Key Files (*.key) + File chiave (*.key) + + + + Please enter a Password or select a key file. + Inserisci una password o seleziona un file chiave. + + + + Please enter a Password. + Insersci una password. + + + + Please provide a key file. + Fornisci un file chiave. + + + + %1: +No such file or directory. + %1: +Nessun file o directory. + + + + The selected key file or directory is not readable. + Il file chiave o la directory selezionata non è leggibile. + + + + The given directory does not contain any key files. + La directory selezionata non contiene alcun file chiave. + + + + The given directory contains more then one key files. +Please specify the key file directly. + La directory selezionata contiene più di un file chiave. +Specifica il file chiave direttamente. + + + + %1: +File is not readable. + %1: +Il file non è leggibile. + + + + Create Key File... + Crea un file chiave... + + + + PasswordDlg + + + Last File + Ultimo file + + + + Enter a Password and/or choose a key file. + Inserisci la password e/o seleziona il file chiave. + + + + Key + Chiave + + + + Password: + Password: + + + + &Browse... + &Sfoglia... + + + + Alt+B + Alt+S + + + + Key File: + File chiave: + + + + Generate Key File... + Genera file chiave... + + + + Please repeat your password: + Ripeti la password: + + + + Back + Indietro + + + + Passwords are not equal. + Le password non corrispondono. + + + + QObject + + + Could not locate library file. + Impossibile trovare il file di libreria. + + + + SearchDialog + + + Search + Cerca + + + + Search_Dlg + + + Search... + Cerca... + + + + Include: + Includi: + + + + Pass&words + Pass&words + + + + Alt+W + Alt+W + + + + A&nhang + A&nhang + + + + Alt+N + Alt+N + + + + U&RLs + U&RL + + + + Alt+R + Alt+R + + + + C&omments + C&ommenti + + + + Alt+O + Alt+O + + + + &Usernames + Nomi &Utente + + + + Alt+U + Alt+U + + + + &Titles + &Titoli + + + + Alt+T + Alt+T + + + + &Case Sensitive + &Case Sensitive + + + + Alt+C + Alt+C + + + + Regular E&xpression + &Espressione regolare + + + + Alt+X + Alt+E + + + + Include Subgroups (recursive) + Includi sottogruppi (ricorsivo) + + + + Search For: + Cerca per: + + + + SelectIconDlg + + + Icon Selection + Selezione icona + + + + SettingsDialog + + + Settings + Impostazioni + + + + The integration plugins provide features like usage of the native file dialogs and message boxes of the particular desktop environments. + L'integrazione dei plugins fornisce caratteristiche come l'uso di file di finestre di dialogo nativi e caselle messaggi degli ambienti desktop particolari. + + + + General + Generale + + + + Show system tray icon + Mostra icona nella barra di sistema + + + + Minimize to tray instead of taskbar + Riduci a icona nella barra di sistema anzichè nella barra delle applicazioni + + + + Minimize to tray when clicking the main window's close button + Riduci alla barra di sistema al click del pulsante chiudi della finestra principale + + + + Remember last opened file + Ricorda l'ultimo file aperto + + + + Alt+Ö + Alt+Ö + + + + Remember last key type and location + Ricorda l'ultima chiave digitata e la posizione + + + + Start minimized + Avvia ridotto a icona + + + + Start locked + Avvia bloccato + + + + Save recent directories of file dialogs + Salva directory recenti dei file di dialoghi + + + + Clear History Now + Pulisci ora la cronologia + + + + Always ask before deleting entries or groups + Chiedi sempre prima di eliminare voci o gruppi + + + + Appea&rance + Asp&etto + + + + Banner Color + Colore banner + + + + Text Color: + Colore testo: + + + + Change... + Cambia... + + + + Color 2: + Colore 2: + + + + C&hange... + Ca&mbia... + + + + Alt+H + Alt+M + + + + Color 1: + Colore 1: + + + + Alternating Row Colors + Colore alternativo delle righe + + + + Customize Entry Detail View... + Personalizza la voce Visualizza dettagli... + + + + Group tree at start-up: + Albero del gruppo all'avvio: + + + + Restore last state + Ripristina ultimo stato + + + + Expand all items + Espandi tutti i valori + + + + Do not expand any item + Non espandere alcun valore + + + + Security + Sicurezza + + + + Edit Entry Dialog + Modifica finestra di dialogo della voce + + + + Alt+O + Alt+O + + + + Clear clipboard after: + Pulisci gli Appunti dopo: + + + + Lock workspace when minimizing the main window + Blocca l'area di lavoro quando riduci a icona la finestra principale + + + + Features + Caratteristiche + + + + You can disable several features of KeePassX here according to your needs in order to keep the user interface slim. + Qui puoi disabilitare alcune caratteristiche di KeePassX a seconda delle tue necessità in modo da mantenere snella l'interfaccia utente. + + + + Bookmarks + Segnalibri + + + + Desktop Integration + Integrazione con il Desktop + + + + Plug-Ins + Plug-Ins + + + + None + Nessuno + + + + Gnome Desktop Integration (Gtk 2.x) + Integrazione con il Desktop di Gnome (Gtk 2.x) + + + + KDE 4 Desktop Integration + Integrazione con il Desktop di KDE 4 + + + + You need to restart the program before the changes take effect. + Devi riavviare il programma per rendere effettivi i cambiamenti. + + + + Configure... + Configura... + + + + Advanced + Avanzate + + + + Auto-Type Fine Tuning + Regola in modo fine l'Auto Digitazione + + + + Time between the activation of an auto-type action by the user and the first simulated key stroke. + Tempo tra l'attivazione di un'azione da parte dell'utente di Auto Digitazione e la pressione della prima chiave simulata. + + + + ms + ms + + + + Pre-Gap: + Differenza precedente: + + + + Key Stroke Delay: + Ritardo pressione tasti: + + + + Delay between two simulated key strokes. Increase this if Auto-Type is randomly skipping characters. + Ritardo tra due pressioni dei tasti simulati. Aumentalo se l'Auto Digitazione salta casualmente i caratteri. + + + + Custom Browser Command + Personalizza il comando Sfoglia + + + + Browse + Sfoglia + + + + Media Root: + Radice dei media: + + + + The directory where storage devices like CDs and memory sticks are normally mounted. + La directory dove le periferiche di salvataggio come CD e chiavette USB vengono montate di solito. + + + + Browse... + Sfoglia... + + + + Enable this if you want to use your bookmarks and the last opened file independet from their absolute paths. This is especially useful when using KeePassX portably and therefore with changing mount points in the file system. + Abilita questo se vuoi usare i segnalibri e l'ultimo file aperto indipendentemente dai loro percorsi assoluti. Questo è utile specialmente quando si usa KeePassX in modo portatile e perciò i punti di mount cambiano nel file system. + + + + Save relative paths (bookmarks and last file) + Salva i percorsi relativi (segnalibri e ultimo file) + + + + Global Auto-Type Shortcut: + Collegamento Auto Digitazione globale: + + + + Automatically save database on exit and workspace locking + Salva automaticamente il database all'uscita e blocca l'area di lavoro + + + + Show plain text passwords in: + Mostra password in chiaro in: + + + + Database Key Dialog + Finestra chiave database + + + + seconds + secondi + + + + Lock database after inactivity of + Blocca il database dopo inattività di + + + + Use entries' title to match the window for Global Auto-Type + Utilizza i titoli della voce per far corrispondere la finestra di Auto Digitazione Globale + + + + ShortcutWidget + + + Ctrl + Ctrl + + + + Shift + Shift + + + + Alt + Alt + + + + AltGr + AltGr + + + + Win + Win + + + + SimplePasswordDialog + + + Enter your Password + Inserisci la Password + + + + Password: + Password: + + + + WorkspaceLockedWidget + + + Form + Casella + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Verdana'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">The workspace is locked.</span></p></body></html> + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Verdana'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">L'area di lavoro è bloccata.</span></p></body></html> + + + + Unlock + Sblocca + + + + Close Database + Chiudi Database + + + diff --git a/todo b/todo deleted file mode 100644 index 5f0beb1..0000000 --- a/todo +++ /dev/null @@ -1,5 +0,0 @@ -Mass modify entries -Backup group (exclude from search) -Improve password generator -Manually select language -kde4 plugin: clear klipper history \ No newline at end of file