AppConfig.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. #include "AppConfig.h"
  2. #include <QProcess>
  3. #include <QDesktopWidget>
  4. #include <QDesktopServices>
  5. #include <QByteArray>
  6. #include <QCryptographicHash>
  7. #include <QFile>
  8. #include <QFileInfo>
  9. #include <QDir>
  10. #include <QCoreApplication>
  11. #include <QTranslator>
  12. #include <QDateTime>
  13. #include <QApplication>
  14. #include <QMessageBox>
  15. #include <QJsonParseError>
  16. #include <QJsonObject>
  17. #include <QJsonArray>
  18. #include <QJsonDocument>
  19. #include <QJsonObject>
  20. #include <QDebug>
  21. #if defined(WIN32)
  22. #include <WinSock2.h>
  23. #include <Windows.h>
  24. #include <direct.h>
  25. #include <io.h> //C (Windows) access
  26. #else
  27. #include <sys/time.h>
  28. #include <stdio.h>
  29. #include <unistd.h>
  30. void Sleep(long mSeconds);
  31. //{
  32. // usleep(mSeconds * 1000);
  33. //}
  34. #endif
  35. QString AppConfig::APPID = "{a1db97ad-b8ed-11e9-a297-0235d2b38928}";
  36. int AppConfig::VERSION = 1;
  37. QString AppConfig::VERSION_NAME = "2.1.3";
  38. MainWindow *AppConfig::gMainWindow = NULL;
  39. QRect AppConfig::gMainWindowRect;
  40. QRect AppConfig::gScreenRect;
  41. bool AppConfig::gVideoKeepAspectRatio = false; //按比例显示
  42. bool AppConfig::gVideoHardDecoder = false; //硬解解码
  43. QString AppConfig::gVideoFilePath;
  44. QString AppConfig::AppDataPath_Main;
  45. QString AppConfig::AppDataPath_Data;
  46. QString AppConfig::AppDataPath_Tmp;
  47. QString AppConfig::AppDataPath_TmpFile;
  48. QString AppConfig::AppFilePath_Log;
  49. QString AppConfig::AppFilePath_LogFile;
  50. QString AppConfig::AppFilePath_EtcFile;
  51. AppConfig::AppConfig()
  52. {
  53. }
  54. void AppConfig::MakeDir(QString dirName)
  55. {
  56. QDir dir;
  57. dir.mkpath(dirName);
  58. }
  59. void AppConfig::InitAllDataPath()
  60. {
  61. #if defined(WIN32)
  62. ///windows数据存储在C盘的数据目录下
  63. QFileInfo fileInfo(QCoreApplication::applicationFilePath());
  64. QString exeFileName = fileInfo.baseName(); //当前程序名字
  65. QString dataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
  66. if (dataPath.right(exeFileName.length()) == exeFileName)
  67. {
  68. dataPath = dataPath.left(dataPath.length() - exeFileName.length());
  69. }
  70. if (!dataPath.endsWith("/"))
  71. {
  72. dataPath += "/";
  73. }
  74. #else
  75. ///Linux则放在程序所在目录下的data目录下
  76. QFileInfo fileInfo(QCoreApplication::applicationFilePath());
  77. QString dataPath = fileInfo.absoluteDir().path();
  78. if (!dataPath.endsWith("/"))
  79. {
  80. dataPath += "/";
  81. }
  82. #endif
  83. qDebug()<<__FUNCTION__<<dataPath;
  84. AppDataPath_Main = dataPath;
  85. AppDataPath_Data = AppDataPath_Main + "/data";
  86. QString dirName = AppDataPath_Data + "/etc";
  87. MakeDir(dirName);
  88. AppFilePath_EtcFile = dirName + "/main.conf";
  89. AppDataPath_Tmp = AppDataPath_Data + "/tmp";
  90. AppFilePath_Log = AppDataPath_Data + "/log";
  91. AppDataPath_TmpFile = AppDataPath_Tmp + "/tmp.txt";
  92. MakeDir(AppDataPath_Data);
  93. MakeDir(AppFilePath_Log);
  94. MakeDir(AppDataPath_Tmp);
  95. InitLogFile();
  96. }
  97. QString AppConfig::bufferToString(QByteArray sendbuf)
  98. {
  99. QString tmp;
  100. for (int k = 0; k < sendbuf.size(); k++)
  101. {
  102. QString str = QString("%1").arg(sendbuf[k] & 0xff, 2, 16, QLatin1Char('0'));
  103. // tmp += str + " ";
  104. tmp += str;
  105. }
  106. tmp = tmp.toUpper();
  107. return tmp;
  108. }
  109. QByteArray AppConfig::StringToBuffer(QString str)
  110. {
  111. QString text = str.remove(" ");
  112. QByteArray sendbuf;
  113. while(!text.isEmpty())
  114. {
  115. QString str = text.left(2);
  116. if (str.length() == 1)
  117. {
  118. str = "0" + str;
  119. }
  120. text.remove(0,2);
  121. int x = str.left(1).toInt(0,16) << 4;
  122. x += str.right(1).toInt(0,16);
  123. QByteArray buf;
  124. buf.resize(1);
  125. buf[0] = x;
  126. sendbuf.append(buf);
  127. }
  128. return sendbuf;
  129. }
  130. QString AppConfig::getFileMd5(QString filePath,qint64 size)
  131. {
  132. QFile localFile(filePath);
  133. if (!localFile.open(QFile::ReadOnly))
  134. {
  135. // qDebug() << "file open error.";
  136. return "";
  137. }
  138. QCryptographicHash ch(QCryptographicHash::Md5);
  139. quint64 totalBytes = 0;
  140. quint64 bytesWritten = 0;
  141. quint64 bytesToWrite = 0;
  142. quint64 loadSize = 1024 * 4;
  143. QByteArray buf;
  144. totalBytes = localFile.size();
  145. if (size > 0)
  146. {
  147. bytesToWrite = size;
  148. }
  149. else
  150. {
  151. bytesToWrite = totalBytes;
  152. }
  153. if (bytesToWrite > totalBytes)
  154. {
  155. bytesToWrite = totalBytes;
  156. }
  157. while (1)
  158. {
  159. if(bytesToWrite > 0)
  160. {
  161. buf = localFile.read(qMin(bytesToWrite, loadSize));
  162. ch.addData(buf);
  163. bytesWritten += buf.length();
  164. bytesToWrite -= buf.length();
  165. buf.resize(0);
  166. }
  167. else
  168. {
  169. break;
  170. }
  171. if (bytesToWrite <= 0)
  172. {
  173. break;
  174. }
  175. // if(bytesWritten == totalBytes)
  176. // {
  177. // break;
  178. // }
  179. }
  180. localFile.close();
  181. QByteArray md5 = ch.result();
  182. return AppConfig::bufferToString(md5).toLower();
  183. }
  184. void AppConfig::loadConfigInfoFromFile()
  185. {
  186. QFile file(AppConfig::AppFilePath_EtcFile);
  187. bool ret = file.open(QIODevice::ReadOnly);
  188. if (!ret) return;
  189. QString text(file.readAll());
  190. if (!text.isEmpty())
  191. {
  192. QJsonParseError json_error;
  193. QJsonDocument jsonDoc(QJsonDocument::fromJson(text.toUtf8(), &json_error));
  194. if(json_error.error == QJsonParseError::NoError)
  195. {
  196. QJsonObject object = jsonDoc.object();
  197. QJsonValue VideoKeepAspectRatioValue = object.value("VideoKeepAspectRatio");
  198. QJsonValue VideoFilePathValue = object.value("VideoFilePath");
  199. AppConfig::gVideoKeepAspectRatio = VideoKeepAspectRatioValue.toBool();
  200. AppConfig::gVideoFilePath = VideoFilePathValue.toString();
  201. }
  202. }
  203. file.close();
  204. }
  205. void AppConfig::saveConfigInfoToFile()
  206. {
  207. QFile file(AppConfig::AppFilePath_EtcFile);
  208. if (file.open(QIODevice::WriteOnly))
  209. {
  210. QTextStream fileOut(&file);
  211. fileOut.setCodec("UTF-8"); //unicode UTF-8 ANSI
  212. QJsonObject dataObject;
  213. dataObject.insert("appid", AppConfig::APPID);
  214. dataObject.insert("VideoKeepAspectRatio", AppConfig::gVideoKeepAspectRatio);
  215. dataObject.insert("VideoFilePath", AppConfig::gVideoFilePath);
  216. QJsonDocument json;
  217. // QJsonObject object;
  218. // object.insert("config", dataObject);
  219. //最外层是大括号所以是object
  220. json.setObject(dataObject);
  221. QString jsonStr = json.toJson(QJsonDocument::Compact);
  222. fileOut<<jsonStr;
  223. // std::string str = base64::base64_encode((unsigned char*)jsonStr.toUtf8().data(),jsonStr.toUtf8().size());
  224. // fileOut<<QString::fromStdString(str);
  225. file.close();
  226. }
  227. }
  228. void AppConfig::InitLogFile()
  229. {
  230. // QString logFilePath = AppFilePath_Log + "\\log.txt";
  231. // gLogFile.setFileName(logFilePath);
  232. QDir dir(AppFilePath_Log);
  233. QFileInfoList fileInfoList = dir.entryInfoList();
  234. foreach(QFileInfo fileInfo, fileInfoList)
  235. {
  236. if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
  237. continue;
  238. if(fileInfo.isFile())
  239. {
  240. qint64 t1 = fileInfo.created().toMSecsSinceEpoch();
  241. qint64 t2 = QDateTime::currentMSecsSinceEpoch();
  242. qint64 t = (t2 - t1) / 1000; //文件创建到现在的时间(单位:秒)
  243. if (t >= (24*3600*3)) //删除3天前的日志文件
  244. // if (t >= (60*20))
  245. {
  246. QFile::remove(fileInfo.absoluteFilePath());
  247. }
  248. }
  249. }
  250. AppFilePath_LogFile = AppFilePath_Log + QString("/log_%1.txt").arg(QDate::currentDate().toString("yyyy-MM-dd"));
  251. WriteLog("\r\n=======================================\r\n=======================================\r\n[App Start...]\r\n\r\n");
  252. }
  253. #if 0
  254. bool AppConfig::WriteLog(QString str)
  255. {
  256. bool IsFileOpened = gLogFile.isOpen();
  257. if (!IsFileOpened)
  258. {
  259. IsFileOpened = gLogFile.open(QIODevice::ReadWrite);
  260. gLogFile.seek(gLogFile.size());
  261. }
  262. if (IsFileOpened)
  263. {
  264. QString tmpStr = QString("[%1] %2 \r\n")
  265. .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
  266. .arg(str);
  267. QTextStream fileOut(&gLogFile);
  268. fileOut.setCodec("UTF-8"); //unicode UTF-8 ANSI
  269. fileOut<<tmpStr;
  270. }
  271. return IsFileOpened;
  272. }
  273. #else
  274. void AppConfig::WriteLog(QString str)
  275. {
  276. // qDebug()<<__FUNCTION__<<str;
  277. QFile file(AppFilePath_LogFile);
  278. if (file.open(QIODevice::ReadWrite))
  279. {
  280. file.seek(file.size());
  281. QString tmpStr = QString("[%1] %2 \r\n")
  282. .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
  283. .arg(str);
  284. QTextStream fileOut(&file);
  285. fileOut.setCodec("UTF-8"); //unicode UTF-8 ANSI
  286. fileOut<<tmpStr;
  287. file.close();
  288. }
  289. }
  290. #endif
  291. QString AppConfig::getSizeInfo(qint64 size)
  292. {
  293. int pee = 1024;
  294. char ch[10]={0};
  295. if (size > (pee*pee*pee)) //大于1G
  296. {
  297. sprintf(ch,"%dGB",(int)(size*1.0/pee/pee/pee+0.5));
  298. }
  299. else if (size > (pee*pee)) //大于1M
  300. {
  301. sprintf(ch,"%dMB",size/pee/pee);
  302. }
  303. else if (size > pee) //大于1K
  304. {
  305. sprintf(ch,"%dKB",size/pee);
  306. }
  307. else //小于1KB
  308. {
  309. sprintf(ch,"%dB",size);
  310. }
  311. QString str = QString(ch);
  312. return str;
  313. }
  314. QImage AppConfig::ImagetoGray( QImage image)
  315. {
  316. int height = image.height();
  317. int width = image.width();
  318. QImage ret(width, height, QImage::Format_Indexed8);
  319. ret.setColorCount(256);
  320. for(int i = 0; i < 256; i++)
  321. {
  322. ret.setColor(i, qRgb(i, i, i));
  323. }
  324. switch(image.format())
  325. {
  326. case QImage::Format_Indexed8:
  327. for(int i = 0; i < height; i ++)
  328. {
  329. const uchar *pSrc = (uchar *)image.constScanLine(i);
  330. uchar *pDest = (uchar *)ret.scanLine(i);
  331. memcpy(pDest, pSrc, width);
  332. }
  333. break;
  334. case QImage::Format_RGB32:
  335. case QImage::Format_ARGB32:
  336. case QImage::Format_ARGB32_Premultiplied:
  337. for(int i = 0; i < height; i ++)
  338. {
  339. const QRgb *pSrc = (QRgb *)image.constScanLine(i);
  340. uchar *pDest = (uchar *)ret.scanLine(i);
  341. for( int j = 0; j < width; j ++)
  342. {
  343. pDest[j] = qGray(pSrc[j]);
  344. }
  345. }
  346. break;
  347. }
  348. return ret;
  349. }
  350. //拷贝文件夹:
  351. bool AppConfig::copyDirectoryFiles(const QString &fromDir, const QString &toDir, bool coverFileIfExist)
  352. {
  353. QDir sourceDir(fromDir);
  354. QDir targetDir(toDir);
  355. if(!targetDir.exists()){ /**< 如果目标目录不存在,则进行创建 */
  356. if(!targetDir.mkdir(targetDir.absolutePath()))
  357. return false;
  358. }
  359. QFileInfoList fileInfoList = sourceDir.entryInfoList();
  360. foreach(QFileInfo fileInfo, fileInfoList){
  361. if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
  362. continue;
  363. if(fileInfo.isDir()){ /**< 当为目录时,递归的进行copy */
  364. if(!copyDirectoryFiles(fileInfo.filePath(),
  365. targetDir.filePath(fileInfo.fileName()),
  366. coverFileIfExist))
  367. return false;
  368. }
  369. else{ /**< 当允许覆盖操作时,将旧文件进行删除操作 */
  370. if(coverFileIfExist && targetDir.exists(fileInfo.fileName())){
  371. targetDir.remove(fileInfo.fileName());
  372. }
  373. /// 进行文件copy
  374. if(!QFile::copy(fileInfo.filePath(),
  375. targetDir.filePath(fileInfo.fileName()))){
  376. return false;
  377. }
  378. }
  379. }
  380. return true;
  381. }
  382. bool AppConfig::removeDirectory(QString dirName)
  383. {
  384. QDir dir(dirName);
  385. QString tmpdir = "";
  386. if (!QFile(dirName).exists()) return false;
  387. if(!dir.exists()){
  388. return false;
  389. }
  390. QFileInfoList fileInfoList = dir.entryInfoList();
  391. foreach(QFileInfo fileInfo, fileInfoList){
  392. if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
  393. continue;
  394. if(fileInfo.isDir()){
  395. tmpdir = dirName + ("/") + fileInfo.fileName();
  396. removeDirectory(tmpdir);
  397. dir.rmdir(fileInfo.fileName()); /**< 移除子目录 */
  398. }
  399. else if(fileInfo.isFile()){
  400. QFile tmpFile(fileInfo.fileName());
  401. dir.remove(tmpFile.fileName()); /**< 删除临时文件 */
  402. }
  403. else{
  404. ;
  405. }
  406. }
  407. dir.cdUp(); /**< 返回上级目录,因为只有返回上级目录,才可以删除这个目录 */
  408. if(dir.exists(dirName)){
  409. if(!dir.rmdir(dirName))
  410. return false;
  411. }
  412. return true;
  413. }
  414. #if defined(Q_OS_WIN32)
  415. #include <ShlObj.h>
  416. #include <ShellAPI.h>
  417. bool AppConfig::restartSelf()
  418. {
  419. SHELLEXECUTEINFO sei;
  420. TCHAR szModule [MAX_PATH],szComspec[MAX_PATH],szParams [MAX_PATH];
  421. // 获得文件名.
  422. if((GetModuleFileName(0,szModule,MAX_PATH)!=0) &&
  423. (GetShortPathName(szModule,szModule,MAX_PATH)!=0) &&
  424. (GetEnvironmentVariable(L"COMSPEC",szComspec,MAX_PATH)!=0))
  425. {
  426. // QString dirPath = QCoreApplication::applicationDirPath();
  427. QString dirPath = QCoreApplication::applicationFilePath();
  428. dirPath.replace("/","\\");
  429. dirPath = "\"" + dirPath + "\"";
  430. // 设置命令参数.
  431. lstrcpy(szParams, L"/c ");
  432. lstrcat(szParams, (WCHAR*)dirPath.utf16());
  433. lstrcat(szParams, L" > nul");
  434. // lstrcpy(szParams, L"/c del ");
  435. // lstrcat(szParams, szModule);
  436. // lstrcat(szParams, L" > nul");
  437. // 设置结构成员.
  438. sei.cbSize = sizeof(sei);
  439. sei.hwnd = 0;
  440. sei.lpVerb = L"Open";
  441. sei.lpFile = szComspec;
  442. sei.lpParameters = szParams;
  443. sei.lpDirectory = 0;
  444. sei.nShow = SW_HIDE;
  445. sei.fMask = SEE_MASK_NOCLOSEPROCESS;
  446. // 执行shell命令.
  447. if(ShellExecuteEx(&sei))
  448. {
  449. // 设置命令行进程的执行级别为空闲执行,使本程序有足够的时间从内存中退出.
  450. SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS);
  451. SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
  452. SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
  453. // 通知Windows资源浏览器,本程序文件已经被删除.
  454. SHChangeNotify(SHCNE_DELETE,SHCNF_PATH,(WCHAR*)dirPath.utf16(),0);
  455. return TRUE;
  456. }
  457. }
  458. return FALSE;
  459. }
  460. #elif defined(Q_OS_MAC)
  461. bool Appconfig::restartSelf()
  462. {
  463. QString bashFilePath = QString("%1/run.sh").arg(Appconfig::AppDataPath_Data);
  464. QFile file(bashFilePath);
  465. if (file.open(QIODevice::WriteOnly))
  466. {
  467. QTextStream fileOut(&file);
  468. fileOut.setCodec("UTF-8"); //unicode UTF-8 ANSI
  469. QString dirPath = QApplication::applicationDirPath();
  470. QString filePath = QString("%1/%2").arg(dirPath).arg(Appconfig::AppExeName);
  471. QString runAppCmd = QString("open -a \""+filePath+"\" \n");
  472. fileOut<<QString("ping -c 4 -t 2 baidu.com \n"); //延时2秒
  473. fileOut<<runAppCmd; //启动程序
  474. file.close();
  475. }
  476. qDebug()<<bashFilePath;
  477. QProcess p(0);
  478. p.start("bash");
  479. p.waitForStarted();
  480. p.write(QString("chmod a+x \""+bashFilePath+"\" \n").toUtf8());
  481. p.write(QString("\""+bashFilePath+"\" &\n").toUtf8()); //后台运行
  482. // p.write(QString("open -a \""+bashFilePath+"\" \n").toUtf8());
  483. p.closeWriteChannel();
  484. p.waitForFinished();
  485. return true;
  486. }
  487. #endif
  488. void AppConfig::mSleep(int mSecond)
  489. {
  490. Sleep(mSecond);
  491. }