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

Расширение возможностей браузера плагинами. Создание собственного веб-клиента. Разработка главной функции ядра системы. Основание подсистемы загрузки файлов. Формирование инсталлятора программной концепции. Тестирование функциональной части программы.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 12.08.2017
Размер файла 2,4 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Рисунок 4.1 - Снимок экрана процесса установки клиента.

В процессе установки клиента, инсталлятор создает ветвь (\HKEY_CURRENT_USER\Software\Interin) в реестре операционной систем, а в выбранную директорию распаковываются исполняемый файл системы (InterinClient.exe), а так же все необходимые для его работы библиотеки и модули.

4.2 Тестирование функциональной части программы

Функциональное тестирование - процесс проверки соответствия поведения системы первоначально заявленным функциональным требованиям [15].

Цель тестирования: Подтвердить, что система реализована в соответствии с предъявленными к ней функциональными требованиями и полностью готова к работе, при этом система воспринимается как единый «чёрный ящик».

Главное преимущества такого тестирования - это имитация фактического использования системы, однако есть и недостатки, такие как возможность упущения логических ошибок в программном обеспечении и вероятность избыточного тестирования.

Исходные данные и результаты тестирования приведены в Таблице 4.1. Графа оценка определяет соответствие результатов ожидаемым («+» - соответствуют, «-» - нет).

Таблица 4.1 - Исходные данные и результаты тестирования программной системы

Исходные данные

Результат

Оценка

Запуск инсталлятора

Запускается установка клиента,по результатам ее выполнения пользователю предлагается ознакомится с основными ее результатами

+

Запук исполняемого файла клиента

Открывается приложения и начинается проверка обновлений, по ее завершению запускается главное окно

+

Нажатие на пунк меню

Открывается выбранное подменю

+

Изменение параметро системы

После сохранения именений результат успешно применяется

+

Запуск обновления

Запускается подсистема обновлений

+

Измнение размеров окна программы

Изменения применяются, пропорции отображаемого материала сохраняются

+

Нажатие на попункт меню "Печать в PDF"

Открывается диалоговое окно печати с возможностью выбора параметров

+

Нажатие на понкт меню "Помощ"

Открывается информационное окно "О программе"

+

Изменение адреса получения обновлений на локальный

Программа меняет протокол обмена данными и получает обновления из локальной папки

+

Переход по ссылке в МИС на открытие тектового файла

Идет загрузка фала, затем его открытие в выбранном тектовом редакторе.

+

Переход по ссылке в МИС на прямую печать тектового файла

Идет загрузка фала, затем его преобразование в pdf формат и отправка на принтер. От пользователя скрыт весь процесс.

Нажание на подпунк меню "Выход"

Программа закрывается

+

4.3 Тестирование модульной расширяемости

Для изменения логики работы всей системы достаточно в ее параметрах указать название другого модуля главного окна. На рисунке 4.2 представлен пример работы главного модуля, которы имеет название "InterinClntMainWnd_2.0.10.dll ".

Рисунок 4.2 - Пример работы модуля "InterinClntMainWnd_2.0.10.dll"

На рисунке 4.3 представлен процесс изменения главного исполнемого модуля на "InterinClntMainWnd_2.0.4.dll".

Рисунок 4.3 - Пример изменения главного исполняемого модуля

После применения измений и перезапуска программы можно увидеть, что система успешно запустилась, однако функционал сущеественно ограничен, поскольку был подключен устаревший модуль.

На рисунке 4.4 представлен пример работы главного модуля, которы имеет название "InterinClntMainWnd_2.0.4.dll ".

Рисунок 4.4 - Пример работы модуля "InterinClntMainWnd_2.0.4.dll"

Для расширения функиционала системы путем добавления бибилотек, а не их изменения потребуется в реестре операционной системы, в ветви "ModulesManeger" создать раздел. В нем разделе необхоимо создать такие параметры как module_path,module_name и version. В module_path необходимо указать полный путь до ибилотеки, а в module_name её полное наименование. После перезапуска программы, функционал реалиованный в данной бибилотеке будет доступен.

5. ВНЕДРЕНИЕ

Для внедрения клиента корпоративной информационной системы необходимо происталлировать програмный продукт на все необходимые рабочие места и насроить адрес домашней страницы. Далее, при необходимости, нужно установить программы для работы с тектовыми документами, а так же выбрать нужную в настройках. Для этого в настройках системы, в пункте "Редактор выходных форм" необходимо выбрать исполняемый файл тектового редактора. Данный процесс представлен на рисунке 5.1.

Рисунок 5.1 - Пример выбора редактора выходны фаорм

Вторым этапом внедрения является создание общего ресурса, на котором будет рассположены файлы обновления с их описанием. Разработанная подсистема обновлений позволяет без изменений использовать раличные протоколы обмена данными, такие как ftp,smb,file. Таким образом, необходимо только указать в настройках путь до папки с обновлениями.

На рисунке 5.2 представлен пример отображения медицинской информационной системы Interin PROMIS ALPHA на реализованном в данной работе клиенском приложениии.

Рисунок 5.2 - Вид типовой МИС

ЗАКЛЮЧЕНИЕ

В данной магистерской диссертации была проведена работа по анализу методов реализации клиента информационной веб-системы, а так же выбран оптимальный способ его реализации. Была представлена и реализована идея интеграции информационных решений, для получения многофункционального, конкурентноспособного программного продукта. Разработана модульная структура, которая отражена на функциональной и структурной схемах. Она позволяет обеспечить легкое обновление, тиражируемость и масштабируемость всей системы без изменения основных компонент.

Реализованы основные модули системы, такие как ее ядро и главное окно. Реализованный метод интеграции предполагает обязательное наличие в системе только этих двух компонент, а остальные исключительно для наращивания функционала. Для расширения возможностей был разработан модуль печати, который основан на сторонней библиотеке, что показывает интеграционные способности всей системы, а подсистема обновлений предоставляет широкий выбор настроек для поддержания всех модулей в актуальном состоянии. Так же продемонстрирована стабильная работоспособность всей системы и возможность изменения ее функционирования путем подключения или отключения бибилотек.

Полученный программный продукт полностью удовлетворяет всем исходным требования и используется в качестве клиента медицинской информационной системы «Interin PROMIS ALPHA» в двух медицинских организацияхж

Результаты работы представляют высокую практическую значимость, поскольку разработанный клиент предоставляет возможность быстрой адаптации к различным информационным системам, путем изменения отдельных библиотек, что позволяет не просто расширять его функционал, а полностью изменять логику работы системы.

ПРИЛОЖЕНИЕ

(Обязательное)

Исходный код функции main ядра системы

#include "../src/InterinClntApp/interinclntapp.h"

int main(int argc, char **argv)

{InterinClntApp *app=Q_NULLPTR;

QString execAfterExit="";

char initRez;

bool done=false;

app=new InterinClntApp(argc, argv);

while(!done){

initRez=app->init();

if(!initRez){

execAfterExit=" Не удалось выполнить инициализацию параметров приложения.\n"

" Работа будет завершена. Обратитесь в техподдержку!";

if(app->getAppLog())

app->getAppLog()->toLog(0)<<execAfterExit<<endl;

QMessageBox::critical(0, QString(" Клиент МИС \"Интерин\" версия ")+

app->applicationVersion(), execAfterExit,

QMessageBox::Ok);

delete app;

return 1;

}

if(initRez==0x01){

if(app->loadMainModule()){

app->exec();

execAfterExit=app->getUpdateCommand();

if(!execAfterExit.isEmpty()){

app->getAppLog()->toLog(9)<<" Перезапускаемся для проверки обновлений.\n "<<execAfterExit<<endl;

initRez=0x02;

}

done=true;

}

else{

execAfterExit=" Не удалось загрузить основной модуль программы.\n"

" Нажмите Ок для загрузки основного модуля с сервера обновлений.\n"

" Нажмите Cancel для завершения работы и обратитесь в техподдержку!.";

if(app->getAppLog())

app->getAppLog()->toLog(0)<<execAfterExit<<endl;

if(QMessageBox::critical(0, QString(" Клиент МИС \"Интерин\" версия ")+

app->applicationVersion(), execAfterExit,

QMessageBox::Ok|QMessageBox::Cancel)!=QMessageBox::Ok)

done=true;

}

}

else{ execAfterExit=app->getUpdateCommand();

app->getAppLog()->toLog(9)<<" Обновились. После завершения выполняем команду\n "<<execAfterExit<<endl;

done=true;

}

}app->saveParams();

delete app;

if(!execAfterExit.isEmpty() && initRez==0x02)

QProcess(0).startDetached(execAfterExit);

return 0;

}

Исходный код менеджера модулей

#include "gsmodule.h"

GSModule::GSModule(const QString &moduleName, const QString &modulesSection,

QObject *parent):

QObject(parent)

{

setObjectName(moduleName);

m_DllInit=Q_NULLPTR;

m_DllStart=Q_NULLPTR;

m_DllStop=Q_NULLPTR;

m_DllAbout=Q_NULLPTR;

m_HandlersArray=Q_NULLPTR;

m_WidgetsArray=Q_NULLPTR;

m_Log=Q_NULLPTR;

m_ModuleParamsSection=modulesSection+"/"+objectName()+"/";

// load();

}

GSModule::~GSModule()

{

unload();

m_Log=Q_NULLPTR;

}

char GSModule::init(void *abstractInterface)

{TGetEventsHandlers getHandlers=Q_NULLPTR;

TGetWidgetsList getWidgets=Q_NULLPTR;

QSettings objectParams;

objectParams.setValue(m_ModuleParamsSection+"version", about(ABOUT_VER));

if(!m_DllInit)

return 0x00;

if(!m_DllInit(abstractInterface, &m_ModuleParamsSection))

return 0x00;

getHandlers=(TGetEventsHandlers) m_Library.resolve("getEventsHandlers");

if(getHandlers)

m_HandlersArray=(THandlersArray *)getHandlers();

getWidgets=(TGetWidgetsList) m_Library.resolve("getWidgetsList");

if(getWidgets)

m_WidgetsArray=(TWidgetsArray *)getWidgets();

return 0x01;

}

char GSModule::start()

{QSettings objectParams;

if(!m_DllStart)

return 0x00;

// objectParams.setValue(m_ModuleParamsSection+"version", about(ABOUT_VER));

return m_DllStart();

}

char GSModule::stop()

{

m_HandlersArray=Q_NULLPTR;

m_WidgetsArray=Q_NULLPTR;

if(!m_DllStop)

return 0x00;

return m_DllStop();

}

QString GSModule::about(char content)

{QString mess;

if(!m_DllAbout)

return "";

m_DllAbout(content, &mess);

return mess;

}

bool GSModule::isLoaded()

{

return m_Library.isLoaded();

}

bool GSModule::load()

{QSettings objectParams;

if(m_Library.isLoaded())

unload();

m_Library.setFileName(objectParams.value(m_ModuleParamsSection+"module_path","").toString()+

objectParams.value(m_ModuleParamsSection+"module_file","").toString());

gsInfo(m_Log,9)<<" Загружаем файл\n "<<m_Library.fileName()<<"\n из секции\n "<<m_ModuleParamsSection<<endl;

if(!m_Library.load()){

objectParams.setValue(m_ModuleParamsSection+"version","");

return false;

}

m_DllInit= (TModuleInit) m_Library.resolve("init");

m_DllStart= (TModuleStart) m_Library.resolve("start");

m_DllStop= (TModuleStop) m_Library.resolve("stop");

m_DllAbout= (TModuleAbout) m_Library.resolve("about");

return true;

}

bool GSModule::unload()

{

if(!m_Library.isLoaded()){

stop();

m_DllInit=Q_NULLPTR;

m_DllStart=Q_NULLPTR;

m_DllStop=Q_NULLPTR;

m_DllAbout=Q_NULLPTR;

return m_Library.unload();

}

return true;

}

char GSModule::onEvent(const QString &event, char param)

{TEventHandler eventHandler;

if(m_HandlersArray){

eventHandler=m_HandlersArray->value(event,Q_NULLPTR);

if(eventHandler){

eventHandler(param);

return 0x01;

}

}

return 0x00;

}

void *GSModule::getWidget(const QString &widgetId)

{

if(m_WidgetsArray)

return m_WidgetsArray->value(widgetId,Q_NULLPTR);

return Q_NULLPTR;

}

void GSModule::setLog(GSLog *log)

{

m_Log=log;

}

GSModulesManager::GSModulesManager(const QString &objectName, QObject *parent)

: QObject(parent)

{

m_ModulesSection=objectName;

setObjectName(objectName);

m_Log=Q_NULLPTR;

m_newExeName="";

m_instReceivedName="";

}

GSModulesManager::~GSModulesManager()

{

unloadAllModules();

m_Log=Q_NULLPTR;

}

GSModule* GSModulesManager::loadModule(const QString &moduleName)

{GSModule* module=Q_NULLPTR;

if(moduleName.isEmpty())

return loadModule(m_MainModuleName);

gsInfo(m_Log,9)<<" Загружаем модуль "<<moduleName<<endl;

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

module=m_lModules.at(i);

if(module->objectName() == moduleName){

if(module->isLoaded())

return module;

else{

module->load();

break;

}

}

module=Q_NULLPTR;

}

if(!module){

module=new GSModule(moduleName, m_ModulesSection, this);

module->setLog(m_Log);

module->load();

m_lModules.append(module);

}

return module;

}

void GSModulesManager::loadAllModules(void *abstractInterface, bool doInit)

{QSettings params;

GSModule* module=Q_NULLPTR;

QStringList modules;

params.beginGroup(m_ModulesSection);

modules=params.childGroups();

int index=modules.indexOf(m_MainModuleName);

if(index>0){

modules[index]=modules[0];

modules[0]=m_MainModuleName;

}

gsInfo(m_Log, 9)<<" Загружаем все модули."<<endl;

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

module=loadModule(modules.at(i));

if(!module->isLoaded()){

gsInfo(m_Log, 9)<<" Модуль "<<modules.at(i)<<" не загружен. Необходимо получить обновление."<<endl;

continue;

}

if(doInit)

if(!module->init((void *)this))

gsInfo(m_Log,0)<<" Не удалось проинициализировать модуль: "<<module->objectName()<<endl;

}

}

void GSModulesManager::unloadModule(GSModule *module)

{

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

if(module == m_lModules.at(i)){

module=m_lModules.takeAt(i);

delete module;

return;

}

}

}

void GSModulesManager::unloadAllModules()

{GSModule *module;

bool ok=false;

gsInfo(m_Log, 9)<<" Выгружаем все модули. Общее число загруженных модулей "<<m_lModules.size()<<"."<<endl;

while(!m_lModules.isEmpty())

delete m_lModules.takeFirst();

}

void GSModulesManager::setLog(GSLog *log)

{

m_Log=log;

}

void 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();

}

void 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;

}

}

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

{void *widget=Q_NULLPTR;

GSModule* module=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;

}

char 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;

}

QString &GSModulesManager::getNewExeName()

{

return m_newExeName;

}

QString &GSModulesManager::getInstName()

{

return m_instReceivedName;

}

void GSModulesManager::exeUpdated(const QString fileName)

{

m_newExeName=fileName;

}

void GSModulesManager::instReceived(const QString fileName)

{

m_instReceivedName=fileName;

}

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

#include "GSApplication.h"

GSApplication* GSApplication::theApplication()

{ return (GSApplication *)qApp;}

void GSApplication::saveParams()

{QSettings params;

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

}

void GSApplication::readParams()

{}

GSLog * GSApplication::createAppLog(const QString &objectName)

{

if(!m_AppLog)

m_AppLog=new GSLog(this, objectName);

return m_AppLog;

}

GSLog *GSApplication::getAppLog()

{ return m_AppLog;}

GSModulesManager* GSApplication::createModulesManager(const QString &objectName)

{

if(!m_ModulesManager)

m_ModulesManager=new GSModulesManager(objectName,this);

return m_ModulesManager;

}

QUuid GSApplication::getAppUID()

{ return m_Uuid;}

GSApplication::GSApplication(int &argc, char **argv)

: QApplication(argc, argv)

{

m_AppLog=Q_NULLPTR;

m_ModulesManager=Q_NULLPTR;

m_Uuid=QUuid::createUuid();

}

GSApplication::~GSApplication()

{

delete m_ModulesManager;

delete m_AppLog;

}

void 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::GSLog(QObject *pobj, const QString &objectName):QObject(pobj)

{

m_LogFile.setObjectName("LogFile");

m_LogFile.setParent(this);

setObjectName(objectName);

}

GSLog::~GSLog()

{

m_LogFile.close();

}

bool 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;

}

bool GSLog::setLogFileName(QString &value)

{

if(value.isEmpty()){

value=m_Params.value(m_ParamsSection+"/log_path",

QStandardPaths::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;

}

QString GSLog::getLogFileName()

{

return m_LogFile.fileName();

}

void GSLog::setLogLevel(int value)

{

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

}

int GSLog::getLogLevel()

{

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

}

void GSLog::setlogMessagesLevel(int value)

{

m_currentLogMessagesLevel=value;

}

GSLog &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 &GSLog::operator <<(QString &value)

{

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

return *this;

m_OutStream<<value;

return *this;

}

GSLog &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 &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 &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 &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 &GSLog::operator <<(int value)

{

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

return *this;

m_OutStream<<value;

return *this;

}

GSLog &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 &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::~GSUpdateFiles()

{

delete m_UpdatesTree;

m_Log=Q_NULLPTR;

}

void 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";

}

void 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

moduleParams.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);

}

void GSUpdateFiles::checkItemForUpdate(TUpdatePolicy updatePolicy)

{QTreeWidgetItem *rootItem, *currentItem;

int updateVersion, localVersion, modulesCount;

bool update;

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);

}

}

}

void 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();

}

void GSUpdateFiles::showEvent(QShowEvent *event)

{}

void GSUpdateFiles::setLog(GSLog *log)

{

m_Log=log;

}

void 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();

m_TimeOut=params.value("time_out", "60000").toLongLong();

params.setValue("update_connect_str", m_UpdateConnectString);

params.setValue("update_user", m_UpdateUser);

params.setValue("update_passwd", m_UpdatePasswd);

params.setValue("backup_dir", m_BackupDir);

params.setValue("show_dialog", m_ShowDialog);

params.setValue("max_downloads", m_MaxDownloads);

params.setValue("time_out", m_TimeOut);

params.endGroup();

}

void GSUpdateFiles::transferProgress(qint64 bytesReceived, qint64 bytesTotal)

{int childProgressData=0;

if(bytesTotal)

childProgressData=(float(bytesReceived)/bytesTotal*100);

m_DownloadingItem->setText(9, QString::number(childProgressData));

}

void GSUpdateFiles::startTransfer(bool value)

{QTreeWidgetItem *rootItem, *currentItem, *childItem;

QUrl src, dst;

QSettings moduleParams;

bool hasErrors=false;

QTime timer;

gsInfo(m_Log, 9)<<" Загружаем обновления."<<endl;

m_NetworkError=false;

rootItem=m_UpdatesTree->invisibleRootItem();

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

currentItem=rootItem->child(index);

if(currentItem->isHidden())

continue;

for(int childIndex=0; childIndex<currentItem->childCount(); childIndex++){

childItem=currentItem->child(childIndex);

src.setUrl(childItem->text(3)+childItem->text(0));

src.setUserName(m_UpdateUser);

src.setPassword(m_UpdatePasswd);

dst.setUrl(childItem->text(4)+childItem->text(5));

m_DownloadingItem=childItem;

currentItem->setText(9,"Загружаем обновление.");

loadUpdate(src, dst, currentItem->text(2)+"/"+childItem->text(2));

hasErrors|=m_NetworkError;

if(!m_NetworkError)

currentItem->setText(9,"Обновление загружено.");

if(currentItem->text(2)+"/"+childItem->text(2)=="dll/Основной"){

moduleParams.beginGroup(m_ModulesSection+"/"+currentItem->text(0));

moduleParams.setValue("module_path",childItem->text(4).mid(8));

moduleParams.setValue("module_file",childItem->text(0));

moduleParams.endGroup();

}

}

}

if(!hasErrors){

timer.start();

while(timer.elapsed()<2000)

qApp->processEvents();

close();

}

else{

m_Button->setVisible(true);

exec();

}

}

void GSUpdateFiles::loadError(QNetworkReply::NetworkError error)

{

gsInfo(m_Log,0)<<" Превышен интервал выполнения запроса!"<<endl;

if(m_ShowDialog=="1")

m_DownloadingItem->parent()->setText(9, "Ошибка!");

m_NetworkError=true;

}

void GSUpdateFiles::loadTimeOut()

{}

ProgressBarDelegate::ProgressBarDelegate(QObject *parent)

: QItemDelegate(parent)

{}

void ProgressBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const

{QStyleOptionProgressBar progressBarOption;

if(index.parent()==QModelIndex()){

QItemDelegate::paint(painter, option, index);

return;

}

progressBarOption.state = QStyle::State_Enabled;

progressBarOption.direction = QApplication::layoutDirection();

progressBarOption.rect = option.rect;

progressBarOption.fontMetrics = QApplication::fontMetrics();

progressBarOption.minimum = 0;

progressBarOption.maximum = 100;

progressBarOption.textAlignment = Qt::AlignCenter;

progressBarOption.textVisible = true;

int progress=index.data().toInt();

progressBarOption.progress = progress < 0 ? 0 : progress;

progressBarOption.text = index.data().toString()+" %";

QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);

}

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

#include "headers/downloadmanager.h"

#include "headers/autosaver.h"

#include "headers/browserapplication.h"

#include <math.h>

#include <QtCore/QMetaEnum>

#include <QtCore/QSettings>

#include <QtGui/QDesktopServices>

#include <QtWidgets/QFileDialog>

#include <QtWidgets/QHeaderView>

#include <QtWidgets/QFileIconProvider>

#include <QtCore/QDebug>

#include <QWebEngineSettings>

#include <QWebEngineDownloadItem>

#include <QMessageBox>

#include "../../Libs/src/WithQT/DebenuPdfLib/DebenuPDFLibraryDLLQt1113.h"

DownloadWidget::DownloadWidget(QWebEngineDownloadItem *download, QWidget *parent)

: QWidget(parent)

, m_bytesReceived(0)

, m_download(download)

{

setupUi(this);

QPalette p = downloadInfoLabel->palette();

p.setColor(QPalette::Text, Qt::darkGray);

downloadInfoLabel->setPalette(p);

progressBar->setMaximum(0);

connect(stopButton, SIGNAL(clicked()), this, SLOT(stop()));

connect(openButton, SIGNAL(clicked()), this, SLOT(open()));

connect(printButton, SIGNAL(clicked()), this, SLOT(print()));

if (download) {

m_file.setFile(download->path());

m_url = download->url();

}

init();

}

void DownloadWidget::init()

{

if (m_download) {

connect(m_download.data(), SIGNAL(downloadProgress(qint64,qint64)),

this, SLOT(downloadProgress(qint64,qint64)));

connect(m_download.data(), SIGNAL(finished()),

this, SLOT(finished()));

}

downloadInfoLabel->clear();

progressBar->setValue(0);

getFileName();

// start timer for the download estimation

m_downloadTime.start();

}

bool DownloadWidget::getFileName(bool promptForFileName)

{

QSettings settings;

settings.beginGroup(QLatin1String("downloadmanager"));

QString defaultLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);

if (m_file.absoluteDir().exists())

defaultLocation = m_file.absolutePath();

QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString();

if (!downloadDirectory.isEmpty())

downloadDirectory += QLatin1Char('/');

QString defaultFileName = QFileInfo(downloadDirectory, m_file.fileName()).absoluteFilePath();

QString fileName = defaultFileName;

if (promptForFileName) {

fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName);

if (fileName.isEmpty()) {

if (m_download)

m_download->cancel();

fileNameLabel->setText(tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName()));

return false;

}

}

m_file.setFile(fileName);

if (m_download && m_download->state() == QWebEngineDownloadItem::DownloadRequested)

m_download->setPath(m_file.absoluteFilePath());

fileNameLabel->setText(m_file.fileName());

return true;

}

void DownloadWidget::stop()

{

setUpdatesEnabled(false);

stopButton->setEnabled(false);

stopButton->hide();

setUpdatesEnabled(true);

if (m_download)

m_download->cancel();

emit statusChanged();

}

void DownloadWidget::open()

{QString strCommand = "cmd /C ", default_editor="";

QSettings params;

QUrl url = QUrl::fromLocalFile(m_file.absoluteFilePath());

default_editor=params.value("default_editor", "").toString();

if(default_editor.isEmpty()){

QMessageBox::critical(0, "Внимание!", "Не настроен редактор документов.\n Редактирование невозможно.",

QMessageBox::Ok);

return;

}

strCommand+=QString("\"")+default_editor+QString("\" ")+url.toString();

m_process.start(strCommand);

}

void DownloadWidget::print()

{DebenuPDFLibraryDLLQt1113 pdfTest(QString("DebenuPDFLibraryDLL1113.dll"));

int iOptions;

QString pdfFileName, customPrinter;

QStringList printParams;

QSettings moduleParams;

if(!pdfTest.LibraryLoaded()){

QMessageBox::critical(0, "Печать PDF", "Библиотека не загружена!", QMessageBox::Ok);

return;

}

if(pdfTest.UnlockKey("j39163i38a653748u9f66rb5y")!=1){

QMessageBox::critical(0, "Печать PDF", "Ошибка инициализации!", QMessageBox::Ok);

return;

}

pdfFileName=m_file.absoluteFilePath();

printParams=m_download->url().toDisplayString().section("?",1,1).split("&", QString::SkipEmptyParts);

pdfTest.LoadFromFile(pdfFileName, QString(""));

iOptions=printParams.indexOf("printerName=*");

if(iOptions>-1)

customPrinter=moduleParams.value("Printers/"+printParams.at(iOptions).section("=",1,1),pdfTest.GetDefaultPrinterName()).toString();

else

customPrinter=pdfTest.GetDefaultPrinterName();

customPrinter=pdfTest.NewCustomPrinter(customPrinter);

pdfTest.SetupCustomPrinter(customPrinter,1,9);

pdfTest.SetupCustomPrinter(customPrinter,4,1);

pdfTest.SetupCustomPrinter(customPrinter,7,1);

pdfTest.SetupCustomPrinter(customPrinter,11,1);

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

if(printParams.at(i).contains("copies="))

pdfTest.SetupCustomPrinter(customPrinter,4,printParams.at(i).section("=",1,1).toInt());//Количество копий

if(printParams.at(i).contains("format=")){

if(printParams.at(i).section("=",1,1)=="A5")

pdfTest.SetupCustomPrinter(customPrinter,1,11);

}

if(printParams.at(i).contains("duplex=")){

if(printParams.at(i).section("=",1,1)=="vertical")

pdfTest.SetupCustomPrinter(customPrinter,7,2);

if(printParams.at(i).section("=",1,1)=="horizontal")

pdfTest.SetupCustomPrinter(customPrinter,7,3);

}

if(printParams.at(i).contains("orientation=")){

if(printParams.at(i).section("=",1,1)=="landscape")

pdfTest.SetupCustomPrinter(customPrinter,11,2);

}

}

iOptions=pdfTest.PrintOptions(0, 0, "PDF_MIS");

pdfTest.PrintDocument(customPrinter,1,pdfTest.PageCount(),iOptions);

}

void DownloadWidget::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)

{

m_bytesReceived = bytesReceived;

if (bytesTotal == -1) {

progressBar->setValue(0);

progressBar->setMaximum(0);

} else {

progressBar->setValue(bytesReceived);

progressBar->setMaximum(bytesTotal);

}

updateInfoLabel();

}

void DownloadWidget::updateInfoLabel()

{

qint64 bytesTotal = progressBar->maximum();

double speed = m_bytesReceived * 1000.0 / m_downloadTime.elapsed();

double timeRemaining = ((double)(bytesTotal - m_bytesReceived)) / speed;

QString timeRemainingString = tr("seconds");

if (timeRemaining > 60) {

timeRemaining = timeRemaining / 60;

timeRemainingString = tr("minutes");

}

timeRemaining = floor(timeRemaining);

// When downloading the eta should never be 0

if (timeRemaining == 0)

timeRemaining = 1;

QString info;

if (!downloadedSuccessfully()) {

QString remaining;

if (bytesTotal != 0)

remaining = tr("- %4 %5 remaining")

.arg(timeRemaining)

.arg(timeRemainingString);

info = tr("%1 of %2 (%3/sec) %4")

.arg(dataString(m_bytesReceived))

.arg(bytesTotal == 0 ? tr("?") : dataString(bytesTotal))

.arg(dataString((int)speed))

.arg(remaining);

} else {

if (m_bytesReceived != bytesTotal) {

info = tr("%1 of %2 - Stopped")

.arg(dataString(m_bytesReceived))

.arg(dataString(bytesTotal));

} else

info = dataString(m_bytesReceived);

}

downloadInfoLabel->setText(info);

}

QString DownloadWidget::dataString(int size) const

{

QString unit;

if (size < 1024) {

unit = tr("bytes");

} else if (size < 1024*1024) {

size /= 1024;

unit = tr("kB");

} else {

size /= 1024*1024;

unit = tr("MB");

}

return QString(QLatin1String("%1 %2")).arg(size).arg(unit);

}

bool DownloadWidget::downloading() const

{

return (progressBar->isVisible());

}

bool DownloadWidget::downloadedSuccessfully() const

{

bool completed = m_download

&& m_download->isFinished()

&& m_download->state() == QWebEngineDownloadItem::DownloadCompleted;

return completed || !stopButton->isVisible();

}

void DownloadWidget::finished()

{QString url;

if (m_download) {

QWebEngineDownloadItem::DownloadState state = m_download->state();

QString message;

bool interrupted = false;

switch (state) {

case QWebEngineDownloadItem::DownloadRequested: // Fall-through.

case QWebEngineDownloadItem::DownloadInProgress:

Q_UNREACHABLE();

break;

case QWebEngineDownloadItem::DownloadCompleted:

break;

case QWebEngineDownloadItem::DownloadCancelled:

message = QStringLiteral("Download cancelled");

interrupted = true;

break;

case QWebEngineDownloadItem::DownloadInterrupted:

message = QStringLiteral("Download interrupted");

interrupted = true;

break;

}

if (interrupted) {

downloadInfoLabel->setText(message);

return;

}

}

progressBar->hide();

stopButton->setEnabled(false);

stopButton->hide();

updateInfoLabel();

url=m_download->url().toDisplayString();

if(url.contains("fn=open"))

open();

if(url.contains("fn=print"))

print();

emit statusChanged();

}

/*!

DownloadManager is a Dialog that contains a list of DownloadWidgets

It is a basic download manager. It only downloads the file, doesn't do BitTorrent,

extract zipped files or anything fancy.

*/

DownloadManager::DownloadManager(QWidget *parent)

: QDialog(parent)

, m_autoSaver(new AutoSaver(this))

, m_iconProvider(0)

, m_removePolicy(Never)

{

setupUi(this);

downloadsView->setShowGrid(false);

downloadsView->verticalHeader()->hide();

downloadsView->horizontalHeader()->hide();

downloadsView->setAlternatingRowColors(true);

downloadsView->horizontalHeader()->setStretchLastSection(true);

m_model = new DownloadModel(this);

downloadsView->setModel(m_model);

connect(cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup()));

load();

}

DownloadManager::~DownloadManager()

{

m_autoSaver->changeOccurred();

m_autoSaver->saveIfNeccessary();

if (m_iconProvider)

delete m_iconProvider;

}

int DownloadManager::activeDownloads() const

{

int count = 0;

for (int i = 0; i < m_downloads.count(); ++i) {

if (m_downloads.at(i)->stopButton->isEnabled())

++count;

}

return count;

}

void DownloadManager::download(QWebEngineDownloadItem *download)

{

DownloadWidget *widget = new DownloadWidget(download, this);

addItem(widget);

}

void DownloadManager::addItem(DownloadWidget *widget)

{

connect(widget, SIGNAL(statusChanged()), this, SLOT(updateRow()));

int row = m_downloads.count();

m_model->beginInsertRows(QModelIndex(), row, row);

m_downloads.append(widget);

m_model->endInsertRows();

updateItemCount();

downloadsView->setIndexWidget(m_model->index(row, 0), widget);

QIcon icon = style()->standardIcon(QStyle::SP_FileIcon);

widget->fileIcon->setPixmap(icon.pixmap(48, 48));

downloadsView->setRowHeight(row, widget->sizeHint().height());

}

void DownloadManager::updateRow()

{

DownloadWidget *widget = qobject_cast<DownloadWidget*>(sender());

int row = m_downloads.indexOf(widget);

if (-1 == row)

return;

if (!m_iconProvider)

m_iconProvider = new QFileIconProvider();

QIcon icon = m_iconProvider->icon(widget->m_file);

if (icon.isNull())

icon = style()->standardIcon(QStyle::SP_FileIcon);

widget->fileIcon->setPixmap(icon.pixmap(48, 48));

downloadsView->setRowHeight(row, widget->minimumSizeHint().height());

bool remove = false;

if (!widget->downloading()

&& BrowserApplication::instance()->privateBrowsing())

remove = true;

if (widget->downloadedSuccessfully()

&& removePolicy() == DownloadManager::SuccessFullDownload) {

remove = true;

}

if (remove)

m_model->removeRow(row);

cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0);

}

DownloadManager::RemovePolicy DownloadManager::removePolicy() const

{

return m_removePolicy;

}

void DownloadManager::setRemovePolicy(RemovePolicy policy)

{

if (policy == m_removePolicy)

return;

m_removePolicy = policy;

m_autoSaver->changeOccurred();

}

void DownloadManager::save() const

{

QSettings settings;

settings.beginGroup(QLatin1String("downloadmanager"));

QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy"));

settings.setValue(QLatin1String("removeDownloadsPolicy"), QLatin1String(removePolicyEnum.valueToKey(m_removePolicy)));

settings.setValue(QLatin1String("size"), size());

if (m_removePolicy == Exit)

return;

for (int i = 0; i < m_downloads.count(); ++i) {

QString key = QString(QLatin1String("download_%1_")).arg(i);

settings.setValue(key + QLatin1String("url"), m_downloads[i]->m_url);

settings.setValue(key + QLatin1String("location"), m_downloads[i]->m_file.filePath());

settings.setValue(key + QLatin1String("done"), m_downloads[i]->downloadedSuccessfully());

}

int i = m_downloads.count();

QString key = QString(QLatin1String("download_%1_")).arg(i);

while (settings.contains(key + QLatin1String("url"))) {

settings.remove(key + QLatin1String("url"));

settings.remove(key + QLatin1String("location"));

settings.remove(key + QLatin1String("done"));

key = QString(QLatin1String("download_%1_")).arg(++i);

}

}

void DownloadManager::load()

{

QSettings settings;

settings.beginGroup(QLatin1String("downloadmanager"));

QSize size = settings.value(QLatin1String("size")).toSize();

if (size.isValid())

resize(size);

QByteArray value = settings.value(QLatin1String("removeDownloadsPolicy"), QLatin1String("Never")).toByteArray();

QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy"));

m_removePolicy = removePolicyEnum.keyToValue(value) == -1 ?

Never :

static_cast<RemovePolicy>(removePolicyEnum.keyToValue(value));

int i = 0;

QString key = QString(QLatin1String("download_%1_")).arg(i);

while (settings.contains(key + QLatin1String("url"))) {

QUrl url = settings.value(key + QLatin1String("url")).toUrl();

QString fileName = settings.value(key + QLatin1String("location")).toString();

bool done = settings.value(key + QLatin1String("done"), true).toBool();

if (done && !url.isEmpty() && !fileName.isEmpty()) {

DownloadWidget *widget = new DownloadWidget(0, this);

widget->m_file.setFile(fileName);

widget->fileNameLabel->setText(widget->m_file.fileName());

widget->m_url = url;

widget->stopButton->setVisible(false);

widget->stopButton->setEnabled(false);

widget->progressBar->hide();

addItem(widget);

}

key = QString(QLatin1String("download_%1_")).arg(++i);

}

cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0);

}

void DownloadManager::cleanup()

{

if (m_downloads.isEmpty())

return;

m_model->removeRows(0, m_downloads.count());

updateItemCount();

if (m_downloads.isEmpty() && m_iconProvider) {

delete m_iconProvider;

m_iconProvider = 0;

}

m_autoSaver->changeOccurred();

}

void DownloadManager::updateItemCount()

{

int count = m_downloads.count();

itemCount->setText(count == 1 ? tr("1 Download") : tr("%1 Downloads").arg(count));

}

DownloadModel::DownloadModel(DownloadManager *downloadManager, QObject *parent)

: QAbstractListModel(parent)

, m_downloadManager(downloadManager)

{}

QVariant DownloadModel::data(const QModelIndex &index, int role) const

{

if (index.row() < 0 || index.row() >= rowCount(index.parent()))

return QVariant();

if (role == Qt::ToolTipRole)

if (!m_downloadManager->m_downloads.at(index.row())->downloadedSuccessfully())

return m_downloadManager->m_downloads.at(index.row())->downloadInfoLabel->text();

return QVariant();

}

int DownloadModel::rowCount(const QModelIndex &parent) const

{ return (parent.isValid()) ? 0 : m_downloadManager->m_downloads.count();}

bool DownloadModel::removeRows(int row, int count, const QModelIndex &parent)

{

if (parent.isValid())

return false;

int lastRow = row + count - 1;

for (int i = lastRow; i >= row; --i) {

if (m_downloadManager->m_downloads.at(i)->downloadedSuccessfully()) {

beginRemoveRows(parent, i, i);

m_downloadManager->m_downloads.takeAt(i)->deleteLater();

endRemoveRows();

}

}

m_downloadManager->m_autoSaver->changeOccurred();

return true;

}

Исходный код диалогового окона печати в pdf

#include "headers/printtopdfdialog.h"

#include "ui_printtopdfdialog.h"

#include <QtCore/QDir>

#ifndef QT_NO_PRINTER

#include <QtPrintSupport/QPageSetupDialog>

#include <QtPrintSupport/QPrinter>

#endif // QT_NO_PRINTER

#include <QtWidgets/QFileDialog>

PrintToPdfDialog::PrintToPdfDialog(const QString &filePath, QWidget *parent) :

QDialog(parent),

currentPageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0.0, 0.0, 0.0, 0.0))),

ui(new Ui::PrintToPdfDialog)

{

ui->setupUi(this);

setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

connect(ui->chooseFilePathButton, &QToolButton::clicked, this, &PrintToPdfDialog::onChooseFilePathButtonClicked);

#ifndef QT_NO_PRINTER

connect(ui->choosePageLayoutButton, &QToolButton::clicked, this, &PrintToPdfDialog::onChoosePageLayoutButtonClicked);

#else

ui->choosePageLayoutButton->hide();

#endif // QT_NO_PRINTER

updatePageLayoutLabel();

setFilePath(filePath);


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.