├── README.md ├── ico.rc ├── v095_logo_macx.icns ├── v095_logo_win32.ico ├── resource └── images │ └── AutoUpdate │ ├── ico.png │ └── upgrader_background.png ├── CallMainPlus.cpp ├── CallMindPlus.cpp ├── src.qrc ├── Download ├── DownloadBase.cpp ├── DownloadBase_p.h ├── TcpDownload_p.h ├── DownloadBase.h ├── TcpDownload.h └── TcpDownload.cpp ├── Versions ├── VersionCreater_p.h ├── UpdateCompare_p.h ├── UpdateCompare.cpp ├── VersionBase_p.h ├── VersionBase.h ├── UpdateCompare.h ├── VersionCreater.h ├── VersionBase.cpp ├── XmlCompare.h ├── XmlCompare_p.h ├── VersionCreater.cpp └── XmlCompare.cpp ├── CallMindPlus.h ├── main.cpp ├── AutoUpdateClient.pro ├── WidgetMain.h ├── WidgetMain.ui ├── dptr.h └── WidgetMain.cpp /README.md: -------------------------------------------------------------------------------- 1 | AutoUpdateClient 2 | ================ 3 | 4 | 基于Qt的跨平台自动更新框架---客户端 5 | -------------------------------------------------------------------------------- /ico.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "v095_logo_win32.ico" 2 | -------------------------------------------------------------------------------- /v095_logo_macx.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slug404/AutoUpdateClient/HEAD/v095_logo_macx.icns -------------------------------------------------------------------------------- /v095_logo_win32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slug404/AutoUpdateClient/HEAD/v095_logo_win32.ico -------------------------------------------------------------------------------- /resource/images/AutoUpdate/ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slug404/AutoUpdateClient/HEAD/resource/images/AutoUpdate/ico.png -------------------------------------------------------------------------------- /CallMainPlus.cpp: -------------------------------------------------------------------------------- 1 | #include "CallMainPlus.h" 2 | 3 | CallMainPlus::CallMainPlus(QObject *parent) : 4 | QObject(parent) 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /resource/images/AutoUpdate/upgrader_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slug404/AutoUpdateClient/HEAD/resource/images/AutoUpdate/upgrader_background.png -------------------------------------------------------------------------------- /CallMindPlus.cpp: -------------------------------------------------------------------------------- 1 | #include "CallMindPlus.h" 2 | #include 3 | 4 | CallMindPlus::CallMindPlus(const QString &path, QObject *parent) 5 | : QObject(parent) 6 | , path_(path) 7 | { 8 | } 9 | 10 | void CallMindPlus::slotCallMindPlus() 11 | { 12 | QProcess::execute(path_); 13 | } 14 | -------------------------------------------------------------------------------- /src.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | resource/images/AutoUpdate/ico.png 4 | resource/images/AutoUpdate/upgrader_background.png 5 | v095_logo_macx.icns 6 | v095_logo_win32.ico 7 | 8 | 9 | -------------------------------------------------------------------------------- /Download/DownloadBase.cpp: -------------------------------------------------------------------------------- 1 | #include "DownloadBase.h" 2 | #include "DownloadBase_p.h" 3 | 4 | DownloadBase::~DownloadBase() 5 | { 6 | } 7 | 8 | void DownloadBase::start() 9 | { 10 | prepare(); 11 | request(); 12 | } 13 | 14 | DownloadBase::DownloadBase(DownloadBasePrivate &data) 15 | : DPTR_INIT(&data) 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /Versions/VersionCreater_p.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSIONCREATER_P_H 2 | #define VERSIONCREATER_P_H 3 | #include "VersionBase_p.h" 4 | class VersionCreater; 5 | class VersionCreaterPrivate: public VersionBasePrivate 6 | { 7 | DPTR_DECLARE_PUBLIC(VersionCreater) 8 | QDomNode *pFilesNode_; 9 | QDomNode *pIpAddressNode_; 10 | }; 11 | 12 | #endif // VERSIONCREATER_P_H 13 | -------------------------------------------------------------------------------- /CallMindPlus.h: -------------------------------------------------------------------------------- 1 | #ifndef CALLMINDPLUS_H 2 | #define CALLMINDPLUS_H 3 | 4 | #include 5 | 6 | class CallMindPlus : public QObject 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit CallMindPlus(const QString &path, QObject *parent = 0); 11 | 12 | signals: 13 | 14 | public slots: 15 | void slotCallMindPlus(); 16 | 17 | private: 18 | QString path_; 19 | }; 20 | 21 | #endif // CALLMINDPLUS_H 22 | -------------------------------------------------------------------------------- /Versions/UpdateCompare_p.h: -------------------------------------------------------------------------------- 1 | #ifndef UPDATECOMPARE_P_H 2 | #define UPDATECOMPARE_P_H 3 | //#include "UpdateCompare.h" 4 | #include 5 | #include "dptr.h" 6 | 7 | class UpdateCompare; 8 | 9 | class UpdateComparePrivate: public DPtrPrivate 10 | { 11 | DPTR_DECLARE_PUBLIC(UpdateCompare) 12 | 13 | public: 14 | QString clientVersion_; 15 | QString serverVersion_; 16 | }; 17 | 18 | #endif // UPDATECOMPARE_P_H 19 | -------------------------------------------------------------------------------- /Versions/UpdateCompare.cpp: -------------------------------------------------------------------------------- 1 | #include "UpdateCompare.h" 2 | #include "UpdateCompare_p.h" 3 | 4 | UpdateCompare::UpdateCompare(UpdateComparePrivate &data) 5 | : DPTR_INIT(&data) 6 | { 7 | } 8 | 9 | UpdateCompare::~UpdateCompare() 10 | { 11 | } 12 | 13 | void UpdateCompare::addClientVersion(const QString &str) 14 | { 15 | DPTR_D(UpdateCompare); 16 | d.clientVersion_ = str; 17 | } 18 | 19 | void UpdateCompare::addServerVersion(const QString &str) 20 | { 21 | DPTR_D(UpdateCompare); 22 | d.serverVersion_ = str; 23 | } 24 | -------------------------------------------------------------------------------- /Download/DownloadBase_p.h: -------------------------------------------------------------------------------- 1 | #ifndef DOWNLOADBASE_P_H 2 | #define DOWNLOADBASE_P_H 3 | 4 | #include "dptr.h" 5 | 6 | class DownloadBase; 7 | class QString; 8 | class DownloadBasePrivate : public DPtrPrivate 9 | { 10 | DPTR_DECLARE_PUBLIC(DownloadBase) 11 | public: 12 | DownloadBasePrivate() 13 | : requestXml_() 14 | , downloadPath_() 15 | , progress_(0) 16 | { 17 | 18 | } 19 | 20 | QString requestXml_; 21 | QString downloadPath_; 22 | int progress_; 23 | }; 24 | 25 | #endif // DOWNLOADBASE_P_H 26 | -------------------------------------------------------------------------------- /Download/TcpDownload_p.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPDOWNLOAD_P_H 2 | #define TCPDOWNLOAD_P_H 3 | 4 | #include "DownloadBase_p.h" 5 | 6 | class TcpDownload; 7 | class QTcpSocket; 8 | 9 | class TcpDownloadPrivate : public DownloadBasePrivate 10 | { 11 | public: 12 | TcpDownloadPrivate() 13 | : pTcpSocket(NULL) 14 | { 15 | } 16 | 17 | //public data here 18 | QTcpSocket *pTcpSocket; 19 | //其他的到时候再加 20 | 21 | private: 22 | //q-ptr 23 | DPTR_DECLARE_PUBLIC(TcpDownload) 24 | }; 25 | 26 | #endif // TCPDOWNLOAD_P_H 27 | -------------------------------------------------------------------------------- /Versions/VersionBase_p.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSIONBASE_P_H 2 | #define VERSIONBASE_P_H 3 | #include "dptr.h" 4 | #include 5 | #include 6 | class VersionBase; 7 | class QDomNode; 8 | class QString; 9 | class QDomDocument; 10 | 11 | class VersionBasePrivate : public DPtrPrivate 12 | { 13 | DPTR_DECLARE_PUBLIC(VersionBase) 14 | public: 15 | VersionBasePrivate() 16 | : pUpdateNode(NULL) 17 | , pDocument(NULL) 18 | , pMap_nodeName_domNode(NULL) 19 | { 20 | 21 | } 22 | QDomNode *pUpdateNode; 23 | QDomDocument *pDocument; 24 | QMap *pMap_nodeName_domNode; 25 | }; 26 | 27 | #endif // VERSIONBASE_P_H 28 | -------------------------------------------------------------------------------- /Versions/VersionBase.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSIONBASE_H 2 | #define VERSIONBASE_H 3 | 4 | #include 5 | #include "../dptr.h" 6 | 7 | class VersionBasePrivate; 8 | class QDomNode; 9 | 10 | class VersionBase : public QObject 11 | { 12 | Q_OBJECT 13 | DPTR_DECLARE_PRIVATE(VersionBase) 14 | public: 15 | virtual ~VersionBase(); 16 | void start(const QString &str); 17 | bool saveXml(const QString &filePath); 18 | 19 | protected: 20 | explicit VersionBase(QObject *parent = 0); 21 | VersionBase(VersionBasePrivate &data); 22 | virtual void initDomTree() = 0; 23 | virtual void traveDomTree(const QString &str) = 0; 24 | 25 | DPTR_DECLARE(VersionBase) 26 | }; 27 | 28 | #endif // VERSIONBASE_H 29 | -------------------------------------------------------------------------------- /Versions/UpdateCompare.h: -------------------------------------------------------------------------------- 1 | #ifndef UPDATECOMPARE_H 2 | #define UPDATECOMPARE_H 3 | 4 | #include 5 | #include "dptr.h" 6 | 7 | class UpdateComparePrivate; 8 | 9 | class UpdateCompare : public QObject 10 | { 11 | Q_OBJECT 12 | DPTR_DECLARE_PRIVATE(UpdateCompare) 13 | 14 | public: 15 | virtual ~UpdateCompare(); 16 | void addClientVersion(const QString &str); 17 | void addServerVersion(const QString &str); 18 | virtual void compare() = 0; 19 | virtual void star(const QString &path1, const QString &path2) = 0; 20 | 21 | protected: 22 | UpdateCompare(QObject *parent = 0); 23 | explicit UpdateCompare(UpdateComparePrivate &data); 24 | 25 | DPTR_DECLARE(UpdateCompare) 26 | }; 27 | 28 | #endif // UPDATECOMPARE_H 29 | -------------------------------------------------------------------------------- /Download/DownloadBase.h: -------------------------------------------------------------------------------- 1 | #ifndef DOWNLOADBASE_H 2 | #define DOWNLOADBASE_H 3 | 4 | #include 5 | #include "dptr.h" 6 | 7 | class DownloadBasePrivate; 8 | 9 | /** 10 | * @brief The DownloadBase class 下载接口 TODO: HttpDownload 11 | */ 12 | class DownloadBase : public QObject 13 | { 14 | Q_OBJECT 15 | DPTR_DECLARE_PRIVATE(DownloadBase) 16 | public: 17 | virtual ~DownloadBase(); 18 | void start(); 19 | 20 | protected: 21 | DISABLE_COPY(DownloadBase) 22 | explicit DownloadBase(DownloadBasePrivate &data); 23 | virtual void prepare() = 0; 24 | virtual void request() = 0; 25 | virtual void handleReadyRead() = 0; 26 | virtual void clear() = 0; 27 | 28 | protected: 29 | DPTR_DECLARE(DownloadBase) 30 | }; 31 | 32 | #endif // DOWNLOADBASE_H 33 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "WidgetMain.h" 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | 9 | WidgetMain w; 10 | #ifdef Q_OS_MAC 11 | w.setWindowIcon(QIcon("v095_logo_macx.icns")); 12 | #else 13 | w.setWindowIcon(QIcon("./resource/images/icon/v095_logop_4_48x48x8.png")); 14 | QApplication::addLibraryPath("./resource/plugins"); 15 | QApplication::addLibraryPath("./resource/plugins/codecs/"); 16 | QApplication::addLibraryPath("./resource/plugins/imageformats/"); 17 | QApplication::addLibraryPath("./resource/plugins/sqldrivers/"); 18 | QApplication::addLibraryPath("./resource/plugins/platforms/"); 19 | #endif 20 | 21 | w.setWindowTitle("Mind+ Upgrading"); 22 | w.show(); 23 | 24 | return a.exec(); 25 | } 26 | -------------------------------------------------------------------------------- /Versions/VersionCreater.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSIONCREATER_H 2 | #define VERSIONCREATER_H 3 | 4 | #include "VersionBase.h" 5 | 6 | #include 7 | 8 | #include "dptr.h" 9 | 10 | class VersionCreaterPrivate; 11 | class QHostAddress; 12 | 13 | class VersionCreater : public VersionBase 14 | { 15 | Q_OBJECT 16 | DPTR_DECLARE_PRIVATE(VersionCreater) 17 | public: 18 | VersionCreater(); 19 | virtual ~VersionCreater(); 20 | QString getXml(); 21 | 22 | protected: 23 | VersionCreater(VersionCreaterPrivate &data); 24 | virtual void initDomTree(); 25 | virtual void traveDomTree(const QString &str); 26 | QString getLocalIpAddress() const; 27 | QString getHostIp(); 28 | bool isLinkLocalAddress(QHostAddress addr); 29 | bool isLocalIp(QHostAddress addr); 30 | 31 | private: 32 | }; 33 | 34 | #endif // VERSIONCREATER_H 35 | -------------------------------------------------------------------------------- /Versions/VersionBase.cpp: -------------------------------------------------------------------------------- 1 | #include "VersionBase.h" 2 | #include "VersionBase_p.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | VersionBase::VersionBase(VersionBasePrivate &data) 11 | : DPTR_INIT(&data) 12 | { 13 | DPTR_D(VersionBase); 14 | d.pMap_nodeName_domNode = new QMap(); 15 | } 16 | 17 | VersionBase::~VersionBase() 18 | { 19 | } 20 | 21 | void VersionBase::start(const QString &str) 22 | { 23 | initDomTree(); 24 | traveDomTree(str); 25 | } 26 | 27 | bool VersionBase::saveXml(const QString &filePath) 28 | { 29 | QFile file(filePath); 30 | 31 | if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate |QIODevice::Text)) 32 | { 33 | return false; 34 | } 35 | 36 | QTextStream out(&file); 37 | out.setCodec("UTF-8"); 38 | 39 | DPTR_D(VersionBase); 40 | if(NULL == d.pDocument) 41 | { 42 | qDebug() << "pDocument_ is null!"; 43 | return false; 44 | } 45 | d.pDocument->save(out, 4); 46 | 47 | file.close(); 48 | return true; 49 | } 50 | -------------------------------------------------------------------------------- /Versions/XmlCompare.h: -------------------------------------------------------------------------------- 1 | #ifndef XMLCOMPARE_H 2 | #define XMLCOMPARE_H 3 | 4 | #include "UpdateCompare.h" 5 | 6 | class XmlComparePrivate; 7 | class QDomDocument; 8 | class QDomNode; 9 | class QDomText; 10 | class QDomElement; 11 | 12 | struct UpdateFileInformation 13 | { 14 | QString name; 15 | QString path; 16 | }; 17 | 18 | class XmlCompare : public UpdateCompare 19 | { 20 | Q_OBJECT 21 | DPTR_DECLARE_PRIVATE(XmlCompare) 22 | public: 23 | explicit XmlCompare(); 24 | virtual ~XmlCompare(); 25 | void star(const QString &path1, const QString &path2); 26 | bool saveXml(); 27 | QString getDifference(const QString &clientXml, const QString &serverXml); 28 | 29 | QList getUpdateFileList(const QString &clientXml, const QString &serverXml); 30 | 31 | signals: 32 | void signalCloseParent(); 33 | 34 | protected: 35 | explicit XmlCompare(XmlComparePrivate &data); 36 | virtual void compare(); 37 | 38 | private: 39 | bool initVersion(QDomDocument **pDoc, QDomNode **pUpdate, QDomNode **pFiles, const QString &domString); 40 | 41 | bool initClientVersion(); 42 | bool initServerVersion(); 43 | void initUpdateVersion(); 44 | QDomText getNodeValue(QDomNode &node, const QString &name); 45 | void setNodeValue(QDomNode &node, const QString &name, const QString &value); 46 | QDomElement createElement(QDomDocument *pDoc, const QDomNode &node); 47 | }; 48 | 49 | #endif // XMLCOMPARE_H 50 | -------------------------------------------------------------------------------- /Versions/XmlCompare_p.h: -------------------------------------------------------------------------------- 1 | #ifndef XMLCOMPARE_P_H 2 | #define XMLCOMPARE_P_H 3 | 4 | #include "UpdateCompare_p.h" 5 | #include 6 | 7 | class XmlCompare; 8 | class QDomNode; 9 | class QString; 10 | class QDomDocument; 11 | 12 | class XmlComparePrivate : public UpdateComparePrivate 13 | { 14 | DPTR_DECLARE_PUBLIC(XmlCompare) 15 | 16 | public: 17 | explicit XmlComparePrivate() 18 | : pClientUpdateNode_(NULL) 19 | , pClientFilesNode_(NULL) 20 | , pClientDocument_(NULL) 21 | , pClientMap_nodeName_domNode_(NULL) 22 | , pServerUpdateNode_(NULL) 23 | , pServerFilesNode_(NULL) 24 | , pServerDocument_(NULL) 25 | , pServerMap_nodeName_domNode_(NULL) 26 | , pUpdateNode_(NULL) 27 | , pFilesNode_(NULL) 28 | , pDocument_(NULL) 29 | , pIpAddressNode_(NULL) 30 | , pMap_nodeName_domNode_(NULL) 31 | { 32 | } 33 | 34 | QDomNode *pClientUpdateNode_; 35 | QDomNode *pClientFilesNode_; 36 | QDomDocument *pClientDocument_; 37 | QMap *pClientMap_nodeName_domNode_; 38 | 39 | QDomNode *pServerUpdateNode_; 40 | QDomNode *pServerFilesNode_; 41 | QDomDocument *pServerDocument_; 42 | QMap *pServerMap_nodeName_domNode_; 43 | 44 | QDomNode *pUpdateNode_; 45 | QDomNode *pFilesNode_; 46 | QDomDocument *pDocument_; 47 | QDomNode *pIpAddressNode_; 48 | QMap *pMap_nodeName_domNode_; 49 | }; 50 | 51 | #endif // XMLCOMPARE_P_H 52 | -------------------------------------------------------------------------------- /AutoUpdateClient.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2013-02-04T18:25:11 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | QT += xml 9 | QT += network 10 | 11 | CONFIG(release, debug|release):DEFINES += USE_RELEASE 12 | CONFIG(debug, debug|release):DEFINES += USE_DEBUG 13 | #CONFIG(debug, debug|release):QT += testlib 14 | 15 | greaterThan(QT_MAJOR_VERSION, 4){ 16 | QT += widgets 17 | CONFIG += c++11 18 | } 19 | 20 | equals(QT_MAJOR_VERSION, 4){ 21 | QMAKE_CXXFLAGS += -std=c++0x 22 | } 23 | 24 | TARGET = Mind+ 25 | TEMPLATE = app 26 | 27 | SOURCES += main.cpp\ 28 | WidgetMain.cpp\ 29 | Versions/VersionBase.cpp \ 30 | Versions/VersionCreater.cpp \ 31 | Versions/XmlCompare.cpp \ 32 | Versions/UpdateCompare.cpp \ 33 | Download/DownloadBase.cpp \ 34 | Download/TcpDownload.cpp \ 35 | CallMindPlus.cpp 36 | 37 | HEADERS += WidgetMain.h \ 38 | Versions/VersionCreater_p.h \ 39 | Versions/VersionCreater.h \ 40 | Versions/VersionBase_p.h \ 41 | Versions/VersionBase.h \ 42 | dptr.h \ 43 | Versions/XmlCompare.h \ 44 | Versions/XmlCompare_p.h \ 45 | Versions/UpdateCompare.h \ 46 | Versions/UpdateCompare_p.h \ 47 | Download/DownloadBase.h \ 48 | Download/DownloadBase_p.h \ 49 | Download/TcpDownload_p.h \ 50 | Download/TcpDownload.h \ 51 | CallMindPlus.h 52 | 53 | FORMS += WidgetMain.ui 54 | 55 | RESOURCES += \ 56 | src.qrc 57 | 58 | win32{ 59 | MOC_DIR = _moc 60 | OBJECTS_DIR = _obj 61 | RCC_DIR = _rcc 62 | UI_DIR = _ui 63 | UI_HEADERS_DIR = _ui 64 | UI_SOURCES_DIR = _ui 65 | RC_FILE = ico.rc 66 | }else{ 67 | mac{ 68 | ICON = v095_logo_macx.icns 69 | } 70 | MOC_DIR = .moc 71 | OBJECTS_DIR = .obj 72 | RCC_DIR = .rcc 73 | UI_DIR = .ui 74 | UI_HEADERS_DIR = .ui 75 | UI_SOURCES_DIR = .ui 76 | } 77 | -------------------------------------------------------------------------------- /Download/TcpDownload.h: -------------------------------------------------------------------------------- 1 | #ifndef TCPDOWNLOAD_H 2 | #define TCPDOWNLOAD_H 3 | 4 | #include "DownloadBase.h" 5 | #include 6 | 7 | #include "dptr.h" 8 | #include "Versions/XmlCompare.h" 9 | 10 | class TcpDownloadPrivate; 11 | 12 | class TcpDownload : public DownloadBase 13 | { 14 | Q_OBJECT 15 | public: 16 | enum RequestType 17 | { 18 | RequestXml, 19 | RequestData, 20 | RequestExecutable 21 | }; 22 | 23 | TcpDownload(); 24 | virtual void prepare(); 25 | virtual void request(); 26 | virtual void handleReadyRead(); 27 | virtual void clear(); 28 | void close(); 29 | 30 | void setUpdateRequestXml(const QString &str); 31 | void setUpdateFileList(QList list); 32 | QMap getFileNameAndFilePath() { return map_name_file_; } 33 | 34 | signals: 35 | void signalBytesAvailable(); 36 | //从服务端下载更新所需xml结束 37 | void signalServerInfoDone(const QString &str); 38 | void signalDownloadProgress(int progress); 39 | void signalDownloadStart(); 40 | void signalDownloadFinish(const QString &name); 41 | void signalTcpError(const QString &errorString); 42 | 43 | public slots: 44 | void startTest(); 45 | 46 | public slots: 47 | void slotConnected(); 48 | void slotError(QAbstractSocket::SocketError error); 49 | void slotReadyRead(); 50 | 51 | private: 52 | void initData(); 53 | void handleXml(QDataStream &in); 54 | void handleData(QDataStream &in); 55 | void handleExecutable(QDataStream &in); 56 | void getXml(); 57 | void getData(); 58 | void getUpdateFilesData(const QList &list); 59 | void getExecutable(); 60 | 61 | private: 62 | DPTR_DECLARE_PRIVATE(TcpDownload) 63 | qint32 blockSize_; 64 | QMap map_name_file_; 65 | }; 66 | 67 | #endif // TCPDOWNLOAD_H 68 | -------------------------------------------------------------------------------- /WidgetMain.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGETMAIN_H 2 | #define WIDGETMAIN_H 3 | 4 | #include "ui_WidgetMain.h" 5 | #ifdef Q_OS_WIN32 6 | #include 7 | #endif 8 | #include 9 | #include 10 | #include 11 | 12 | class TcpDownload; 13 | 14 | class WidgetMain : public QWidget, private Ui::WidgetMain 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit WidgetMain(QWidget *parent = 0); 20 | 21 | protected: 22 | void changeEvent(QEvent *e); 23 | void paintEvent(QPaintEvent *event); 24 | void mousePressEvent(QMouseEvent *event); 25 | void mouseMoveEvent(QMouseEvent *event); 26 | 27 | private slots: 28 | void slotDownloadFinish(const QString &name); 29 | void slotServerInfoDone(const QString &str); 30 | void iconActivated(QSystemTrayIcon::ActivationReason reason); 31 | 32 | void slotHideWindows(); 33 | void slotTcpError(const QString &errorString); 34 | 35 | void on_pushButton_clicked(); 36 | 37 | private: 38 | void initSetting(); 39 | void initData(); 40 | void showMessage(); 41 | void createActions(); 42 | void createTrayIcon(); 43 | 44 | void moveTempFileToWorkPath(); 45 | void moveTempFileToWorkPath(QMap &map_name_path); 46 | void startMind(const QString &path); 47 | //真应该分成及派生类, Windows一个, Linux一个, Mac一个. 回学校之后再改吧 48 | 49 | void copyFile(const QString &name, const QString &path); 50 | 51 | private: 52 | TcpDownload *pDownload_; 53 | QString strLocalVersionInfo_; 54 | QString strServerVersionInfo_; 55 | QMap map_name_path_; 56 | QPoint offset_; 57 | ///////////////////////////////////////////// 58 | //通知栏 59 | QAction *minimizeAction; 60 | QAction *maximizeAction; 61 | QAction *restoreAction; 62 | QAction *quitAction; 63 | 64 | QSystemTrayIcon *trayIcon; 65 | QMenu *trayIconMenu; 66 | }; 67 | 68 | #endif // WIDGETMAIN_H 69 | -------------------------------------------------------------------------------- /WidgetMain.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | WidgetMain 4 | 5 | 6 | 7 | 0 8 | 0 9 | 414 10 | 388 11 | 12 | 13 | 14 | 15 | 414 16 | 388 17 | 18 | 19 | 20 | WidgetMain 21 | 22 | 23 | QWidget#WidgetMain 24 | { 25 | border-image: url(:/resource/images/AutoUpdate/upgrader_background.png); 26 | } 27 | 28 | 29 | 30 | 31 | 68 32 | 288 33 | 271 34 | 23 35 | 36 | 37 | 38 | color: rgb(255, 255, 255); 39 | 40 | 41 | 24 42 | 43 | 44 | 45 | 46 | 47 | 372 48 | 10 49 | 31 50 | 31 51 | 52 | 53 | 54 | QPushButton 55 | { 56 | font: 75 11pt "Microsoft YaHei UI"; 57 | background-color: rgba(255, 255, 255, 0); 58 | color: rgb(255, 255, 255); 59 | } 60 | QPushButton:hover 61 | { 62 | font: 75 11pt "Microsoft YaHei UI"; 63 | background-color: rgba(255, 255, 255, 0); 64 | color: rgb(234, 128, 91); 65 | } 66 | 67 | 68 | X 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /dptr.h: -------------------------------------------------------------------------------- 1 | #ifndef DPTR_H 2 | #define DPTR_H 3 | 4 | #define DPTR_INIT(p) dptr(p) 5 | //put in protected 6 | #define DPTR_DECLARE(Class) DPtrInterface dptr; 7 | //put in private 8 | #define DPTR_DECLARE_PRIVATE(Class) \ 9 | inline Class##Private& d_func() { return dptr.pri(); } \ 10 | inline const Class##Private& d_func() const { return dptr.pri(); } \ 11 | friend class Class##Private; 12 | 13 | #define DPTR_DECLARE_PUBLIC(Class) \ 14 | inline Class& q_func() { return *static_cast(dptr_ptr()); } \ 15 | inline const Class& q_func() const { return *static_cast(dptr_ptr()); } \ 16 | friend class Class; 17 | 18 | #define DPTR_INIT_PRIVATE(Class) dptr.setPublic(this); 19 | #define DPTR_D(Class) Class##Private& d = dptr.pri() 20 | #define DPTR_P(Class) Class& p = *static_cast(dptr_ptr()) 21 | 22 | //interface 23 | template 24 | class DPtrPrivate 25 | { 26 | public: 27 | virtual ~DPtrPrivate() {} 28 | inline void DPTR_setPublic(PUB* pub) { dptr_p_ptr = pub; } 29 | protected: 30 | inline PUB& dptr_p() { return *dptr_p_ptr; } 31 | inline const PUB& dptr_p() const { return *dptr_p_ptr; } 32 | inline PUB* dptr_ptr() { return dptr_p_ptr; } 33 | inline const PUB* dptr_ptr() const { return dptr_p_ptr; } 34 | private: 35 | PUB* dptr_p_ptr; 36 | }; 37 | 38 | //interface 39 | template 40 | class DPtrInterface 41 | { 42 | friend class DPtrPrivate; 43 | public: 44 | DPtrInterface(PVT* d):pvt(d) {} 45 | DPtrInterface():pvt(new PVT) {} 46 | ~DPtrInterface() { 47 | if (pvt) { 48 | delete pvt; 49 | pvt = 0; 50 | } 51 | } 52 | inline void setPublic(PUB* pub) { pvt->DPTR_setPublic(pub); } 53 | template 54 | inline T& pri() { return *reinterpret_cast(pvt); } 55 | template 56 | inline const T& pri() const { return *reinterpret_cast(pvt); } //static cast requires defination of T 57 | inline PVT& operator()() { return *static_cast(pvt); } 58 | inline const PVT& operator()() const { return *static_cast(pvt); } 59 | inline PVT * operator->() { return static_cast(pvt); } 60 | inline const PVT * operator->() const { return static_cast(pvt); } 61 | private: 62 | DPtrInterface(const DPtrInterface&); 63 | DPtrInterface& operator=(const DPtrInterface&); 64 | DPtrPrivate* pvt; 65 | }; 66 | 67 | //不属于DPTR, 但是又常用的东西, 暂时放这里 68 | 69 | //暂时, 应该加入一个判断, 判断是否支持C++11特性 70 | #define DISABLE_COPY(Class) \ 71 | Class(const Class &); \ 72 | Class &operator = (const Class &); 73 | 74 | #endif // DPTR_H 75 | -------------------------------------------------------------------------------- /Versions/VersionCreater.cpp: -------------------------------------------------------------------------------- 1 | #include "VersionCreater.h" 2 | #include "VersionCreater_p.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | VersionCreater::VersionCreater() 16 | : VersionBase(*new VersionCreaterPrivate) 17 | { 18 | } 19 | 20 | VersionCreater::~VersionCreater() 21 | { 22 | } 23 | 24 | QString VersionCreater::getXml() 25 | { 26 | DPTR_D(VersionCreater); 27 | QString str = d.pDocument->toString(); 28 | return str; 29 | } 30 | 31 | VersionCreater::VersionCreater(VersionCreaterPrivate &data) 32 | : VersionBase(data) 33 | { 34 | } 35 | 36 | void VersionCreater::initDomTree() 37 | { 38 | DPTR_D(VersionCreater); 39 | d.pDocument = new QDomDocument(); 40 | QDomProcessingInstruction instruction = d.pDocument->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""); 41 | d.pDocument->appendChild(instruction); 42 | QDomElement updateElement = d.pDocument->createElement("update"); 43 | d.pDocument->appendChild(updateElement); 44 | 45 | QDomElement fileElement = d.pDocument->createElement("files"); 46 | QDomElement ipAddressElement = d.pDocument->createElement("serverAddress"); 47 | updateElement.appendChild(fileElement); 48 | updateElement.appendChild(ipAddressElement); 49 | 50 | d.pUpdateNode = new QDomNode(d.pDocument->firstChildElement("update")); 51 | d.pFilesNode_ = new QDomNode(d.pUpdateNode->firstChildElement("files")); 52 | d.pIpAddressNode_= new QDomNode(d.pUpdateNode->firstChildElement("serverAddress")); 53 | QDomText ipText = d.pDocument->createTextNode(getHostIp()); 54 | //QDomText ipText = d.pDocument->createTextNode(getLocalIpAddress()); 55 | d.pIpAddressNode_->appendChild(ipText); 56 | //qDebug()<< "ip address: " <nodeName(); 59 | // qDebug() << d.pFilesNode_->nodeName(); 60 | // qDebug() << d.pIpAddressNode_->nodeName(); 61 | } 62 | 63 | void VersionCreater::traveDomTree(const QString &str) 64 | { 65 | //好了明天的工作就是开始遍历数据, 然后生成xml 66 | //先处理files 67 | QDir dir(str); 68 | dir.setFilter(QDir::Files); 69 | if(!dir.entryList().isEmpty()) 70 | { 71 | foreach (QString fileName, dir.entryList()) 72 | { 73 | QString path = str + dir.separator() + fileName; 74 | QFile file(path); 75 | if(!file.open(QFile::ReadOnly)) 76 | { 77 | qDebug() << "can't open file:" << path; 78 | continue; 79 | } 80 | DPTR_D(VersionCreater); 81 | 82 | if("MindUpgrader.exe" == fileName) 83 | { 84 | continue; 85 | } 86 | else if("Thumbs.db" == fileName) 87 | { 88 | continue; 89 | } 90 | 91 | QDomNode filesNode = d.pDocument->createElement("file"); 92 | d.pFilesNode_->appendChild(filesNode); 93 | 94 | // 95 | QDomNode fileNameNode = d.pDocument->createElement("name"); 96 | QDomText fileNameText = d.pDocument->createTextNode(fileName); 97 | fileNameNode.appendChild(fileNameText); 98 | filesNode.appendChild(fileNameNode); 99 | 100 | // 101 | QDomNode filePathNode = d.pDocument->createElement("path"); 102 | QDomText filePathText = d.pDocument->createTextNode(QDir::toNativeSeparators(path)); 103 | filePathNode.appendChild(filePathText); 104 | filesNode.appendChild(filePathNode); 105 | 106 | // 107 | QDomNode fileMD5Node = d.pDocument->createElement("md5"); 108 | QDomText fileMD5Text = d.pDocument->createTextNode(QCryptographicHash::hash(file.readAll(), QCryptographicHash::Md5).toHex()); 109 | fileMD5Node.appendChild(fileMD5Text); 110 | filesNode.appendChild(fileMD5Node); 111 | 112 | // 113 | QDomNode fileLastModifyNode = d.pDocument->createElement("lastModify"); 114 | QDomText fileLastModifyText = d.pDocument->createTextNode(QFileInfo(path).lastModified().toString("yyyy-MM-dd,hh:mm")); 115 | fileLastModifyNode.appendChild(fileLastModifyText); 116 | filesNode.appendChild(fileLastModifyNode); 117 | } 118 | } 119 | 120 | dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); 121 | if(dir.entryList().isEmpty()) 122 | { 123 | return; 124 | } 125 | else 126 | { 127 | //然后继续遍历子目录 128 | dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); 129 | foreach (QString dirName, dir.entryList()) 130 | { 131 | QString path = str + dir.separator() + dirName; 132 | traveDomTree(path); 133 | } 134 | } 135 | } 136 | 137 | QString VersionCreater::getLocalIpAddress() const 138 | { 139 | QString ipAddress = ""; 140 | 141 | #ifdef _WIN32 142 | QHostInfo localHostInfo = QHostInfo::fromName(QHostInfo::localHostName()); 143 | QList ipAddressList = localHostInfo.addresses(); 144 | #else 145 | QList ipAddressList = QNetworkInterface::allAddresses(); 146 | #endif 147 | for(int i = 0; i < ipAddressList.size(); ++i) 148 | { 149 | if(!ipAddressList.at(i).isNull() && 150 | ipAddressList.at(i) != QHostAddress::LocalHost && 151 | ipAddressList.at(i).protocol() == QAbstractSocket::IPv4Protocol) 152 | { 153 | ipAddress = ipAddressList.at(i).toString(); 154 | break; 155 | } 156 | } 157 | 158 | return ipAddress; 159 | } 160 | 161 | QString VersionCreater::getHostIp() 162 | { 163 | qWarning()<<__FUNCTION__; 164 | QHostInfo hostInfo = QHostInfo::fromName(QHostInfo::localHostName()); 165 | QList hostNameLookupAddressList = hostInfo.addresses(); 166 | QList interfaceAddressList = QNetworkInterface::allAddresses(); 167 | qDebug()<<__FUNCTION__<<"hostName lookup addresses:"<= rangeMin && hostIpv4Addr <= rangeMax) 203 | { 204 | return true; 205 | } 206 | else 207 | { 208 | return false; 209 | } 210 | } 211 | 212 | /*! 213 | * \brief 判断是否是私有地址 214 | * \param addr 地址 215 | * \return bool 216 | */ 217 | bool VersionCreater::isLocalIp(QHostAddress addr) 218 | { 219 | quint32 hostIpv4Addr = addr.toIPv4Address(); 220 | //A类地址私有地址段 221 | quint32 range1Min = QHostAddress("10.0.0.0").toIPv4Address(); 222 | quint32 range1Max = QHostAddress("10.255.255.255").toIPv4Address(); 223 | //B类地址私有地址段 224 | quint32 range3Min = QHostAddress("172.16.0.0").toIPv4Address(); 225 | quint32 range3Max = QHostAddress("172.31.255.255").toIPv4Address(); 226 | //C类地址私有地址段 227 | quint32 range2Min = QHostAddress("192.168.0.0").toIPv4Address(); 228 | quint32 range2Max = QHostAddress("192.168.255.255").toIPv4Address(); 229 | 230 | if((hostIpv4Addr >= range1Min && hostIpv4Addr <= range1Max) 231 | || (hostIpv4Addr >= range2Min && hostIpv4Addr <= range2Max) 232 | || (hostIpv4Addr >= range3Min && hostIpv4Addr <= range3Max)) 233 | { 234 | return true; 235 | } 236 | else 237 | { 238 | return false; 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /Versions/XmlCompare.cpp: -------------------------------------------------------------------------------- 1 | #include "XmlCompare.h" 2 | #include "XmlCompare_p.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | XmlCompare::XmlCompare() 9 | : UpdateCompare(*new XmlComparePrivate) 10 | { 11 | } 12 | 13 | XmlCompare::XmlCompare(XmlComparePrivate &data) 14 | : UpdateCompare(data) 15 | { 16 | } 17 | 18 | XmlCompare::~XmlCompare() 19 | { 20 | } 21 | 22 | bool XmlCompare::saveXml() 23 | { 24 | DPTR_D(XmlCompare); 25 | if(NULL == d.pDocument_) 26 | { 27 | qDebug() << "d.pDocument_ is null"; 28 | return false; 29 | } 30 | QFile file("result.xml"); 31 | if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) 32 | { 33 | return false; 34 | } 35 | 36 | QTextStream out(&file); 37 | out.setCodec("UTF-8"); 38 | 39 | d.pDocument_->save(out, 4); 40 | file.close(); 41 | 42 | return true; 43 | } 44 | 45 | QString XmlCompare::getDifference(const QString &clientXml, const QString &serverXml) 46 | { 47 | //初始化数据 48 | DPTR_D(XmlCompare); 49 | d.clientVersion_ = clientXml; 50 | d.serverVersion_ = serverXml; 51 | 52 | if(!initClientVersion()) 53 | { 54 | qDebug() << "initClientVersion error"; 55 | } 56 | if(!initServerVersion()) 57 | { 58 | qDebug() << "initServerVersion error"; 59 | } 60 | 61 | initUpdateVersion(); 62 | 63 | //开始比较 64 | compare(); 65 | 66 | //保存结果 67 | QString result = d.pDocument_->toString(); 68 | return result; 69 | } 70 | 71 | QList XmlCompare::getUpdateFileList(const QString &clientXml, const QString &serverXml) 72 | { 73 | QString domString = getDifference(clientXml, serverXml); 74 | 75 | ////////////////////////// 76 | ///发布时删掉 77 | // { 78 | // QFile fileTmp("request.xml"); 79 | // if(!fileTmp.open(QFile::WriteOnly)) 80 | // { 81 | // qDebug() << "request.xml can't open!"; 82 | // } 83 | // fileTmp.write(domString.toUtf8()); 84 | // } 85 | ////////////////////////// 86 | 87 | ///////////////////////////////////////////////////////////////// 88 | //处理Xml中的有效数据 89 | QDomDocument *pDoc = new QDomDocument(); 90 | QString errorStr; 91 | int errorLine; 92 | int errorCol; 93 | 94 | if(!pDoc->setContent(domString, true, &errorStr, &errorLine, &errorCol)) 95 | { 96 | qDebug()<<"error! "< (); 98 | } 99 | 100 | QDomNode *pUpdate = new QDomNode(pDoc->firstChildElement("update")); 101 | QDomNode *pFiles = new QDomNode(pUpdate->firstChildElement("files")); 102 | 103 | QDomNodeList nodeList = pFiles->childNodes(); 104 | int sizeUpdateFiles = nodeList.size(); 105 | qDebug() << "update files is : " << sizeUpdateFiles; 106 | if(0 == sizeUpdateFiles) 107 | { 108 | //emit signalCloseParent(); 109 | } 110 | 111 | QList listFileInfo; 112 | 113 | for(int i = 0; i != nodeList.size(); ++i) 114 | { 115 | QString name = nodeList.at(i).firstChildElement("name").firstChild().toText().nodeValue(); 116 | QString path = nodeList.at(i).firstChildElement("path").firstChild().toText().nodeValue(); 117 | QString md5 = nodeList.at(i).firstChildElement("md5").firstChild().toText().nodeValue(); 118 | // qDebug() << "name: " << name; 119 | // qDebug() << "path : " << path; 120 | // qDebug() << "md5 : " << md5; 121 | 122 | UpdateFileInformation fileInfor; 123 | fileInfor.name = name; 124 | fileInfor.path = path; 125 | 126 | listFileInfo.append(fileInfor); 127 | } 128 | ////////////////////////////////////////////////////////////////////// 129 | 130 | return listFileInfo; 131 | } 132 | 133 | void XmlCompare::compare() 134 | { 135 | DPTR_D(XmlCompare); 136 | 137 | QDomNodeList serverNodes = d.pServerFilesNode_->childNodes(); 138 | QDomNodeList clientNodes = d.pClientFilesNode_->childNodes(); 139 | 140 | for(int i = 0; i != serverNodes.size(); ++i) 141 | { 142 | bool bInClient = false; 143 | QDomNode s = serverNodes.at(i); 144 | for(int j = 0; j != clientNodes.size(); ++j) 145 | { 146 | QDomNode c = clientNodes.at(j); 147 | if(getNodeValue(s, tr("name")).nodeValue() == getNodeValue(c, tr("name")).nodeValue()) 148 | { 149 | //比较MD5 和 lastModify 150 | if(getNodeValue(s, tr("md5")).nodeValue() == getNodeValue(c, tr("md5")).nodeValue()) 151 | { 152 | bInClient = true; 153 | } 154 | } 155 | } 156 | 157 | //这里是更新部分 158 | if(!bInClient) 159 | { 160 | QDomElement updateNode = this->createElement(d.pDocument_, s); 161 | d.pFilesNode_->appendChild(updateNode); 162 | } 163 | } 164 | } 165 | 166 | void XmlCompare::star(const QString &path1, const QString &path2) 167 | { 168 | QFile file1(path1); 169 | if(!file1.open(QFile::ReadOnly)) 170 | { 171 | qDebug() << "can't open " << path1; 172 | return; 173 | } 174 | 175 | QFile file2(path2); 176 | if(!file2.open(QFile::ReadOnly)) 177 | { 178 | qDebug() << "can't open " << path2; 179 | return; 180 | } 181 | //初始化数据 182 | DPTR_D(XmlCompare); 183 | d.clientVersion_ = QString(file1.readAll()); 184 | d.serverVersion_ = QString(file2.readAll()); 185 | 186 | file1.close(); 187 | file2.close(); 188 | 189 | // qDebug() << d.clientVersion_; 190 | // qDebug() << d.serverVersion_; 191 | 192 | if(!initClientVersion()) 193 | { 194 | qDebug() << "initClientVersion error"; 195 | } 196 | if(!initServerVersion()) 197 | { 198 | qDebug() << "initServerVersion error"; 199 | } 200 | 201 | initUpdateVersion(); 202 | 203 | //开始比较 204 | compare(); 205 | 206 | //保存结果 207 | saveXml(); 208 | } 209 | 210 | bool XmlCompare::initClientVersion() 211 | { 212 | DPTR_D(XmlCompare); 213 | return initVersion(&d.pClientDocument_, &d.pClientUpdateNode_, &d.pClientFilesNode_, d.clientVersion_); 214 | } 215 | 216 | bool XmlCompare::initServerVersion() 217 | { 218 | DPTR_D(XmlCompare); 219 | return initVersion(&d.pServerDocument_, &d.pServerUpdateNode_, &d.pServerFilesNode_, d.serverVersion_); 220 | } 221 | 222 | bool XmlCompare::initVersion(QDomDocument **pDoc, QDomNode **pUpdate, QDomNode **pFiles, const QString &domString) 223 | { 224 | (*pDoc) = new QDomDocument(); 225 | //加载Xml的string描述到Dom 226 | QString errorStr; 227 | int errorLine; 228 | int errorCol; 229 | 230 | if(!(*pDoc)->setContent(domString, true, &errorStr, &errorLine, &errorCol)) 231 | { 232 | qDebug()<<"error! "<firstChildElement("update")); 237 | *pFiles = new QDomNode((*pUpdate)->firstChildElement("files")); 238 | 239 | return true; 240 | } 241 | 242 | void XmlCompare::initUpdateVersion() 243 | { 244 | DPTR_D(XmlCompare); 245 | d.pDocument_ = new QDomDocument(); 246 | QDomProcessingInstruction instruction = d.pDocument_->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""); 247 | d.pDocument_->appendChild(instruction); 248 | QDomElement updateElement = d.pDocument_->createElement("update"); 249 | d.pDocument_->appendChild(updateElement); 250 | 251 | QDomElement fileElement = d.pDocument_->createElement("files"); 252 | QDomElement ipAddressElement = d.pDocument_->createElement("serverAddress"); 253 | updateElement.appendChild(fileElement); 254 | updateElement.appendChild(ipAddressElement); 255 | 256 | d.pUpdateNode_ = new QDomNode(d.pDocument_->firstChildElement("update")); 257 | d.pFilesNode_ = new QDomNode(d.pUpdateNode_->firstChildElement("files")); 258 | d.pIpAddressNode_= new QDomNode(d.pUpdateNode_->firstChildElement("serverAddress")); 259 | QDomText ipText = d.pDocument_->createTextNode(""); 260 | d.pIpAddressNode_->appendChild(ipText); 261 | 262 | // qDebug() << d.pUpdateNode_->nodeName(); 263 | // qDebug() << d.pFilesNode_->nodeName(); 264 | // qDebug() << d.pIpAddressNode_->nodeName(); 265 | } 266 | 267 | QDomText XmlCompare::getNodeValue(QDomNode &node, const QString &name) 268 | { 269 | return node.firstChildElement(name).firstChild().toText(); 270 | } 271 | 272 | void XmlCompare::setNodeValue(QDomNode &node, const QString &name, const QString &value) 273 | { 274 | node.firstChildElement(name).toText().setNodeValue(value); 275 | } 276 | 277 | QDomElement XmlCompare::createElement(QDomDocument *pDoc, const QDomNode &node) 278 | { 279 | QDomElement element = pDoc->createElement(node.nodeName()); 280 | QDomNodeList childList = node.childNodes(); 281 | for(int i = 0; i != childList.size(); ++i) 282 | { 283 | QDomElement tmpNode = pDoc->createElement(childList.at(i).nodeName()); 284 | QString value = childList.at(i).firstChild().toText().nodeValue(); 285 | //qDebug() << value; 286 | QDomText textNode = pDoc->createTextNode(value); 287 | tmpNode.appendChild(textNode); 288 | element.appendChild(tmpNode); 289 | } 290 | 291 | return element; 292 | } 293 | 294 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /Download/TcpDownload.cpp: -------------------------------------------------------------------------------- 1 | #include "TcpDownload.h" 2 | #include "TcpDownload_p.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | TcpDownload::TcpDownload() 11 | : DownloadBase(*new TcpDownloadPrivate) 12 | , blockSize_(0) 13 | { 14 | initData(); 15 | } 16 | 17 | void TcpDownload::initData() 18 | { 19 | DPTR_D(TcpDownload); 20 | d.pTcpSocket = new QTcpSocket(this); 21 | connect(d.pTcpSocket, SIGNAL(connected()), this, SLOT(slotConnected())); 22 | connect(d.pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotError(QAbstractSocket::SocketError))); 23 | connect(d.pTcpSocket, SIGNAL(readyRead()), this, SLOT(slotReadyRead()), Qt::QueuedConnection); 24 | } 25 | 26 | void TcpDownload::handleXml(QDataStream &in) 27 | { 28 | QString buffer; 29 | in >> buffer; 30 | //qDebug() << (buffer); 31 | 32 | // QFile file("requestXml.xml"); 33 | // if(!file.open(QFile::WriteOnly)) 34 | // { 35 | // qDebug() << "requestXml.xml open fail!"; 36 | // return; 37 | // } 38 | // file.write(buffer.toUtf8()); 39 | emit signalServerInfoDone(buffer); 40 | } 41 | 42 | /*! 43 | * \brief 请求服务端版本信息 44 | */ 45 | void TcpDownload::getXml() 46 | { 47 | //在这里发送响应 48 | DPTR_D(TcpDownload); 49 | QByteArray bytes; 50 | QDataStream out(&bytes, QIODevice::WriteOnly); 51 | out.setVersion(QDataStream::Qt_4_8); 52 | //为了防止不同平台数据大小不一致, 全部指定用qint32和qint64 53 | //报文大小->socket descriptor-> request type -> data 54 | out << (qint32)0; //占位 55 | out << (qint32)RequestXml; 56 | 57 | out.device()->seek(0); 58 | out << (qint32)(bytes.size() - (qint32)sizeof(qint32)); 59 | d.pTcpSocket->write(bytes.data(), bytes.size()); 60 | } 61 | 62 | /*! 63 | * \brief 请求更新数据 64 | */ 65 | void TcpDownload::getData() 66 | { 67 | //在这里发送响应 68 | DPTR_D(TcpDownload); 69 | QByteArray bytes; 70 | QDataStream out(&bytes, QIODevice::WriteOnly); 71 | out.setVersion(QDataStream::Qt_4_8); 72 | //为了防止不同平台数据大小不一致, 全部指定用qint32和qint64 73 | //报文大小->socket descriptor-> request type -> data 74 | out << (qint32)0; //占位 75 | out << (qint32)RequestData; 76 | if(d.requestXml_.isEmpty()) 77 | { 78 | qDebug() << ("requestXml_ is empty"); 79 | } 80 | 81 | out.device()->seek(0); 82 | out << (qint32)(bytes.size() - (qint32)sizeof(qint32)); 83 | d.pTcpSocket->write(bytes.data(), bytes.size()); 84 | } 85 | 86 | /*! 87 | * \brief 向服务端发送请求需要更新的文件列表(为了代替之前的getData, 把计算量尽量做在客户端) 88 | * \param list 要更新的文件列表, 其中的每一个元素包含一个文件名还有对应的路径 89 | */ 90 | void TcpDownload::getUpdateFilesData(const QList &list) 91 | { 92 | qDebug() << "start to request update file list"; 93 | QByteArray bytes; 94 | QDataStream out(&bytes, QIODevice::WriteOnly); 95 | out.setVersion(QDataStream::Qt_4_8); 96 | //为了防止不同平台数据大小不一致, 全部指定用qint32和qint64 97 | //报文大小->socket descriptor-> request type -> data 98 | out << (qint32)0; //占位 99 | out << (qint32)RequestData; 100 | out << (qint32)list.size(); //通知服务端有多少个要更新的文件 101 | 102 | qDebug() << "update files number : " << list.size(); 103 | 104 | for(int i = 0; i != list.size(); ++i) 105 | { 106 | UpdateFileInformation tmp = list.at(i); 107 | out << tmp.name; 108 | qDebug() << tmp.name; 109 | } 110 | 111 | out.device()->seek(0); 112 | out << (qint32)(bytes.size() - (qint32)sizeof(qint32)); 113 | 114 | qDebug() << "bytes size is" << bytes.size(); 115 | DPTR_D(TcpDownload); 116 | d.pTcpSocket->write(bytes.data(), bytes.size()); 117 | } 118 | 119 | /*! 120 | * \brief 处理更新数据 121 | * \param in 122 | */ 123 | void TcpDownload::handleData(QDataStream &in) 124 | { 125 | //这里做后续的处理 126 | int num; 127 | in >> num; 128 | QDir tmpDir("./"); 129 | qDebug()<<"need to download file : " << num; 130 | if(!tmpDir.exists("DownloadTemp")) 131 | { 132 | tmpDir.mkdir("DownloadTemp"); 133 | } 134 | 135 | while (num--) 136 | { 137 | QString name; 138 | QByteArray bytes; 139 | in >> name >> bytes; 140 | 141 | QString filePath = tr("./DownloadTemp/%1").arg(name); 142 | if(QFile::exists(filePath)) 143 | { 144 | qDebug() << "delete alrealy exist file"; 145 | //QFile::remove(filePath); 146 | } 147 | 148 | QFile file(filePath); 149 | if(!file.open(QFile::WriteOnly)) 150 | { 151 | continue; 152 | } 153 | 154 | file.write(bytes); 155 | qDebug() << "download file:" << name; 156 | } 157 | 158 | QByteArray serialize; 159 | in >> serialize; 160 | QDataStream serializeIn(&serialize, QIODevice::ReadOnly); 161 | QMap map_name_file; 162 | serializeIn >> map_name_file; 163 | map_name_file_ = map_name_file; 164 | 165 | DPTR_D(TcpDownload); 166 | d.pTcpSocket->close(); 167 | emit signalDownloadFinish(""); 168 | } 169 | 170 | /*! 171 | * \brief 请求exe文件 172 | */ 173 | void TcpDownload::getExecutable() 174 | { 175 | //在这里发送响应 176 | DPTR_D(TcpDownload); 177 | QByteArray bytes; 178 | QDataStream out(&bytes, QIODevice::WriteOnly); 179 | out.setVersion(QDataStream::Qt_4_8); 180 | 181 | out << (qint32)0; //占位 182 | out << (qint32)RequestExecutable; 183 | 184 | out.device()->seek(0); 185 | out << (qint32)(bytes.size() - (qint32)sizeof(qint32)); 186 | d.pTcpSocket->write(bytes.data(), bytes.size()); 187 | } 188 | 189 | void TcpDownload::handleExecutable(QDataStream &in) 190 | { 191 | QString name; 192 | in >> name; 193 | qDebug() << (QString("name: %1").arg(name)); 194 | QByteArray bytes; 195 | in >> bytes; 196 | qDebug() << (tr("size of bytes :") + QString::number(bytes.size())); 197 | QByteArray md5; 198 | in >> md5; 199 | qDebug() << (QString(md5)); 200 | QByteArray tmp = QCryptographicHash::hash(bytes, QCryptographicHash::Md5).toHex(); 201 | qDebug() << (QString(tmp)); 202 | if(md5 != tmp) 203 | { 204 | qDebug() << ("data error!"); 205 | } 206 | 207 | QDir tmpDir("./"); 208 | if(!tmpDir.exists("DownloadTemp")) 209 | { 210 | tmpDir.mkdir("DownloadTemp"); 211 | } 212 | QFile file(tr("./DownloadTemp/%1").arg(name)); 213 | if(!file.open(QFile::WriteOnly)) 214 | { 215 | qDebug() << (tr("can't open file ") + name); 216 | } 217 | file.write(bytes); 218 | file.close(); 219 | 220 | emit signalDownloadFinish(name); 221 | } 222 | 223 | void TcpDownload::prepare() 224 | { 225 | DPTR_D(TcpDownload); 226 | emit signalDownloadStart(); 227 | qDebug() << "connect to server"; 228 | 229 | #ifdef Q_OS_WIN32 230 | d.pTcpSocket->connectToHost("mindplus.cc", 8769); 231 | #elif defined(Q_OS_LINUX) 232 | d.pTcpSocket->connectToHost("mindplus.cc", 8770); 233 | #elif defined(Q_OS_MAC) 234 | d.pTcpSocket->connectToHost("mindplus.cc", 8771); 235 | #endif 236 | } 237 | 238 | void TcpDownload::request() 239 | { 240 | getXml(); 241 | } 242 | 243 | void TcpDownload::handleReadyRead() 244 | { 245 | qDebug() << "start handle tcp datagram"; 246 | qDebug() << ("logger : tart handle tcp datagram"); 247 | DPTR_D(TcpDownload); 248 | QDataStream in(d.pTcpSocket); 249 | in.setVersion(QDataStream::Qt_4_8); 250 | 251 | if(0 == blockSize_) 252 | { 253 | if(d.pTcpSocket->bytesAvailable() < (qint32)sizeof(qint32)) 254 | { 255 | return; 256 | } 257 | in >> blockSize_; 258 | } 259 | 260 | qint32 currentSize = d.pTcpSocket->bytesAvailable(); 261 | qDebug() << "blockSize_:" << blockSize_ << "currentSize:" << currentSize; 262 | emit signalDownloadProgress((currentSize- (qint32)sizeof(qint32))*100 / blockSize_); 263 | 264 | if(currentSize < blockSize_) 265 | { 266 | return; 267 | } 268 | 269 | int type; 270 | in >> type; 271 | emit signalDownloadProgress(100); 272 | switch (type) 273 | { 274 | case RequestXml: 275 | { 276 | handleXml(in); 277 | break; 278 | } 279 | case RequestData: 280 | { 281 | handleData(in); 282 | break; 283 | } 284 | case RequestExecutable: 285 | { 286 | handleExecutable(in); 287 | break; 288 | } 289 | default: 290 | { 291 | qDebug() << "error data type"; 292 | break; 293 | } 294 | } 295 | 296 | blockSize_ = 0; 297 | } 298 | 299 | void TcpDownload::clear() 300 | { 301 | DPTR_D(TcpDownload); 302 | d.pTcpSocket->close(); 303 | } 304 | /*! 305 | * \brief 关闭Tcp连接 306 | */ 307 | void TcpDownload::close() 308 | { 309 | DPTR_D(TcpDownload); 310 | if(d.pTcpSocket) 311 | { 312 | d.pTcpSocket->close(); 313 | } 314 | } 315 | 316 | /*! 317 | * \brief 设置更新文件的请求列表, 然后从服务端请求文件 318 | * \param dom树的string描述 319 | */ 320 | void TcpDownload::setUpdateRequestXml(const QString &str) 321 | { 322 | DPTR_D(TcpDownload); 323 | d.requestXml_ = str; 324 | 325 | //发送更新请求, 让服务端返回更新数据 326 | getData(); 327 | } 328 | 329 | void TcpDownload::setUpdateFileList(QList list) 330 | { 331 | getUpdateFilesData(list); 332 | } 333 | 334 | void TcpDownload::slotConnected() 335 | { 336 | qDebug() << "connected !!"; 337 | request(); 338 | } 339 | 340 | void TcpDownload::slotError(QAbstractSocket::SocketError error) 341 | { 342 | Q_UNUSED(error); 343 | qDebug() << "tcp socket error!!"; 344 | DPTR_D(TcpDownload); 345 | qDebug() << d.pTcpSocket->errorString(); 346 | emit signalTcpError(d.pTcpSocket->errorString()); 347 | } 348 | 349 | void TcpDownload::slotReadyRead() 350 | { 351 | handleReadyRead(); 352 | } 353 | 354 | void TcpDownload::startTest() 355 | { 356 | prepare(); 357 | } 358 | -------------------------------------------------------------------------------- /WidgetMain.cpp: -------------------------------------------------------------------------------- 1 | #include "WidgetMain.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "Versions/UpdateCompare.h" 21 | #include "Versions/XmlCompare.h" 22 | #include "Versions/VersionCreater.h" 23 | #include "Download/TcpDownload.h" 24 | #include "CallMindPlus.h" 25 | 26 | WidgetMain::WidgetMain(QWidget *parent) 27 | : QWidget(parent) 28 | , strLocalVersionInfo_("") 29 | , strServerVersionInfo_("") 30 | { 31 | setupUi(this); 32 | initSetting(); 33 | initData(); 34 | 35 | QTimer::singleShot(1, this, SLOT(slotHideWindows())); 36 | } 37 | 38 | void WidgetMain::changeEvent(QEvent *e) 39 | { 40 | QWidget::changeEvent(e); 41 | switch (e->type()) 42 | { 43 | case QEvent::LanguageChange: 44 | retranslateUi(this); 45 | break; 46 | default: 47 | break; 48 | } 49 | } 50 | 51 | void WidgetMain::paintEvent(QPaintEvent *event) 52 | { 53 | Q_UNUSED(event); 54 | QStyleOption opt; 55 | opt.init(this); 56 | QPainter p(this); 57 | style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); 58 | } 59 | 60 | void WidgetMain::mousePressEvent(QMouseEvent *event) 61 | { 62 | if (event->button() == Qt::LeftButton) 63 | { 64 | QWidget *pParent_ = static_cast(this->parent()); 65 | if(NULL == pParent_) 66 | { 67 | return; 68 | } 69 | offset_ = event->globalPos() - pParent_->frameGeometry().topLeft(); 70 | } 71 | } 72 | 73 | void WidgetMain::mouseMoveEvent(QMouseEvent *event) 74 | { 75 | if (!(event->buttons() & Qt::LeftButton)) 76 | { 77 | return; 78 | } 79 | if ((event->pos() - offset_).manhattanLength() 80 | < QApplication::startDragDistance()) 81 | { 82 | return; 83 | } 84 | } 85 | 86 | void WidgetMain::slotDownloadFinish(const QString &name) 87 | { 88 | //下载完了做后续处理 89 | map_name_path_ = pDownload_->getFileNameAndFilePath(); 90 | { 91 | //保存文件路径信息, 下次更新的时候需要 92 | QByteArray bytes; 93 | QDataStream out(&bytes, QIODevice::WriteOnly); 94 | out << map_name_path_; 95 | QFile file("./DownloadTemp/filePath.dat"); 96 | if(!file.open(QFile::WriteOnly)) 97 | { 98 | qDebug() << "open file fail : " << "./DownloadTemp/filePath.dat"; 99 | } 100 | file.write(bytes); 101 | } 102 | qDebug() << "update data download finish"; 103 | 104 | pDownload_->close(); 105 | 106 | QSettings setting("./resource/setting.ini", QSettings::IniFormat); 107 | setting.setValue("Normal/update", true); 108 | this->close(); 109 | } 110 | 111 | void WidgetMain::slotServerInfoDone(const QString &str) 112 | { 113 | strServerVersionInfo_ = str; 114 | qDebug() << "start scan local files"; 115 | ///////////////////////////////////////////////// 116 | /// \brief 发布时注释 117 | // //// 118 | // { 119 | // QFile file("server.xml"); 120 | // if(!file.open(QFile::WriteOnly)) 121 | // { 122 | // qDebug() << "server.xml can't open! "; 123 | // } 124 | // file.write(strServerVersionInfo_.toUtf8()); 125 | // file.waitForBytesWritten(1000); 126 | // file.close(); 127 | // } 128 | ///////////////////////////////////////////////////// 129 | 130 | XmlCompare compare; 131 | QList listFileInfo = compare.getUpdateFileList(strLocalVersionInfo_, strServerVersionInfo_); 132 | 133 | qDebug() << "listFileInfo size is ::::::::::::::::" << listFileInfo.size(); 134 | if(listFileInfo.isEmpty()) 135 | { 136 | qDebug() << "listFileInfo is empty process will be close"; 137 | this->close(); 138 | } 139 | else 140 | { 141 | pDownload_->setUpdateFileList(listFileInfo); 142 | } 143 | } 144 | 145 | void WidgetMain::iconActivated(QSystemTrayIcon::ActivationReason reason) 146 | { 147 | switch (reason) 148 | { 149 | case QSystemTrayIcon::Trigger: 150 | case QSystemTrayIcon::DoubleClick: 151 | case QSystemTrayIcon::MiddleClick: 152 | this->showNormal(); 153 | break; 154 | default: 155 | ; 156 | } 157 | } 158 | 159 | void WidgetMain::slotHideWindows() 160 | { 161 | hide(); 162 | } 163 | 164 | void WidgetMain::slotTcpError(const QString &errorString) 165 | { 166 | QMessageBox::warning(this, tr("warning"), errorString); 167 | this->close(); 168 | } 169 | 170 | void WidgetMain::initSetting() 171 | { 172 | setWindowFlags(Qt::FramelessWindowHint); 173 | setAttribute(Qt::WA_TranslucentBackground); 174 | } 175 | 176 | void WidgetMain::copyFile(const QString &name, const QString &path) 177 | { 178 | qDebug() << "handle :" << tr("./DownloadTemp") + "/" + name; 179 | QFile file(tr("./DownloadTemp") + "/" + name); 180 | if(!file.open(QFile::ReadOnly)) 181 | { 182 | qDebug() << "open src file fail"; 183 | return; 184 | } 185 | 186 | QByteArray bytes = file.readAll(); 187 | file.close(); 188 | 189 | if(QFile::exists(tr("./DownloadTemp") + "/" + name)) 190 | { 191 | qDebug() << "if exite it will be delete"; 192 | if(!QFile::remove(tr("./DownloadTemp") + "/" + name)) 193 | { 194 | qDebug() << "delete fail: " << name; 195 | } 196 | } 197 | 198 | //////////////////////////////// 199 | //在这里要确保path可用 200 | { 201 | QDir pathTest("./"); 202 | QString oldPath = pathTest.currentPath(); 203 | 204 | pathTest.setPath(path); 205 | if(!pathTest.exists()) 206 | { 207 | qDebug() << "not exists the path, and it will try to cerate it:" << path; 208 | if(!pathTest.mkpath(path)) 209 | { 210 | qDebug() << "create path fail!!!!"; 211 | } 212 | } 213 | pathTest.setPath(oldPath); 214 | } 215 | //////////////////////////////// 216 | 217 | QFile desFile(path + "/" + name); 218 | if(!desFile.open(QFile::WriteOnly)) 219 | { 220 | qDebug() << "open des file fail"; 221 | return; 222 | } 223 | 224 | desFile.write(bytes); 225 | desFile.waitForBytesWritten(10); 226 | desFile.close(); 227 | } 228 | 229 | void WidgetMain::initData() 230 | { 231 | QSettings setting("./resource/setting.ini", QSettings::IniFormat); 232 | bool bUpdate = setting.value("Normal/update").toBool(); 233 | if(bUpdate) 234 | { 235 | //更新文件 236 | qDebug() << "start to copy update file"; 237 | //在这之前需要文件放在哪的信息 238 | QMap map_file_path; 239 | { 240 | QFile file("./DownloadTemp/filePath.dat"); 241 | if(!file.open(QFile::ReadOnly)) 242 | { 243 | qDebug() << "open filePath.dat file"; 244 | qDebug() << file.errorString(); 245 | } 246 | QByteArray bytes = file.readAll(); 247 | QDataStream in(&bytes, QIODevice::ReadOnly); 248 | 249 | in >> map_file_path; 250 | if(map_file_path.isEmpty()) 251 | { 252 | qDebug() << "load filePath.dat error"; 253 | } 254 | 255 | } 256 | moveTempFileToWorkPath(map_file_path); 257 | setting.setValue("Normal/update", false); 258 | } 259 | else 260 | { 261 | qDebug() << "don't need to update file, and start Mind+"; 262 | } 263 | #ifdef Q_OS_WIN32 264 | startMind("./mp.exe"); 265 | #elif defined(Q_OS_LINUX) 266 | startMind("./mp"); 267 | #elif defined(Q_OS_MAC) 268 | QProcess::execute("chmod +x ./mp.app/Contents/MacOS/mp"); 269 | startMind("./mp.app"); 270 | #endif 271 | //检查本地版本以及服务器版本. 272 | 273 | progressBar->setMinimum(0); 274 | progressBar->setMaximum(100); 275 | progressBar->setValue(0); 276 | 277 | //////////////////////////////////////////////////////////////////////////// 278 | //清理TempDownLoad中的垃圾文件 279 | QDir dirDelete("./DownloadTemp"); 280 | dirDelete.setFilter(QDir::Files); 281 | foreach (const QString str, dirDelete.entryList()) 282 | { 283 | if(QFile::remove(tr("./DownloadTemp/") + str)) 284 | { 285 | qDebug() << "./DownloadTemp/" << str << " fail!"; 286 | } 287 | } 288 | ///////////////////////////////////////////////////////////////////////////// 289 | //本地文件的计算 290 | QDir dirtmp("./"); 291 | qDebug() << "get local files version information"; 292 | VersionCreater versionCreater; 293 | versionCreater.start(dirtmp.currentPath()); 294 | strLocalVersionInfo_ = versionCreater.getXml(); 295 | //qDebug() << strLocalVersionInfo_; 296 | 297 | // { 298 | // QFile fileTemp("./client.xml"); 299 | // if(!fileTemp.open(QFile::WriteOnly)) 300 | // { 301 | // //qdebug() << "open fail 1234"; 302 | // } 303 | 304 | // fileTemp.write(strLocalVersionInfo_.toAscii()); 305 | // fileTemp.close(); 306 | // } 307 | //qDebug() << "strLocalVersionInfo_ done"; 308 | //map_name_path_ = versionCreater.getFilePath(); 309 | ///////////////////////////////////////////////////////////////////////////// 310 | 311 | pDownload_ = new TcpDownload(); 312 | connect(pDownload_, SIGNAL(signalDownloadProgress(int)), progressBar, SLOT(setValue(int))); 313 | connect(pDownload_, SIGNAL(signalDownloadFinish(QString)), this, SLOT(slotDownloadFinish(QString))); 314 | connect(pDownload_, SIGNAL(signalServerInfoDone(QString)), this, SLOT(slotServerInfoDone(QString))); 315 | connect(pDownload_, SIGNAL(signalTcpError(QString)), this, SLOT(slotTcpError(QString))); 316 | pDownload_->prepare(); 317 | 318 | //通知栏 319 | createActions(); 320 | createTrayIcon(); 321 | connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); 322 | trayIcon->show(); 323 | } 324 | 325 | void WidgetMain::showMessage() 326 | { 327 | trayIcon->showMessage(tr("title"), tr("show the message")); 328 | } 329 | 330 | void WidgetMain::createActions() 331 | { 332 | minimizeAction = new QAction(tr("Mi&nimize"), this); 333 | connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide())); 334 | 335 | maximizeAction = new QAction(tr("Ma&ximize"), this); 336 | connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized())); 337 | 338 | restoreAction = new QAction(tr("&Restore"), this); 339 | connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal())); 340 | 341 | quitAction = new QAction(tr("&Quit"), this); 342 | connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); 343 | } 344 | 345 | void WidgetMain::createTrayIcon() 346 | { 347 | trayIconMenu = new QMenu(this); 348 | trayIconMenu->addAction(minimizeAction); 349 | //trayIconMenu->addAction(maximizeAction); 350 | trayIconMenu->addAction(restoreAction); 351 | trayIconMenu->addSeparator(); 352 | trayIconMenu->addAction(quitAction); 353 | 354 | trayIcon = new QSystemTrayIcon(this); 355 | trayIcon->setContextMenu(trayIconMenu); 356 | trayIcon->setToolTip(tr("auto update program")); 357 | trayIcon->setIcon(QIcon(QPixmap("./resource/images/AutoUpdate/ico.png").scaled(QSize(16, 16)))); 358 | } 359 | 360 | void WidgetMain::moveTempFileToWorkPath() 361 | { 362 | qDebug() << "start copy files"; 363 | QDir dir("./DownloadTemp"); 364 | dir.setFilter(QDir::Files); 365 | QStringList list = dir.entryList(); 366 | 367 | for(int i = 0; i != list.size(); ++i) 368 | { 369 | QString name = list.at(i); 370 | if(map_name_path_.contains(name)) 371 | { 372 | QString path = map_name_path_.value(name); 373 | qDebug() << name << path; 374 | copyFile(name, path); 375 | } 376 | else 377 | { 378 | qDebug() << "map_name_path_ not contains " << name; 379 | } 380 | } 381 | } 382 | 383 | void WidgetMain::moveTempFileToWorkPath(QMap &map_name_path) 384 | { 385 | qDebug() << "start copy files"; 386 | QDir dir("./DownloadTemp"); 387 | dir.setFilter(QDir::Files); 388 | QStringList list = dir.entryList(); 389 | 390 | for(int i = 0; i != list.size(); ++i) 391 | { 392 | QString name = list.at(i); 393 | if(map_name_path.contains(name)) 394 | { 395 | QString path = map_name_path.value(name); 396 | qDebug() << name << path; 397 | copyFile(name, path); 398 | } 399 | else 400 | { 401 | qDebug() << "map_name_path not contains " << name; 402 | } 403 | } 404 | } 405 | 406 | void WidgetMain::startMind(const QString &path) 407 | { 408 | if(!QFile::exists(path)) 409 | { 410 | int result = QMessageBox::warning(this, tr("warnning"), tr("Failed to find mp in current directory. Could you manually select a directory?"), QMessageBox::Yes, QMessageBox::No); 411 | if(QMessageBox::Yes == result) 412 | { 413 | QString pathNow = QFileDialog::getOpenFileName(this, tr(""), tr(".")); 414 | startMind(pathNow); 415 | } 416 | else 417 | { 418 | return; 419 | } 420 | } 421 | //另外一个线程中去阻塞调用 422 | QThread *pThread = new QThread(this); 423 | CallMindPlus *pCallMindPlus = new CallMindPlus(path); 424 | connect(pThread, SIGNAL(started()), pCallMindPlus, SLOT(slotCallMindPlus())); 425 | pCallMindPlus->moveToThread(pThread); 426 | 427 | pThread->start(); 428 | } 429 | 430 | void WidgetMain::on_pushButton_clicked() 431 | { 432 | pDownload_->close(); 433 | this->close(); 434 | } 435 | --------------------------------------------------------------------------------