Материал: Разработка и реализация программных средств для работы с веб-контентом в рамках проекта INTERIN PROMIS

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

{

m_Log=log;

}GSModulesManager::init()

{QSettings params;

params.beginGroup(m_ModulesSection);

m_MainModuleName=params.value("main_module", "MainWindow").toString();

m_AutoDownload=params.value("auto_download", true).toBool();

m_CheckUpdates=params.value("check_updates", true).toBool();

params.setValue("main_module", m_MainModuleName);

params.setValue("auto_download", m_AutoDownload);

params.setValue("check_updates", m_CheckUpdates);

params.endGroup();

}GSModulesManager::onEvent(const QString &event, char param)

{GSModule* module=Q_NULLPTR;

for(int i=0; i<m_lModules.size(); i++){

module=m_lModules.at(i);

if(module->onEvent(event, param))

gsInfo(m_Log, 9)<<" Событие "<<event<<" обработано в модуле "<<module->objectName()<<"."<<endl;

}

}* GSModulesManager::getWidget(const QString &widgetID)

{void *widget=Q_NULLPTR;

for(int i=0; i<m_lModules.size(); i++){

module=m_lModules.at(i);

widget=module->getWidget(widgetID);

if(widget)

return widget;

}

gsInfo(m_Log,9)<<" Элемент графического интерфейса: "<<widgetID<<" не найден!"<<endl;

return Q_NULLPTR;

}GSModulesManager::checkUpdates(const QString &listFileName, bool forceUpdate)

{

if(!m_CheckUpdates && !forceUpdate)

return 0x02;

GSUpdateFiles updateFiles;

updateFiles.setObjectName("updateFiles");

connect(&updateFiles, SIGNAL(exeUpdated(QString)), this,

SLOT(exeUpdated(QString)));

connect(&updateFiles, SIGNAL(instReceived(QString)), this,

SLOT(instReceived(QString)));

updateFiles.setLog(m_Log);

updateFiles.init(m_ModulesSection);

updateFiles.getUpdatesList(listFileName);

updateFiles.buildUpdatesTree(listFileName, m_ModulesSection);

return 0x01;

}&GSModulesManager::getNewExeName()

{

return m_newExeName;

}&GSModulesManager::getInstName()

{

return m_instReceivedName;

}GSModulesManager::exeUpdated(const QString fileName)

{

m_newExeName=fileName;

}GSModulesManager::instReceived(const QString fileName)

{

m_instReceivedName=fileName;

}

Исходный код подсистемы работы с параметрами

#include "GSApplication.h"* GSApplication::theApplication()

{ return (GSApplication *)qApp;}GSApplication::saveParams()

{QSettings params;

params.setValue("version",applicationVersion());

}GSApplication::readParams()

{}* GSApplication::createAppLog(const QString &objectName)

{

if(!m_AppLog)

m_AppLog=new GSLog(this, objectName);

return m_AppLog;

}*GSApplication::getAppLog()

{ return m_AppLog;}* GSApplication::createModulesManager(const QString &objectName)

{

if(!m_ModulesManager)

m_ModulesManager=new GSModulesManager(objectName,this);

return m_ModulesManager;

}GSApplication::getAppUID()

{ return m_Uuid;}::GSApplication(int &argc, char **argv)

: QApplication(argc, argv)

{

m_AppLog=Q_NULLPTR;

m_ModulesManager=Q_NULLPTR;

m_Uuid=QUuid::createUuid();

}::~GSApplication()

{

delete m_ModulesManager;

delete m_AppLog;

}GSApplication::isWow64(QString *appDigits)

{LPFN_ISWOW64PROCESS fnIsWow64Process=Q_NULLPTR;

BOOL bIsWow64=false, ok=false;

*appDigits="_Wx32";

fnIsWow64Process=(LPFN_ISWOW64PROCESS) GetProcAddress(

GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

if(fnIsWow64Process){

if(fnIsWow64Process(GetCurrentProcess(),&bIsWow64)){

ok=true;

if(!bIsWow64)

*appDigits="_Wx64";

}

}

if(!ok)

gsInfo(m_AppLog,9)<<" Не удалось определить разрядность приложения!"<<endl;

}

Исходный код подсистемы логирования

#include "GSLog.h"::GSLog(QObject *pobj, const QString &objectName):QObject(pobj)

{

m_LogFile.setObjectName("LogFile");

m_LogFile.setParent(this);

setObjectName(objectName);

}::~GSLog()

{

m_LogFile.close();

}GSLog::init(const QString &paramsSection)

{QTextCodec *codec = QTextCodec::codecForName("UTF-8");

QTextCodec::setCodecForLocale(codec);

m_ParamsSection=paramsSection;

setLogFileName();

setLogLevel(getLogLevel());

m_OutStream.setCodec(codec);

m_currentLogMessagesLevel=0;

return true;

}GSLog::setLogFileName(QString &value)

{

if(value.isEmpty()){

value=m_Params.value(m_ParamsSection+"/log_path",::writableLocation(QStandardPaths::AppLocalDataLocation)+

QString("/")+qApp->applicationName()+".log").toString();

}

if(m_LogFile.fileName()==value)

return true;

m_LogFile.close();

m_LogFile.setFileName(value);

if(!m_LogFile.exists()){

QFileInfo fileInfo(m_LogFile);

fileInfo.absoluteDir().mkpath(fileInfo.absolutePath());

}

if(!m_LogFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append))

return false;

m_OutStream.setDevice(&m_LogFile);

m_Params.setValue(m_ParamsSection+"/log_path",value);

return true;

}GSLog::getLogFileName()

{

return m_LogFile.fileName();

}GSLog::setLogLevel(int value)

{

m_Params.setValue(m_ParamsSection+"/log_level", value);

}GSLog::getLogLevel()

{

return m_Params.value(m_ParamsSection+"/log_level", -1).toInt();

}GSLog::setlogMessagesLevel(int value)

{

m_currentLogMessagesLevel=value;

}&GSLog::toLog(int level, QObject *pobj)

{

m_currentLogMessagesLevel=level;

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<level)

return *this;

m_OutStream<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz ")

<<QString("%1 [").arg(level,2);

if(pobj){

m_OutStream<<pobj->objectName();

}

m_OutStream<<"] "<<endl;

// m_OutStream<<" ";

return *this;

}&GSLog::operator <<(QString &value)

{

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<m_currentLogMessagesLevel)

return *this;

m_OutStream<<value;

return *this;

}&GSLog::operator <<(const QString &value)

{

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<m_currentLogMessagesLevel)

return *this;

m_OutStream<<value;

return *this;

}&GSLog::operator <<(char *value)

{

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<m_currentLogMessagesLevel)

return *this;

m_OutStream<<QString(value).toLocal8Bit();

return *this;

}&GSLog::operator <<(const char *value)

{

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<m_currentLogMessagesLevel)

return *this;

m_OutStream<<QString(value).toLocal8Bit();

return *this;

}&GSLog::operator <<(bool value)

{

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<m_currentLogMessagesLevel)

return *this;

if(value)

m_OutStream<<"Yes";

else

m_OutStream<<"No";

return *this;

}&GSLog::operator <<(int value)

{

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<m_currentLogMessagesLevel)

return *this;

m_OutStream<<value;

return *this;

}&GSLog::operator <<(QTextStream &(__cdecl *)(QTextStream &))

{

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<m_currentLogMessagesLevel)

return *this;

m_OutStream<<endl;

return *this;

}&GSLog::operator <<(QEvent::Type value)

{QString event_type;

if(m_Params.value(m_ParamsSection+"/log_level", -1).toInt()<m_currentLogMessagesLevel)

return *this;

switch (value) {

case QEvent::ActionAdded:

event_type="A new action has been added";

break;

case QEvent::ApplicationActivate:

event_type="Application activated.";

break;

case QEvent::ApplicationDeactivate:

event_type="Application deactivated.";

break;

case QEvent::ApplicationStateChange:

event_type="The state of the application has changed.";

break;

case QEvent::MetaCall:

event_type="An asynchronous method invocation via QMetaObject::invokeMethod().";

break;

case QEvent::Timer:

event_type="Regular timer events.";

break;

default:

event_type=QString("Unknown(")+QString().number(value)+")";

break;

}

m_OutStream<<event_type;

return *this;

}

Исходный код подсистемы обновлений

#include "GSUpdateFiles.h"

GSUpdateFiles::GSUpdateFiles(QWidget *parent):QDialog(parent)

{QStringList headers;

// QPushButton* button;

m_UpdatesTree=new QTreeWidget(this);

headers<<tr("Модуль")<<tr("Версия")<<tr("Тип")

<<tr("Путь на сервере")<<tr("Локальный путь")<<tr("Локальное имя")

<<tr("Локальная версия")<<tr("Принудительно")<<tr("Обновить")

<<tr("Прогресс");

m_UpdatesTree->setColumnCount(headers.count());

m_UpdatesTree->setHeaderLabels(headers);

m_UpdatesTree->setColumnHidden(2, true);

m_UpdatesTree->setColumnHidden(3, true);

m_UpdatesTree->setColumnHidden(4, true);

m_UpdatesTree->setColumnHidden(5, true);

m_UpdatesTree->setColumnHidden(6, true);

m_UpdatesTree->setColumnHidden(7, true);

m_UpdatesTree->setItemDelegateForColumn(9,new ProgressBarDelegate(m_UpdatesTree));

m_UpdatesTree->setColumnWidth(0,300);

QVBoxLayout *vLayout= new QVBoxLayout(this);

vLayout->addWidget(m_UpdatesTree);

QHBoxLayout *hLayout= new QHBoxLayout(this);

hLayout->addStretch(10);

m_Button=new QPushButton(this);

m_Button->setText("Закрыть");

m_Button->setFocus();

connect(m_Button, SIGNAL(clicked(bool)), this, SLOT(close()));

hLayout->addWidget(m_Button);

m_Button->setVisible(false);

vLayout->addLayout(hLayout);

resize(700,300);

setWindowTitle("Доступные обновления");

m_Log=Q_NULLPTR;

}::~GSUpdateFiles()

{

delete m_UpdatesTree;

m_Log=Q_NULLPTR;

}GSUpdateFiles::getUpdatesList(const QString &listFileName)

{QUrl src, dst;

src.setUrl(m_UpdateConnectString+listFileName);

gsInfo(m_Log, 9)<<" Получаем файл списка обновлений "<<src.toDisplayString()<<endl;

src.setUserName(m_UpdateUser);

src.setPassword(m_UpdatePasswd);

dst.setUrl(QString("file:///")+QDir::current().absolutePath()+

"/"+listFileName);

m_ShowDialog="0";

loadUpdate(src, dst);

m_ShowDialog="1";

}GSUpdateFiles::buildUpdatesTree(const QString &listFileName,

const QString &modulesSection,

TUpdatePolicy updatePolicy)

{QFile file(QDir::current().absolutePath()+"/"+listFileName);

QDomDocument updatesDoc;

QString tmpStr;

int errorLine;

int errorColumn;

QTreeWidgetItem *rootItem, *currentItem, *childItem;

QSettings moduleParams;

if(m_NetworkError)

return;

m_ModulesSection=modulesSection;

gsInfo(m_Log, 9)<<" Заполняем список обновлений из файла "<<listFileName<<endl;

if(!file.open(QFile::ReadOnly | QFile::Text)){

tmpStr=" Не удалось открыть файл списка обновлений ";

gsInfo(m_Log, 9)<<tmpStr<<listFileName<<endl;

QMessageBox::critical(0, QString("Ошибка!"), tmpStr, QMessageBox::Ok);

return;

}

if(!updatesDoc.setContent(&file, true, &tmpStr, &errorLine, &errorColumn)){

tmpStr=QString(" Ошибка формата в строке %1, столбец %2:\n%3")

.arg(errorLine)

.arg(errorColumn)

.arg(tmpStr);

gsInfo(m_Log, 9)<<tmpStr<<endl;

QMessageBox::critical(0, QString("Ошибка!"), tmpStr, QMessageBox::Ok);

return;

}

QDomElement root=updatesDoc.documentElement();

if(root.tagName()!="updxml"){

tmpStr=" Формат файла обновлений неизвестен.";

gsInfo(m_Log, 9)<<tmpStr<<endl;

QMessageBox::critical(0, QString("Ошибка!"), tmpStr, QMessageBox::Ok);

return;

}

else

if(root.hasAttribute("version")

&& root.attribute("version") != "1.0"){

tmpStr=" Версия формата файла обновлений не поддерживается.";

gsInfo(m_Log, 9)<<tmpStr<<endl;

QMessageBox::critical(0, QString("Ошибка!"), tmpStr, QMessageBox::Ok);

return;

}

QDomElement moduleElement=root.firstChildElement("module");

rootItem=m_UpdatesTree->invisibleRootItem();

currentItem=Q_NULLPTR;

while(!moduleElement.isNull()){

currentItem=new QTreeWidgetItem(rootItem, currentItem);

currentItem->setText(0, moduleElement.attribute("name"));

currentItem->setText(1, moduleElement.attribute("version"));

currentItem->setText(2, moduleElement.attribute("type"));

currentItem->setText(7, moduleElement.attribute("force"));

currentItem->setText(8, "Да");

if(moduleElement.attribute("type")=="exe")

moduleParams.beginGroup("");

else.beginGroup(modulesSection+"/"+moduleElement.attribute("name"));

currentItem->setText(6, moduleParams.value("version", "").toString());

currentItem->setExpanded(true);

QDomElement child=moduleElement.firstChildElement();

childItem=Q_NULLPTR;

while(!child.isNull()){

childItem=new QTreeWidgetItem(currentItem, childItem);

childItem->setText(0, child.text());

childItem->setText(3, child.attribute("path"));

childItem->setText(4,"file:///"+moduleParams.value("module_path",

QDir::current().absolutePath()+"/").toString());

if(child.tagName()=="file"){

childItem->setText(5, moduleParams.value("module_file", child.text()).toString());

childItem->setText(2, "Основной");

}

else{

childItem->setText(5, child.text());

childItem->setText(2, "Необходимый");

}

child=child.nextSiblingElement();

}

moduleParams.endGroup();

moduleElement=moduleElement.nextSiblingElement("module");

}

checkItemForUpdate(updatePolicy);

}GSUpdateFiles::checkItemForUpdate(TUpdatePolicy updatePolicy)

{QTreeWidgetItem *rootItem, *currentItem;

int updateVersion, localVersion, modulesCount;

QString message;

rootItem=m_UpdatesTree->invisibleRootItem();

modulesCount=rootItem->childCount();

for(int index=0; index<rootItem->childCount(); index++){

currentItem=rootItem->child(index);

update=true;

if(!currentItem->text(6).isEmpty()){

updateVersion=currentItem->text(1).section(".",0,0).toInt()*10000;

localVersion=currentItem->text(6).section(".",0,0).toInt()*10000;

updateVersion=currentItem->text(1).section(".",1,1).toInt()*100;

localVersion=currentItem->text(6).section(".",1,1).toInt()*100;

updateVersion=currentItem->text(1).section(".",2,2).toInt();

localVersion=currentItem->text(6).section(".",2,2).toInt();

update=updateVersion>localVersion;

}

if(update){

currentItem->setText(8,"Да");

currentItem->setText(5, currentItem->text(0));

}

else{

message=" Модуль "+currentItem->text(0)+" "+currentItem->text(1)+

".\n Установлена версия "+currentItem->text(6)+

".\n В обновлении не нуждается.";

gsInfo(m_Log, 9)<<message<<endl;

currentItem->setText(8,message);

if(updatePolicy==newOnly){

currentItem->setHidden(true);

modulesCount--;

}

}

}

if(updatePolicy==newOnly)

m_UpdatesTree->setColumnHidden(8, true);

if(modulesCount){

if(QMessageBox::information(0, QString("Клиент МИС \"Интерин\"."), "Доступны обновления программы.\nОбновление может занять несколько минут. В процессе обновления программа может перезапуститься.\nОбновить сейчас?",

QMessageBox::Ok|QMessageBox::Cancel)==QMessageBox::Ok){

setModal(true);

show();

startTransfer(true);

}

}

}GSUpdateFiles::loadUpdate(const QUrl &src, const QUrl &dst, const QString &type)

{QNetworkReply* networkReply;

QNetworkAccessManager networkAccessManager;

QEventLoop loop;

QTimer timer;

timer.setSingleShot(true);

gsInfo(m_Log,9)<<" Обновляем файл\n src="<<src.toDisplayString()<<

"\n dst="<<dst.toDisplayString()<<"\n type="<<type<<endl;

networkReply=networkAccessManager.get(QNetworkRequest(src));

connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),

this, SLOT(loadError(QNetworkReply::NetworkError)));

if(m_ShowDialog=="1")

connect(networkReply, SIGNAL(downloadProgress(qint64,qint64)),

this, SLOT(transferProgress(qint64,qint64)));

connect(networkReply, SIGNAL(finished()), &loop, SLOT(quit()));

connect(&timer, SIGNAL(timeout()), networkReply, SLOT(abort()));

m_NetworkError=false;

timer.start(m_TimeOut);

loop.exec();

if(!m_NetworkError){

QFile file(dst.toLocalFile());

QFileInfo fileInfo(file);

if(!fileInfo.absoluteDir().exists())

fileInfo.absoluteDir().mkpath(fileInfo.absolutePath());

file.open(QIODevice::WriteOnly);

file.write(networkReply->readAll());

if(type=="exe/Основной")

emit exeUpdated(fileInfo.absoluteFilePath());

if(type=="inst/Основной")

emit instReceived(fileInfo.absoluteFilePath());

}

networkReply->deleteLater();

}GSUpdateFiles::showEvent(QShowEvent *event)

{}GSUpdateFiles::setLog(GSLog *log)

{

m_Log=log;

}GSUpdateFiles::init(const QString &paramSectionName)

{QSettings params;

params.beginGroup(paramSectionName);

m_UpdateConnectString=params.value("update_connect_str", "ftp://interin.rk35.ru/updates/").toString();

m_UpdateUser=params.value("update_user", "interin").toString();

m_UpdatePasswd=params.value("update_passwd", "www.gslobod.ru").toString();

m_BackupDir=params.value("backup_dir",

QDir::current().absolutePath()+"/backup/").toString();

m_ShowDialog=params.value("show_dialog", "1").toString();

m_MaxDownloads=params.value("max_downloads", "5").toString();

Источник: https://www.bibliofond.ru/view.aspx?id=897371