// Расшифровка аттача на диске и в памяти void Attach::decrypt(unsigned int area) { // Если аттач не зашифрован, и происходит расшифровка, значит есть какая-то ошибка в логике выше if(getField("crypt")!="1") criticalError("Attach::decrypt() : Cant decrypt unencrypted attach."); // Расшифровывается файл if(area & areaFile) if(getField("type")=="file") CryptService::decryptFile(globalParameters.getCryptKey(), getFullInnerFileName()); // Расшифровывается содержимое файла в памяти, если таковое есть if(area & areaMemory) if(liteFlag==false && fileContent.length()>0) fileContent=CryptService::decryptByteArray(globalParameters.getCryptKey(), fileContent); // Расшифровываются поля, которые подлежат шифрованию foreach( QString fieldName, fieldCryptedList() ) { // У аттача с типом file не должно быть обращений к полю link (оно не должно использоваться) if(getField("type")=="file" && fieldName=="link") continue; // Если поле с указанным именем существует и содержит данные, оно расшифровывается из исходных зашифрованных данных if(getField(fieldName).length()>0) setFieldSource(fieldName, CryptService::decryptString( globalParameters.getCryptKey(), fields[fieldName])); } // Устанавливается флаг, что запись не зашифрована setField("crypt", ""); // Отсутсвие значения предпочтительней, так как тогда в XML-данные не будет попадать атрибут crypt="0" }
// Получение значения поля // Метод возвращает расшифрованные данные, если запись была зашифрована QString Attach::getField(QString name) const { // Если имя поля недопустимо if(fieldAvailableList().contains(name)==false) criticalError("Attach::getField() : get unavailable field "+name); // ------------------------------------------ // Проверки и действия для разных типов полей // ------------------------------------------ // Если запрашивается линк на файл if(name=="link") if(fields["type"]!="link") // И тип аттача не является линком criticalError("Attach::getField() : Can't get link from non-link attach."); // ----------------------- // Получение значения поля // ----------------------- // Если запись зашифрована, но ключ не установлен (т.е. человек не вводил пароль) // то расшифровка невозможна if(fieldCryptedList().contains(name)) if(fields.contains("crypt")) if(fields["crypt"]=="1") if(globalParameters.getCryptKey().length()==0) return QString(); bool isCrypt=false; // Если имя поля принадлежит списку полей, которые могут шифроваться // и в наборе полей есть поле crypt // и поле crypt установлено в 1 // и запрашиваемое поле не пустое (пустые данные невозможно расшифровать) if(fieldCryptedList().contains(name)) if(fields.contains("crypt")) if(fields["crypt"]=="1") if(fields[name].length()>0) isCrypt=true; // Если поле не подлежит шифрованию if(isCrypt==false) return fields[name]; // Возвращается значение поля else return CryptService::decryptString(globalParameters.getCryptKey(), fields[name]); // Поле расшифровывается }
void TreeScreen::edit_branch(void) { qDebug() << "In edit_branch()"; // Получение списка индексов QModelIndex выделенных элементов QModelIndexList selectitems=knowTreeView->selectionModel()->selectedIndexes(); // Если выбрано более одной ветки if(selectitems.size()>1) { QMessageBox messageBox(this); messageBox.setWindowTitle(tr("Unavailable action")); messageBox.setText(tr("You've selected ")+QString::number(selectitems.size())+tr(" items.\nPlease select single item for enabling edit operation.")); messageBox.addButton(tr("OK"), QMessageBox::AcceptRole); messageBox.exec(); return; } // Получение индекса выделенной строки QModelIndex index=getCurrentItemIndex(); // Получение ссылки на узел, который соответствует выделенной строке TreeItem *item=knowTreeModel->getItem(index); // Если ветка зашифрована и пароль не был введен if(item->getField("crypt")=="1" && globalParameters.getCryptKey().length()==0) return; // Получение имени ветки QString name=item->getField("name"); // Создается окно ввода данных bool ok; QString newname = QInputDialog::getText(this, tr("Edit item name"), tr("Item name:"), QLineEdit::Normal, name, &ok); // Если была нажата отмена if (!( ok && !newname.isEmpty() )) return; find_object<MainWindow>("mainwindow")->setDisabled(true); item->setField("name", newname); // Сохранение дерева веток find_object<TreeScreen>("treeScreen")->saveKnowTree(); find_object<MainWindow>("mainwindow")->setEnabled(true); }
// Шифрация аттача на диске и в памяти void Attach::encrypt(unsigned int area) { // В этом методе важна последовательность действий, // чтобы не получилась ситуации, когда часть данных зашифрована, // а другая пытается их использовать, а флаг шифрации еще не установлен // Если аттач уже зашифрован, значит есть какая-то ошибка в логике выше if(getField("crypt")=="1") criticalError("Attach::encrypt() : Cant encrypt already encrypted attach."); // Шифруется файл if(area & areaFile) if(getField("type")=="file") CryptService::encryptFile(globalParameters.getCryptKey(), getFullInnerFileName()); // Шифруется содержимое файла в памяти, если таковое есть if(area & areaMemory) if(liteFlag==false && fileContent.length()>0) fileContent=CryptService::encryptByteArray(globalParameters.getCryptKey(), fileContent); // Шифруются поля, которые подлежат шифрованию foreach( QString fieldName, fieldCryptedList() ) { // У аттача с типом file не должно быть обращений к полю link (оно не должно использоваться) if(getField("type")=="file" && fieldName=="link") continue; // Если поле с указанным именем существует if(getField(fieldName).length()>0) setFieldSource(fieldName, CryptService::encryptString( globalParameters.getCryptKey(), getField(fieldName))); } // Устанавливается флаг, что запись зашифрована setField("crypt", "1"); }
QVariant TreeModel::data(const QModelIndex &index, int role) const { // Если индекс невалиден, возвращается несуществующий элемент if(!index.isValid())return QVariant(); // Если запрашивается окраска текста элемента if(role==Qt::ForegroundRole) { TreeItem *item = getItem(index); if(item->recordtableGetRowCount()>0) return Qt::black;// Если узел содержит таблицу конечных записей else return Qt::darkGray; // Обычная ветка } // Если запрашивается содержимое текста элемента if(role==Qt::DisplayRole || role== Qt::EditRole) { TreeItem *item = getItem(index); return QVariant( item->getField("dynamicname") ); // Запрашивается строка имени с количеством элементов } // Если запрашиваются элементы оформления if(role == Qt::DecorationRole) { TreeItem *item = getItem(index); // Если ветка зашифрована if(item->getField("crypt")=="1") { // Если пароль не введен, доступа к ветке нет if(globalParameters.getCryptKey().length()==0) return QIcon(":/resource/pic/branch_closed.svg"); else return QIcon(":/resource/pic/branch_opened.svg"); } } return QVariant(); }
// Удаление выбранных веток, вызывается при выборе соотвествущей // кнопки или пункта меню void TreeScreen::del_branch(QString mode) { qDebug() << "In del_branch()"; // На время удаления блокируется главное окно find_object<MainWindow>("mainwindow")->setDisabled(true); find_object<MainWindow>("mainwindow")->blockSignals(true); // Получение списка индексов QModelIndex выделенных элементов QModelIndexList selectitems=knowTreeView->selectionModel()->selectedIndexes(); // Список имен веток, которые нужно удалить QStringList branches_name; for(int i = 0; i < selectitems.size(); ++i) { QModelIndex index=selectitems.at(i); TreeItem *item=knowTreeModel->getItem(index); branches_name << item->getField("name"); } // Если системный пароль не установлен, зашифрованные ветки удалять нельзя if(globalParameters.getCryptKey().size()==0) { bool disableFlag=false; // Перебираются удаляемые ветки for(int i = 0; i < selectitems.size(); ++i) { QModelIndex index=selectitems.at(i); TreeItem *item=knowTreeModel->getItem(index); // Если у ветки установлен флаг шифрования if(item->getField("crypt")=="1") { disableFlag=true; break; } // Проверяется наличие флага шифрования у всех подветок QList<QStringList> cryptFlagsList=item->getAllChildrenPathAsField("crypt"); foreach(QStringList cryptFlags, cryptFlagsList) if(cryptFlags.contains("1")) { disableFlag=true; break; } if(disableFlag) break; } // Закрылся цикл перебора всех выделенных для удаления веток // Если в какой-то ветке обнаружено шифрование if(disableFlag) { QMessageBox messageBox(this); messageBox.setWindowTitle(tr("Unavailable action")); messageBox.setText(tr("In your selected data found closed item. Action canceled.")); messageBox.addButton(tr("OK"), QMessageBox::AcceptRole); messageBox.exec(); // Разблокируется главное окно find_object<MainWindow>("mainwindow")->setEnabled(true); find_object<MainWindow>("mainwindow")->blockSignals(false); return; } } // Закрылось условие что системный пароль не установлен
// Открытие контекстного меню в дереве разделов void TreeScreen::on_customContextMenuRequested(const QPoint &pos) { qDebug() << "In TreeScreen::on_customContextMenuRequested"; // Конструирование меню QMenu menu(this); menu.addAction(actionList["insSubbranch"]); menu.addAction(actionList["insBranch"]); menu.addAction(actionList["editBranch"]); menu.addAction(actionList["delBranch"]); menu.addSeparator(); menu.addAction(actionList["expandAllSubbranch"]); menu.addAction(actionList["collapseAllSubbranch"]); menu.addSeparator(); menu.addAction(actionList["moveUpBranch"]); menu.addAction(actionList["moveDnBranch"]); menu.addSeparator(); menu.addAction(actionList["cutBranch"]); menu.addAction(actionList["copyBranch"]); menu.addAction(actionList["pasteBranch"]); menu.addAction(actionList["pasteSubbranch"]); menu.addSeparator(); menu.addAction(actionList["encryptBranch"]); menu.addAction(actionList["decryptBranch"]); // Получение индекса выделенной ветки QModelIndex index=getCurrentItemIndex(); // Выясняется, зашифрована ли ветка или нет QString cryptFlag=knowTreeModel->getItem(index)->getField("crypt"); // Выясняется, зашифрована ли родительская ветка QString parentCryptFlag=knowTreeModel->getItem(index)->parent()->getField("crypt"); // Если ветка не зашифрована // Или ветка зашифрована, но пароль успешно введен if(cryptFlag!="1" || (cryptFlag=="1" && globalParameters.getCryptKey().length()>0)) { // Если в буфере есть ветки, соответсвующие пункты становятся активными bool isBranch=false; const QMimeData *mimeData=QApplication::clipboard()->mimeData(); if(mimeData!=NULL) if(mimeData->hasFormat("mytetra/branch")) isBranch=true; if( isBranch ) { actionList["pasteBranch"]->setEnabled(true); actionList["pasteSubbranch"]->setEnabled(true); } else { actionList["pasteBranch"]->setEnabled(false); actionList["pasteSubbranch"]->setEnabled(false); } // ---------------------------- // Подсветка пунктов шифрования // ---------------------------- // Если ветка незашифрована if(cryptFlag!="1") { // Шифровать можно // Дешифровать нельзя actionList["encryptBranch"]->setEnabled(true); actionList["decryptBranch"]->setEnabled(false); } else { // Ветка зашифрована // Шифровать нельзя actionList["encryptBranch"]->setEnabled(false); // Дешифровать можно только если верхнележащая ветка незашифрована if(parentCryptFlag!="1") actionList["decryptBranch"]->setEnabled(true); else actionList["decryptBranch"]->setEnabled(false); } } // Включение отображения меню на экране // menu.exec(event->globalPos()); menu.exec(knowTreeView->viewport()->mapToGlobal(pos)); }
// Установка значения поля // Метод принимает незашифрованные данные, и шфирует их если запись является зашифрованой void Attach::setField(QString name, QString value) { // Если имя поля недопустимо if(fieldAvailableList().contains(name)==false) criticalError("Attach::setField() : set unavailable field "+name); // ------------------------------------------ // Проверки и действия для разных типов полей // ------------------------------------------ // Поле с типом аттача if(name=="type") if( !typeAvailableList().contains(value) ) criticalError("Attach::setField() : Incorrect attach type : "+value); // Поле с именем файла if(name=="fileName") if(getField("type")=="link") // Если устанавливается имя файла для линка if(getField("fileName").length()>0 && value.length()>0) { // Если имя уже было задано (при создании аттача), и новое имя не пустое // Имя файла для линка менять нельзя showMessageBox(QObject::tr("Can't modify file name for link type attach.")); return; } // Поле со ссылкой на файл (содержит путь к файлу, на который указывает линк) if(name=="link") { QFile tempFile(value); // Если файла, на который ссылается линк, не существует if(!tempFile.exists()) { showMessageBox(QObject::tr("Bad link. File not found.")); return; } } // ----------------------- // Установка значения поля // ----------------------- bool isCrypt=false; // Если имя поля принадлежит списку полей, которые могут шифроваться // и в наборе полей есть поле crypt // и поле crypt установлено в 1 // и поле не пустое (пустые данные ненужно шифровать) if(fieldCryptedList().contains(name)) if(fields.contains("crypt")) if(fields["crypt"]=="1") if(value.length()>0) { if(globalParameters.getCryptKey().length()>0) isCrypt=true; else criticalError("In Attach::setField() can not set data to crypt field "+name+". Password not setted"); } // Если нужно шифровать, значение поля шифруется if(isCrypt==true) value=CryptService::encryptString(globalParameters.getCryptKey(), value); // Устанавливается значение поля fields.insert(name, value); }