void DatabaseTabWidget::saveDatabaseAs(Database* db) { DatabaseManagerStruct& dbStruct = m_dbList[db]; QString oldFileName; if (dbStruct.saveToFilename) { oldFileName = dbStruct.filePath; } QString fileName = fileDialog()->getSaveFileName(this, tr("Save database as"), oldFileName, tr("KeePass 2 Database").append(" (*.kdbx)")); if (!fileName.isEmpty()) { bool result = false; QSaveFile saveFile(fileName); if (saveFile.open(QIODevice::WriteOnly)) { m_writer.writeDatabase(&saveFile, db); result = saveFile.commit(); } if (result) { dbStruct.modified = false; dbStruct.saveToFilename = true; QFileInfo fileInfo(fileName); dbStruct.filePath = fileInfo.absoluteFilePath(); dbStruct.canonicalFilePath = fileInfo.canonicalFilePath(); dbStruct.fileName = fileInfo.fileName(); dbStruct.dbWidget->updateFilename(dbStruct.filePath); updateTabName(db); updateLastDatabases(dbStruct.filePath); } else { MessageBox::critical(this, tr("Error"), tr("Writing the database failed.") + "\n\n" + saveFile.errorString()); } } }
void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw, const QString& keyFile) { QFileInfo fileInfo(fileName); QString canonicalFilePath = fileInfo.canonicalFilePath(); if (canonicalFilePath.isEmpty()) { MessageBox::warning(this, tr("Warning"), tr("File not found!")); return; } QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList); while (i.hasNext()) { i.next(); if (i.value().canonicalFilePath == canonicalFilePath) { setCurrentIndex(databaseIndex(i.key())); return; } } DatabaseManagerStruct dbStruct; // test if we can read/write or read the file QFile file(fileName); // TODO: error handling if (!file.open(QIODevice::ReadWrite)) { if (!file.open(QIODevice::ReadOnly)) { // can't open // TODO: error message return; } else { // can only open read-only dbStruct.readOnly = true; } } file.close(); Database* db = new Database(); dbStruct.dbWidget = new DatabaseWidget(db, this); dbStruct.saveToFilename = !dbStruct.readOnly; dbStruct.filePath = fileInfo.absoluteFilePath(); dbStruct.canonicalFilePath = canonicalFilePath; dbStruct.fileName = fileInfo.fileName(); insertDatabase(db, dbStruct); updateLastDatabases(dbStruct.filePath); if (!pw.isNull() || !keyFile.isEmpty()) { dbStruct.dbWidget->switchToOpenDatabase(dbStruct.filePath, pw, keyFile); } else { dbStruct.dbWidget->switchToOpenDatabase(dbStruct.filePath); } }
bool DatabaseTabWidget::saveDatabaseAs(Database* db) { DatabaseManagerStruct& dbStruct = m_dbList[db]; QString oldFileName; if (dbStruct.saveToFilename) { oldFileName = dbStruct.filePath; } else { oldFileName = tr("New database").append(".kdbx"); } QString fileName = fileDialog()->getSaveFileName(this, tr("Save database as"), oldFileName, tr("KeePass 2 Database").append(" (*.kdbx)"), nullptr, 0, "kdbx"); if (!fileName.isEmpty()) { QFileInfo fileInfo(fileName); QString lockFilePath; if (fileInfo.exists()) { // returns empty string when file doesn't exist lockFilePath = fileInfo.canonicalPath(); } else { lockFilePath = fileInfo.absolutePath(); } QString lockFileName = QString("%1/.%2.lock").arg(lockFilePath, fileInfo.fileName()); QScopedPointer<QLockFile> lockFile(new QLockFile(lockFileName)); lockFile->setStaleLockTime(0); if (!lockFile->tryLock()) { // for now silently ignore if we can't create a lock file // due to lack of permissions if (lockFile->error() != QLockFile::PermissionError) { QMessageBox::StandardButton result = MessageBox::question(this, tr("Save database as"), tr("The database you are trying to save as is locked by another instance of KeePassX.\n" "Do you want to save it anyway?"), QMessageBox::Yes | QMessageBox::No); if (result == QMessageBox::No) { return false; } else { // take over the lock file if possible if (lockFile->removeStaleLockFile()) { lockFile->tryLock(); } } } } QSaveFile saveFile(fileName); if (!saveFile.open(QIODevice::WriteOnly)) { MessageBox::critical(this, tr("Error"), tr("Writing the database failed.") + "\n\n" + saveFile.errorString()); return false; } m_writer.writeDatabase(&saveFile, db); if (m_writer.hasError()) { MessageBox::critical(this, tr("Error"), tr("Writing the database failed.") + "\n\n" + m_writer.errorString()); return false; } if (!saveFile.commit()) { MessageBox::critical(this, tr("Error"), tr("Writing the database failed.") + "\n\n" + saveFile.errorString()); return false; } dbStruct.modified = false; dbStruct.saveToFilename = true; dbStruct.readOnly = false; dbStruct.filePath = fileInfo.absoluteFilePath(); dbStruct.canonicalFilePath = fileInfo.canonicalFilePath(); dbStruct.fileName = fileInfo.fileName(); dbStruct.dbWidget->updateFilename(dbStruct.filePath); delete dbStruct.lockFile; dbStruct.lockFile = lockFile.take(); updateTabName(db); updateLastDatabases(dbStruct.filePath); return true; } else { return false; } }
void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw, const QString& keyFile) { QFileInfo fileInfo(fileName); QString canonicalFilePath = fileInfo.canonicalFilePath(); if (canonicalFilePath.isEmpty()) { MessageBox::warning(this, tr("Warning"), tr("File not found!")); return; } QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList); while (i.hasNext()) { i.next(); if (i.value().canonicalFilePath == canonicalFilePath) { setCurrentIndex(databaseIndex(i.key())); return; } } DatabaseManagerStruct dbStruct; // test if we can read/write or read the file QFile file(fileName); if (!file.open(QIODevice::ReadWrite)) { if (!file.open(QIODevice::ReadOnly)) { MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n") .append(file.errorString())); return; } else { // can only open read-only dbStruct.readOnly = true; } } file.close(); QLockFile* lockFile = new QLockFile(QString("%1/.%2.lock").arg(fileInfo.canonicalPath(), fileInfo.fileName())); lockFile->setStaleLockTime(0); if (!dbStruct.readOnly && !lockFile->tryLock()) { // for now silently ignore if we can't create a lock file // due to lack of permissions if (lockFile->error() != QLockFile::PermissionError) { QMessageBox::StandardButton result = MessageBox::question(this, tr("Open database"), tr("The database you are trying to open is locked by another instance of KeePassX.\n" "Do you want to open it anyway? Alternatively the database is opened read-only."), QMessageBox::Yes | QMessageBox::No); if (result == QMessageBox::No) { dbStruct.readOnly = true; delete lockFile; lockFile = nullptr; } else { // take over the lock file if possible if (lockFile->removeStaleLockFile()) { lockFile->tryLock(); } } } } Database* db = new Database(); dbStruct.dbWidget = new DatabaseWidget(db, this); dbStruct.lockFile = lockFile; dbStruct.saveToFilename = !dbStruct.readOnly; dbStruct.filePath = fileInfo.absoluteFilePath(); dbStruct.canonicalFilePath = canonicalFilePath; dbStruct.fileName = fileInfo.fileName(); insertDatabase(db, dbStruct); updateLastDatabases(dbStruct.filePath); if (!pw.isNull() || !keyFile.isEmpty()) { dbStruct.dbWidget->switchToOpenDatabase(dbStruct.filePath, pw, keyFile); } else { dbStruct.dbWidget->switchToOpenDatabase(dbStruct.filePath); } }