同步操作将从 爬山虎/ndd 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#include "ccnotepad.h"#include "nddsetting.h"#include "styleset.h"#include <QtWidgets/QApplication>#include <QTextCodec>#include <QMessageBox>#include <QSharedMemory>#include <QFile>#include <QStatusBar>#include <qobject.h>#include <QThread>#include <QDir>#ifdef Q_OS_UNIX#include <QStyleFactory>#include <signal.h>#include <unistd.h>#include <QDebug>#include <QWidget>#endif#ifdef Q_OS_WIN#pragma comment(lib, "user32.lib")#if _DEBUG#pragma comment(lib, "qmyedit_qt5d.lib")#else#pragma comment(lib, "qmyedit_qt5.lib")#endif#include <qt_windows.h>const ULONG_PTR CUSTOM_TYPE = 10000;const ULONG_PTR OPEN_NOTEPAD_TYPE = 10001;const ULONG_PTR CUSTOM_TYPE_FILE_LINENUM = 10002;bool s_isAdminAuth = false;#endifconst QString c_strTitle = "Ndd";#ifdef Q_OS_UNIX#if defined(Q_OS_MAC)QSharedMemory shared("CCNotebook123");;//mac下面后面带一个版本号,避免新的打不开#elseQSharedMemory shared("CCNotebook");#endifQSharedMemory nppShared("notepad--");static void sig_usr(int signo){if(signo == SIGUSR1){qlonglong winId;shared.lock();memcpy(&winId,shared.data(),sizeof(qlonglong));shared.unlock();QWidget *pMain = QWidget::find((WId)winId);CCNotePad* pNotePad = dynamic_cast<CCNotePad*>(pMain);if(pNotePad != nullptr){QString filePath((char*)nppShared.data()+4);if(!filePath.isEmpty()){pNotePad->openFile(filePath);}pNotePad->activateWindow();pNotePad->showNormal();qDebug() << "sig_usr" << filePath;}}}#endif#ifdef Q_OS_MACstatic void openfile(QString filePath){qlonglong winId;shared.lock();memcpy(&winId,shared.data(),sizeof(qlonglong));shared.unlock();QWidget *pMain = QWidget::find((WId)winId);CCNotePad* pNotePad = dynamic_cast<CCNotePad*>(pMain);if(pNotePad != nullptr){if(!filePath.isEmpty()){pNotePad->openFile(filePath);}pNotePad->activateWindow();pNotePad->showNormal();}}class MyApplication : public QApplication{public:MyApplication(int &argc, char **argv): QApplication(argc, argv){}bool event(QEvent *event){if (event->type() == QEvent::FileOpen) {QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);qDebug() << "Open file" << openEvent->file();s_openfile = openEvent->file();openfile(s_openfile);}return QApplication::event(event);}QString s_openfile;};#endifint main(int argc, char *argv[]){#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);#elif (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))#ifdef Q_OS_WINHDC hdc = CreateDC(L"display", NULL, NULL, NULL);int ndpi = GetDeviceCaps(hdc, LOGPIXELSY);qputenv("QT_SCALE_FACTOR", QString::number(ndpi / 96.0).toUtf8());#endif // Q_OS_WIN#endif#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);#endif#ifdef Q_OS_MACMyApplication a(argc, argv);#elseQApplication a(argc, argv);#endif#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))a.setAttribute(Qt::AA_UseHighDpiPixmaps);#endif//不能开启,开启后相对路径打开文件失败//QDir::setCurrent(QCoreApplication::applicationDirPath());#if defined(Q_OS_UNIX)QApplication::setStyle(QStyleFactory::create("fusion"));#endifa.setApplicationDisplayName(c_strTitle);a.setApplicationName(c_strTitle);QStringList arguments = QCoreApplication::arguments();//目前就三种//1) ndd filepath//2) ndd filepath -n linenum//3) ndd -multi filepath//只有 1 2 需要处理短路径if ((arguments.size() == 2) || (arguments.size() == 4)){QFileInfo fi(arguments[1]);if (fi.isRelative()){QString absDir = QDir::currentPath();//获取绝对路径arguments[1] = QString("%1/%2").arg(absDir).arg(arguments.at(1));}}#ifdef uosQFont font("Noto Sans CJK SC,9,-1,5,50,0,0,0,0,0,Regular", 9);QApplication::setFont(font);#endif#ifdef Q_OS_MAC//这里的字体大小,务必要和查找结果框的高度匹配,否则会结构字体拥挤QFont font("Courier New,11,-1,5,50,0,0,0,0,0,Regular", 11);// qDebug() << "font name mac";QApplication::setFont(font);// qDebug() << QApplication::font().toString();#endifbool isGotoLine = false;#ifdef Q_OS_WINQSharedMemory shared("ccnotepad");if (arguments.size() > 2){//如果是多开请求,这种是从管理员权限申请后重开过来的if (arguments[1] == QString("-muti")){s_isAdminAuth = true;QString title = QString(u8"%1 管理员").arg(c_strTitle);a.setApplicationDisplayName(title);//删除-muti这个参数arguments.removeAt(1);//管理员不占用共享标志。这样的目的是,当管理员窗口存在时//打开原来的文件,原来的文件可以占用共享标志,作为主窗口打开。//管理员窗口永远不做主窗口打开goto authAdmin;}else if ((arguments.size() == 4) && arguments[2] == QString("-n")){//使用的是 file -n lineNums 方式。目前只有windows下支持 xxxfile -n linenum的格式isGotoLine = true;}}#elseif ((arguments.size() == 4) && (arguments[2] == QString("-n"))){//使用的是 file -n lineNums 方式。目前只有windows下支持 xxxfile -n linenum的格式isGotoLine = true;}#endif//attach成功表示已经存在该内存了,表示当前存在实例if (shared.attach())//共享内存被占用则直接返回{//发现在文件中如果存在空格时,参数不止1个,所以不能单纯用2个参数表示if (arguments.size() > 1){#if defined(Q_OS_WIN)int tryTimes = 0;do {qlonglong hwndId;shared.lock();memcpy(&hwndId, shared.data(), sizeof(qlonglong));shared.unlock();HWND hwnd = (HWND)hwndId;if (::IsWindow(hwnd)){if (!isGotoLine){//就是ndd filepath的命令行格式//去掉第一个参数,后续的参数拼接起来。其实参数中间有空格还是需要使用""引用起来,避免空格参数分隔为多个arguments.takeFirst();QString filename = arguments.join("");QByteArray data = filename.toUtf8();COPYDATASTRUCT copydata;copydata.dwData = CUSTOM_TYPE; //自定义类型copydata.lpData = data.data(); //数据大小copydata.cbData = data.size(); // 指向数据的指针::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(©data));}else{//是 filepath -n linenums 方式。不考虑filepath含有空格的情况,因为前面做了严格判断QString para = QString("%1|%2").arg(arguments[1]).arg(arguments[3]);QByteArray data = para.toUtf8();COPYDATASTRUCT copydata;copydata.dwData = CUSTOM_TYPE_FILE_LINENUM; //自定义类型copydata.lpData = data.data(); //数据大小copydata.cbData = data.size(); // 指向数据的指针::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(©data));}break;}else{//20230304 右键多个文件同时打开,比如3个。此时只有第1个可获取锁,其余2个均走这里。//因为第个还没有来的及写入hwnd。此时不要goto drop_old。等一下再重试QThread::sleep(1);++tryTimes;//2次识别后,没法了,只能通过继续往下走。//失败了,此时说明前一个窗口极可能状态错误了。如果不处理,则再也打不开程序了if (tryTimes > 2){goto drop_old;}}} while (true);#elif defined (Q_OS_MAC){//mac下面不需要,有他自身的机制保证}#elsepid_t pid;arguments.takeFirst();QString filename = arguments.join("");QByteArray data = filename.toUtf8();nppShared.attach();nppShared.lock();memcpy(&pid, nppShared.data(), sizeof(pid_t));memset((char*)nppShared.data()+sizeof(pid_t),0, 1024-sizeof(pid_t));memcpy((char*)nppShared.data()+sizeof(pid_t),data.data(),data.size());nppShared.unlock();//if kill failed, then open a new processif(0 != kill(pid,SIGUSR1)){goto unix_goon;}#endif}else if (arguments.size() == 1){#if defined(Q_OS_WIN)//把窗口设置到最前qlonglong hwndId;shared.lock();memcpy(&hwndId, shared.data(), sizeof(qlonglong));shared.unlock();HWND hwnd = (HWND)hwndId;if (::IsWindow(hwnd)){QString filename("open");QByteArray data = filename.toUtf8();COPYDATASTRUCT copydata;copydata.dwData = OPEN_NOTEPAD_TYPE; //自定义类型copydata.lpData = data.data(); //数据大小copydata.cbData = data.size(); // 指向数据的指针::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(©data));}else{//失败了,此时说明前一个窗口极可能状态错误了。如果不处理,则再也打不开程序了//继续新开一个窗口,放弃之前的旧内容goto drop_old;}#elif defined (Q_OS_MAC){//mac下面不需要,有他自身的机制保证}#elsepid_t pid;nppShared.attach();nppShared.lock();memcpy(&pid, nppShared.data(), sizeof(pid_t));memset((char*)nppShared.data()+sizeof(pid_t),0, 1024-sizeof(pid_t));nppShared.unlock();qDebug()<<"empty file send";if(0 != kill(pid,SIGUSR1)){goto unix_goon;}#endif}return 0;}#if defined(Q_OS_WIN)shared.create(32);#elif defined (Q_OS_MAC){//mac下面不需要,有他自身的机制保证。当程序已经在线时,再打开程序,系统会自动调用已经存在的程序出现//不需要使用类似linux下面的机制。shared.create(32);nppShared.create(32);}#elseunix_goon:shared.create(32);nppShared.create(2048);if(signal(SIGUSR1,sig_usr) == SIG_ERR){qDebug()<<"linux create sign failed";}#endif#if defined(Q_OS_WIN)authAdmin:drop_old:#endif//20221009发现有小概率出现窗口没有,但是进程还在的诡异问题,加个保护一下QApplication::setQuitOnLastWindowClosed(true);NddSetting::init();int id = NddSetting::getKeyValueFromNumSets(SKIN_KEY);StyleSet::setSkin(id);CCNotePad *pMainNotepad = new CCNotePad(true);pMainNotepad->setAttribute(Qt::WA_DeleteOnClose);pMainNotepad->setShareMem(&shared);pMainNotepad->quickshow();pMainNotepad->syncCurSkinToMenu(id);#ifdef Q_OS_WIN//HWND hwnd = ::FindWindowA("Qt5QWindowIcon", "CCNotebook");//发现hwnd就是和effectiveWinId相等的,不需要查询了//管理员可以多开,暂时不把管理员的权限作为主窗口,因为其他用户没有权限右键菜单发送消息给管理员窗口去打开文件if (!s_isAdminAuth){qlonglong winId = (qlonglong)pMainNotepad->effectiveWinId();shared.lock();memcpy(shared.data(), &winId, sizeof(qlonglong));shared.unlock();}#elseqlonglong winId = (qlonglong)pMainNotepad->effectiveWinId();shared.lock();memcpy(shared.data(), &winId, sizeof(qlonglong));shared.unlock();nppShared.attach();//get proceess id to share memorypid_t pid = getpid();nppShared.lock();memcpy(nppShared.data(), &pid, sizeof(pid_t));nppShared.unlock();#endif // Q_OS_WIN//恢复上次关闭时的文件#ifdef Q_OS_WINif (!s_isAdminAuth){if (0 == pMainNotepad->restoreLastFiles() && (arguments.size() == 1)){pMainNotepad->initTabNewOne();}}#elseif (0 == pMainNotepad->restoreLastFiles()){pMainNotepad->initTabNewOne();}#endifif (arguments.size() == 2){#ifdef Q_OS_WINif (!s_isAdminAuth){pMainNotepad->openFile(arguments[1]);}else{//如果是管理员,还不能直接打开文件,需要恢复之前文件的修改内容//恢复不了,再直接打开pMainNotepad->tryRestoreFile(arguments[1]);}#elsepMainNotepad->openFile(arguments[1]);#endif}else if (isGotoLine){//是filepath -n xxx 格式。bool ok = true;int lineNum = arguments[3].toInt(&ok);if (!ok){lineNum = -1;}pMainNotepad->openFile(arguments[1], lineNum);}#ifdef Q_OS_WINpMainNotepad->checkAppFont();#endifa.exec();NddSetting::close();return 0;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。