#include "sqlitehelper.h" #include #include #include "globalvariables.h" #include "MyButton.h" #include #include #include #include #include #include #include #include "navbar.h" #include "config.h" #include #include #include #include #include #include #include "applicationmanager.h" #define MAX_KEY_LENGTH 255 #define MAX_VALUE_NAME 16383 #ifdef _DEBUG #pragma comment (lib,"Qt5Xmld.lib") #else #pragma comment (lib,"Qt5Xml.lib") #endif #pragma comment (lib,"Shell32.lib") #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING #include #include namespace fs= std::experimental::filesystem; bool getMenu(std::wstring &path_str,QHash *paths) { fs::directory_iterator* it = new fs::directory_iterator(path_str); for (auto file : *it) { Record record; if (fs::is_regular_file(file)) { if (file.path().extension().wstring() == L".lnk") { HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { IShellLink* pShellItem; hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pShellItem); if (SUCCEEDED(hr)) { IPersistFile* pPersistFile; hr = pShellItem->QueryInterface(IID_IPersistFile, (void**)&pPersistFile); if (SUCCEEDED(hr)) { WCHAR szTargetPath[MAX_PATH]; LPOLESTR pszTargetPath = szTargetPath; hr = pPersistFile->Load(file.path().wstring().c_str(), STGM_READ); if (SUCCEEDED(hr)) { WIN32_FIND_DATA fd; hr = pShellItem->GetPath(szTargetPath, sizeof(szTargetPath), &fd, 0); ; if (SUCCEEDED(hr)) { QString filename = file.path().filename().string().c_str(); *paths->insert(filename,QString::fromWCharArray(szTargetPath)); } else { pPersistFile->Release(); pShellItem->Release(); CoUninitialize(); return false; } } else { pPersistFile->Release(); pShellItem->Release(); CoUninitialize(); return false; } pPersistFile->Release(); } else { pShellItem->Release(); pShellItem->Release(); CoUninitialize(); return false; } pShellItem->Release(); } else { CoUninitialize(); return false; } CoUninitialize(); } } }else if(fs::is_directory(file)) { getMenu(file.path().wstring(), paths); } } delete it; return true; } SQLiteHelper::SQLiteHelper(QObject *parent) : QObject(parent) { if (QSqlDatabase::contains("mydb")) { db = QSqlDatabase::database("mydb"); } else { db = QSqlDatabase::addDatabase("QSQLITE","mydb"); QString name = QApplication::applicationDirPath() + "/identifier.sqlite"; db.setDatabaseName(name); } if (!db.open()) { QMessageBox::critical(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("无法打开数据库")); exit_manager.exit(1); } } SQLiteHelper::~SQLiteHelper() { } bool SQLiteHelper::update_software() { HKEY hKeyUninstall = nullptr; QHash* paths = new QHash; //开始菜单中已安装软件列表 WCHAR path[MAX_PATH]; HRESULT hr = SHGetFolderPathW(nullptr, CSIDL_COMMON_PROGRAMS, nullptr, 0, path);//获取ProgramData中开始菜单的路径 std::wstring path_str(path); getMenu(path_str, paths); for (int i = 0; i < sizeof(path) / sizeof(wchar_t); i++) { path[i] = 0; } hr = SHGetFolderPathW(nullptr, CSIDL_PROGRAMS, nullptr, 0, path);//获取用户文件夹中开始菜单的路径 path_str.clear(); path_str = std::wstring(path); getMenu(path_str, paths); // 打开注册表中的已安装软件列表 QHash reg_records; HKEY hKey; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name DWORD cbName; // size of name string TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys = 0; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time DWORD i, retCode; TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey( hKey, // key handle achClass, // buffer for class name &cchClassName, // size of class string NULL, // reserved &cSubKeys, // number of subkeys &cbMaxSubKey, // longest subkey size &cchMaxClass, // longest class string &cValues, // number of values for this key &cchMaxValue, // longest value name &cbMaxValueData, // longest value data &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time // 枚举该列表下所有子键 for (DWORD i = 0; i < cSubKeys; i++) { WCHAR szSubKey[MAX_PATH] = { 0 }; DWORD dwSize = MAX_PATH; if (RegEnumKeyExW(hKey, i, szSubKey, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { // 读取软件属性值 HKEY hSubKey; if (RegOpenKeyExW(hKey, szSubKey, 0, KEY_READ | KEY_WOW64_64KEY, &hSubKey) == ERROR_SUCCESS) { Record record; WCHAR szProductPath[MAX_PATH] = { 0 }; WCHAR buffer[MAX_PATH] = { 0 }; DWORD buffer_num; dwSize = MAX_PATH * sizeof(WCHAR); //安装文件夹 if (RegQueryValueExW(hSubKey, L"InstallLocation", NULL, NULL, (LPBYTE)szProductPath, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); continue; } QString path = QString::fromWCharArray(szProductPath); //软件名 if (RegQueryValueExW(hSubKey, L"DisplayName", NULL, NULL, (LPBYTE)buffer, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); continue; } record.name = QString::fromWCharArray(buffer); record.orig_name = QString::fromWCharArray(buffer); //图标 RegQueryValueExW(hSubKey, L"DisplayIcon", NULL, NULL, (LPBYTE)buffer, &dwSize); record.logo = QString::fromWCharArray(buffer); //主版本号 RegQueryValueExW(hSubKey, L"VersionMajor", NULL, NULL, (LPBYTE)&buffer_num, &dwSize); QString versionMajor = QString::number(buffer_num); //次版本号 RegQueryValueExW(hSubKey, L"VersionMinor", NULL, NULL, (LPBYTE)&buffer_num, &dwSize); QString versionMinor = QString::number(buffer_num); //将主版本号和次版本号拼接在一起 QString version = versionMajor + "." + versionMinor; record.version = version; //开发者 RegQueryValueExW(hSubKey, L"Publisher", NULL, NULL, (LPBYTE)buffer, &dwSize); record.dev = QString::fromWCharArray(buffer); record.type = "app"; record.status = true; record.op = "soft"; record.locked = false; RegCloseKey(hSubKey); if (!path.isEmpty()) { reg_records.insert(path, record); } } } else { break; } } RegCloseKey(hKey); } HKEY hkey2; if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, KEY_READ, &hkey2) == ERROR_SUCCESS) { TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name DWORD cbName; // size of name string TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys = 0; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time DWORD i, retCode; TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey( hkey2, // key handle achClass, // buffer for class name &cchClassName, // size of class string NULL, // reserved &cSubKeys, // number of subkeys &cbMaxSubKey, // longest subkey size &cchMaxClass, // longest class string &cValues, // number of values for this key &cchMaxValue, // longest value name &cbMaxValueData, // longest value data &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time // 枚举该列表下所有子键 for (DWORD i = 0; i < cSubKeys; i++) { WCHAR szSubKey[MAX_PATH] = { 0 }; DWORD dwSize = MAX_PATH; if (RegEnumKeyExW(hkey2, i, szSubKey, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { // 读取软件属性值 HKEY hSubKey; if (RegOpenKeyExW(hkey2, szSubKey, 0, KEY_READ | KEY_WOW64_64KEY, &hSubKey) == ERROR_SUCCESS) { Record record; WCHAR szProductPath[MAX_PATH] = { 0 }; WCHAR buffer[MAX_PATH] = { 0 }; DWORD buffer_num; dwSize = MAX_PATH * sizeof(WCHAR); //安装文件夹 if (RegQueryValueExW(hSubKey, L"InstallLocation", NULL, NULL, (LPBYTE)szProductPath, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); continue; } QString path = QString::fromWCharArray(szProductPath); //软件名 if (RegQueryValueExW(hSubKey, L"DisplayName", NULL, NULL, (LPBYTE)buffer, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); continue; } record.name = QString::fromWCharArray(buffer); record.orig_name = QString::fromWCharArray(buffer); //图标 RegQueryValueExW(hSubKey, L"DisplayIcon", NULL, NULL, (LPBYTE)buffer, &dwSize); record.logo = QString::fromWCharArray(buffer); //主版本号 RegQueryValueExW(hSubKey, L"VersionMajor", NULL, NULL, (LPBYTE)&buffer_num, &dwSize); QString versionMajor = QString::number(buffer_num); //次版本号 RegQueryValueExW(hSubKey, L"VersionMinor", NULL, NULL, (LPBYTE)&buffer_num, &dwSize); QString versionMinor = QString::number(buffer_num); //将主版本号和次版本号拼接在一起 QString version = versionMajor + "." + versionMinor; record.version = version; //开发者 RegQueryValueExW(hSubKey, L"Publisher", NULL, NULL, (LPBYTE)buffer, &dwSize); record.dev = QString::fromWCharArray(buffer); record.type = "app"; record.status = true; record.op = "soft"; record.locked = false; RegCloseKey(hSubKey); reg_records.insert(path, record); } } else { break; } } RegCloseKey(hkey2); } BOOL isWow64; if (IsWow64Process(GetCurrentProcess(), &isWow64)) { HKEY hkey3; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, KEY_READ | KEY_WOW64_64KEY, &hkey3) == ERROR_SUCCESS) { TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name DWORD cbName; // size of name string TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys = 0; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time DWORD i, retCode; TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey( hkey3, // key handle achClass, // buffer for class name &cchClassName, // size of class string NULL, // reserved &cSubKeys, // number of subkeys &cbMaxSubKey, // longest subkey size &cchMaxClass, // longest class string &cValues, // number of values for this key &cchMaxValue, // longest value name &cbMaxValueData, // longest value data &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time // 枚举该列表下所有子键 for (DWORD i = 0; i < cSubKeys; i++) { WCHAR szSubKey[MAX_PATH] = { 0 }; DWORD dwSize = MAX_PATH; if (RegEnumKeyExW(hkey3, i, szSubKey, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { // 读取软件属性值 HKEY hSubKey; if (RegOpenKeyExW(hkey3, szSubKey, 0, KEY_READ | KEY_WOW64_64KEY, &hSubKey) == ERROR_SUCCESS) { Record record; WCHAR szProductPath[MAX_PATH] = { 0 }; WCHAR buffer[MAX_PATH] = { 0 }; DWORD buffer_num; dwSize = MAX_PATH * sizeof(WCHAR); //安装文件夹 if (RegQueryValueExW(hSubKey, L"InstallLocation", NULL, NULL, (LPBYTE)szProductPath, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); continue; } QString path = QString::fromWCharArray(szProductPath); //软件名 if (RegQueryValueExW(hSubKey, L"DisplayName", NULL, NULL, (LPBYTE)buffer, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); continue; } record.name = QString::fromWCharArray(buffer); record.orig_name = QString::fromWCharArray(buffer); //图标 RegQueryValueExW(hSubKey, L"DisplayIcon", NULL, NULL, (LPBYTE)buffer, &dwSize); record.logo = QString::fromWCharArray(buffer); //主版本号 RegQueryValueExW(hSubKey, L"VersionMajor", NULL, NULL, (LPBYTE)&buffer_num, &dwSize); QString versionMajor = QString::number(buffer_num); //次版本号 RegQueryValueExW(hSubKey, L"VersionMinor", NULL, NULL, (LPBYTE)&buffer_num, &dwSize); QString versionMinor = QString::number(buffer_num); //将主版本号和次版本号拼接在一起 QString version = versionMajor + "." + versionMinor; record.version = version; //开发者 RegQueryValueExW(hSubKey, L"Publisher", NULL, NULL, (LPBYTE)buffer, &dwSize); record.dev = QString::fromWCharArray(buffer); record.type = "app"; record.status = true; record.op = "soft"; record.locked = false; RegCloseKey(hSubKey); reg_records.insert(path, record); } } else { break; } } RegCloseKey(hkey3); } HKEY hkey4; if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, KEY_READ | KEY_WOW64_64KEY, &hkey4) == ERROR_SUCCESS) { TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name DWORD cbName; // size of name string TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys = 0; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time DWORD i, retCode; TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey( hkey3, // key handle achClass, // buffer for class name &cchClassName, // size of class string NULL, // reserved &cSubKeys, // number of subkeys &cbMaxSubKey, // longest subkey size &cchMaxClass, // longest class string &cValues, // number of values for this key &cchMaxValue, // longest value name &cbMaxValueData, // longest value data &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time // 枚举该列表下所有子键 for (DWORD i = 0; i < cSubKeys; i++) for (DWORD i = 0; ; i++) { WCHAR szSubKey[MAX_PATH] = { 0 }; DWORD dwSize = MAX_PATH; if (RegEnumKeyExW(hkey4, i, szSubKey, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { //读取软件属性值 HKEY hSubKey; if (RegOpenKeyExW(hkey3, szSubKey, 0, KEY_READ | KEY_WOW64_64KEY, &hSubKey) == ERROR_SUCCESS) { Record record; WCHAR szProductPath[MAX_PATH] = { 0 }; WCHAR buffer[MAX_PATH] = { 0 }; DWORD buffer_num; dwSize = MAX_PATH * sizeof(WCHAR); //安装文件夹 if (RegQueryValueExW(hSubKey, L"InstallLocation", NULL, NULL, (LPBYTE)szProductPath, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); continue; } QString path = QString::fromWCharArray(szProductPath); //软件名 if (RegQueryValueExW(hSubKey, L"DisplayName", NULL, NULL, (LPBYTE)buffer, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); continue; } record.name = QString::fromWCharArray(buffer); record.orig_name = QString::fromWCharArray(buffer); //图标 RegQueryValueExW(hSubKey, L"DisplayIcon", NULL, NULL, (LPBYTE)buffer, &dwSize); record.logo = QString::fromWCharArray(buffer); //主版本号 RegQueryValueExW(hSubKey, L"VersionMajor", NULL, NULL, (LPBYTE)&buffer_num, &dwSize); QString versionMajor = QString::number(buffer_num); //次版本号 RegQueryValueExW(hSubKey, L"VersionMinor", NULL, NULL, (LPBYTE)&buffer_num, &dwSize); QString versionMinor = QString::number(buffer_num); //将主版本号和次版本号拼接在一起 QString version = versionMajor + "." + versionMinor; record.version = version; //开发者 RegQueryValueExW(hSubKey, L"Publisher", NULL, NULL, (LPBYTE)buffer, &dwSize); record.dev = QString::fromWCharArray(buffer); record.type = "app"; record.locked = false; record.status = true; record.op = "soft"; RegCloseKey(hSubKey); reg_records.insert(path, record); } } else { break; } } RegCloseKey(hkey4); } } QHash public_programs_list; for (auto key : reg_records.keys()) { public_programs_list.insert(reg_records[key].orig_name, reg_records[key]); } QSqlQuery find2(db); QJsonArray array; if (find2.exec("select * from kmd_menu where status=1;")) { while (find2.next()) { QJsonObject obj; obj.insert("sort", find2.value("sort").toInt()); obj.insert("app_id", find2.value("app_id").toString()); obj.insert("locked", find2.value("locked").toBool()); obj.insert("type", find2.value("type").toString()); obj.insert("category_id", find2.value("category_id").toString()); obj.insert("name", find2.value("name").toString()); obj.insert("orig_name", find2.value("orig_name").toString()); obj.insert("version", find2.value("version").toString()); obj.insert("dev", find2.value("dev").toString()); obj.insert("create_time", find2.value("create_time").toInt()); obj.insert("use_time", find2.value("use_time").toInt()); obj.insert("op", find2.value("op").toString()); obj.insert("func", find2.value("func").toString()); obj.insert("path", find2.value("path").toString()); obj.insert("url", find2.value("url").toString()); obj.insert("initial_position", find2.value("initial_position").toString()); obj.insert("logo", find2.value("logo").toString()); obj.insert("status", find2.value("status").toBool()); obj.insert("is_navbar", find2.value("is_navbar").toBool()); obj.insert("is_elite", find2.value("is_elite").toBool()); array.append(obj); } } //进行网络请求,补全字段 SoftwareRequest software_request; bool ok=software_request.sendRequest(*paths,&public_programs_list,array); if(!ok) { return false; } QSqlQuery begin(db); if (!begin.exec("begin;")) { return false; } for(auto key : public_programs_list.keys()) { QSqlQuery query(db); QString sql_find = "select sort from kmd_menu where orig_name='"; sql_find += key; sql_find += "';"; QSqlQuery query_find(db); if(!query_find.exec(sql_find)) { QSqlQuery rollback(db); rollback.exec("rollback;"); return false; } QString sql; if(query_find.next()) { sql = "update kmd_menu set"; sql += " path='"; sql += public_programs_list[key].path; sql += "'"; sql += " ,op='"; sql += public_programs_list[key].op; sql += "' ,func='"; sql += public_programs_list[key].func; sql += "' ,url='"; sql += public_programs_list[key].url; sql += "' where orig_name='"; sql += key; sql += "';"; } else { public_programs_list[key].img.replace(QApplication::applicationDirPath(), ""); sql = "insert into kmd_menu (sort,app_id,locked,type,category_id,name,orig_name,version,dev,create_time,use_time,op,func,path,url,status,is_navbar,is_elite) values " "(:sort,:app_id,:locked,:type,:category_id,:name,:orig_name,:version,:dev,:create_time,:use_time,:op,:func,:path,:url,:status,:is_navbar,:is_elite); "; query.prepare(sql); query.bindValue(":sort", 50); query.bindValue(":app_id", public_programs_list[key].app_id); query.bindValue(":locked", public_programs_list[key].locked); query.bindValue(":type", public_programs_list[key].type); query.bindValue(":category_id", public_programs_list[key].category_id); query.bindValue(":name", public_programs_list[key].name); query.bindValue(":orig_name", public_programs_list[key].orig_name); query.bindValue(":version", public_programs_list[key].version); query.bindValue(":dev", public_programs_list[key].dev); query.bindValue(":create_time", public_programs_list[key].create_time); query.bindValue(":use_time", public_programs_list[key].use_time); query.bindValue(":op", public_programs_list[key].op); query.bindValue(":func", public_programs_list[key].func); query.bindValue(":path", public_programs_list[key].path); query.bindValue(":url", public_programs_list[key].url); query.bindValue(":is_navbar", public_programs_list[key].is_navbar); query.bindValue(":is_elite", public_programs_list[key].is_elite); query.bindValue(":status", true); bool categories[CATEGORIES_NUM] = { false }; categories[ALL - 1] = true; categories[SOFT - 1] = true; } update_total(); if(!query.exec(sql)) { QSqlQuery rollback("rollback;"); rollback.exec(); return false; } } QSqlQuery find(db); find.exec("select orig_name,op from kmd_menu;"); while(find.next()) { if(!public_programs_list.contains(find.value("orig_name").toString())) { if (find.value("op").toString() == "soft") { QSqlQuery del(db); del.prepare("update kmd_menu set status=0 where orig_name=:orig_name;"); del.bindValue(":orig_value", find.value("orig_name")); del.exec(); bool categories[CATEGORIES_NUM] = { false }; categories[ALL - 1] = true; categories[SOFT - 1] = true; update_total(); } } } find.clear(); find.exec("select id from kmd_menu where status=0;"); if(find.size()>=100) { QSqlQuery del(db); del.exec("delete from kmd_menu where status=0;"); } QSqlQuery commit(db); commit.exec("commit;"); return true; } void SetSVGBackColor(QDomElement& elem, QString strtagname, QString strattr, QString strattrval) { if (elem.tagName().compare(strtagname) == 0) { QString before_color = elem.attribute(strattr); elem.setAttribute(strattr, strattrval); QString color = elem.attribute(strattr); } for (int i = 0; i < elem.childNodes().count(); i++) { if (!elem.childNodes().at(i).isElement()) { continue; } SetSVGBackColor(elem.childNodes().at(i).toElement(), strtagname, strattr, strattrval); } } bool SQLiteHelper::get_software(QList* button_structs, ConfigResponse* config_response) { QSqlQuery query(db); QString sql = "select * from kmd_menu where is_navbar=1 order by sort,orig_name asc ;"; QString title_color; QString title_cover_color; QList