From e981394808a30a3463fc012972a403f64732859d Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Fri, 2 Oct 2015 18:30:13 +0200 Subject: [PATCH] Windows: the qt GUI builds with Qt/MinGW. No link. --- .hgignore | 1 - src/common/conf_post.h | 6 +- src/internfile/mimehandler.h | 5 +- src/qtgui/rclm_idx.cpp | 15 ++- src/qtgui/recoll.pro | 188 +++++++++++++++++++++++++++++++++++ src/qtgui/rtitool.cpp | 2 + src/qtgui/rtitool.h | 7 ++ src/utils/execmd.cpp | 8 ++ src/utils/execmd.h | 17 +++- src/utils/smallut.cpp | 71 +++++++++++++ src/utils/smallut.h | 5 + src/windows/execmd_w.cpp | 12 +++ 12 files changed, 322 insertions(+), 15 deletions(-) create mode 100644 src/qtgui/recoll.pro diff --git a/.hgignore b/.hgignore index ecbfebe5..825ae08c 100644 --- a/.hgignore +++ b/.hgignore @@ -90,7 +90,6 @@ src/qtgui/Makefile src/qtgui/qrc_recoll.cpp src/qtgui/recoll src/qtgui/recoll.app -src/qtgui/recoll.pro src/query/alldeps src/query/recollq src/sampleconf/rclmon.sh diff --git a/src/common/conf_post.h b/src/common/conf_post.h index 57d3cff9..f6bfcb70 100644 --- a/src/common/conf_post.h +++ b/src/common/conf_post.h @@ -42,6 +42,9 @@ inline int readlink(const char *cp, void *buf, int cnt) { #define PATH_MAX MAX_PATH #define MAXPATHLEN PATH_MAX typedef int mode_t; +#define fseeko _fseeki64 +#define ftello (off_t)_ftelli64 +#define ftruncate _chsize_s #endif typedef DWORD32 u_int32_t; @@ -50,7 +53,6 @@ typedef unsigned __int8 u_int8_t; typedef int ssize_t; #define strncasecmp _strnicmp #define strcasecmp _stricmp -#define ftruncate _chsize_s #define chdir _chdir #define R_OK 4 @@ -59,8 +61,6 @@ typedef int ssize_t; #define RECOLL_DATADIR "C:\\recoll\\" #define S_ISLNK(X) false #define lstat stat -#define fseeko _fseeki64 -#define ftello (off_t)_ftelli64 #define timegm _mkgmtime #endif diff --git a/src/internfile/mimehandler.h b/src/internfile/mimehandler.h index 38e5429a..97257a17 100644 --- a/src/internfile/mimehandler.h +++ b/src/internfile/mimehandler.h @@ -24,6 +24,7 @@ #include "Filter.h" #include "cstr.h" +#include "smallut.h" class RclConfig; @@ -93,9 +94,7 @@ public: virtual void set_docsize(off_t size) { - char csize[30]; - sprintf(csize, "%lld", (long long)size); - m_metaData[cstr_dj_keydocsize] = csize; + m_metaData[cstr_dj_keydocsize] = ulltodecstr(size); } virtual bool has_documents() const {return m_havedoc;} diff --git a/src/qtgui/rclm_idx.cpp b/src/qtgui/rclm_idx.cpp index 226c6f9e..c6cb7b12 100644 --- a/src/qtgui/rclm_idx.cpp +++ b/src/qtgui/rclm_idx.cpp @@ -175,15 +175,21 @@ void RclMain::toggleIndexing() if (m_idxproc) { // Indexing was in progress, request stop. Let the periodic // routine check for the results. - int pid = m_idxproc->getChildPid(); - if (pid > 0) { - kill(pid, SIGTERM); + if (m_idxproc->requestChildExit()) { m_idxkilled = true; } } break; case IXST_RUNNINGNOTMINE: { +#ifdef _WIN32 + QMessageBox::warning(0, tr("Warning"), + tr("The current indexing process " + "was not started from this " + "interface, can't kill it"), + QMessageBox::Ok, + QMessageBox::NoButton); +#else int rep = QMessageBox::information(0, tr("Warning"), tr("The current indexing process " @@ -199,7 +205,8 @@ void RclMain::toggleIndexing() if (pid > 0) kill(pid, SIGTERM); } - } +#endif + } break; case IXST_NOTRUNNING: { diff --git a/src/qtgui/recoll.pro b/src/qtgui/recoll.pro new file mode 100644 index 00000000..e032895f --- /dev/null +++ b/src/qtgui/recoll.pro @@ -0,0 +1,188 @@ +# Note this is generated by configure on Linux (see recoll.pro.in). +# recoll.pro is under version control anyway and used on Windows + +TEMPLATE = app +LANGUAGE = C++ + +QT += webkit + +# QT += dbus +# QMAKE_CXXFLAGS += -DUSE_ZEITGEIST + +QT += xml +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets webkitwidgets printsupport + +CONFIG += qt warn_on thread release + +HEADERS += \ + advsearch_w.h \ + advshist.h \ + confgui/confgui.h \ + confgui/confguiindex.h \ + crontool.h \ + editdialog.h \ + firstidx.h \ + fragbuts.h \ + idxsched.h \ + listdialog.h \ + preview_w.h \ + ptrans_w.h \ + rclhelp.h \ + rclmain_w.h \ + reslist.h \ + restable.h \ + rtitool.h \ + searchclause_w.h \ + snippets_w.h \ + specialindex.h \ + spell_w.h \ + ssearch_w.h \ + systray.h \ + uiprefs_w.h \ + viewaction_w.h \ + +SOURCES += \ + advsearch_w.cpp \ + advshist.cpp \ + confgui/confgui.cpp \ + confgui/confguiindex.cpp \ + crontool.cpp \ + fragbuts.cpp \ + guiutils.cpp \ + main.cpp \ + multisave.cpp \ + preview_w.cpp \ + ptrans_w.cpp \ + rclhelp.cpp \ + rclmain_w.cpp \ + rclm_idx.cpp \ + rclm_preview.cpp \ + rclm_saveload.cpp \ + rclm_view.cpp \ + rclm_wins.cpp \ + rclzg.cpp \ + respopup.cpp \ + reslist.cpp \ + restable.cpp \ + rtitool.cpp \ + searchclause_w.cpp \ + snippets_w.cpp \ + spell_w.cpp \ + ssearch_w.cpp \ + systray.cpp \ + uiprefs_w.cpp \ + viewaction_w.cpp \ + xmltosd.cpp + +FORMS = \ + advsearch.ui \ + crontool.ui \ + editdialog.ui \ + firstidx.ui \ + idxsched.ui \ + listdialog.ui \ + ptrans.ui \ + rclmain.ui \ + restable.ui \ + rtitool.ui \ + specialindex.ui \ + spell.ui \ + snippets.ui \ + ssearchb.ui \ + uiprefs.ui \ + viewaction.ui \ + +RESOURCES = recoll.qrc + +INCLUDEPATH += ../common ../index ../internfile ../query ../unac \ + ../utils ../aspell ../rcldb ../qtgui ../xaposix \ + confgui +windows{ + contains(QMAKE_CC, gcc){ + # MingW + QMAKE_CXXFLAGS += -std=c++0x -Wno-unused-parameter + } + contains(QMAKE_CC, cl){ + # Visual Studio + } +} + + +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj + LIBS += -L../.libs -lrecoll + + !macx { + # Note: libdir may be substituted with sthing like $(exec_prefix)/lib + # at this point and will go as such in the Makefile. Expansion will be + # completed at make time. + LIBS += -Wl,-rpath=@libdir@/recoll + } + + LIBS += @LIBXAPIAN@ $(LIBXAPIANSTATICEXTRA) \ + @LIBICONV@ $(BDYNAMIC) @LIBQZEITGEIST@ -lz + + + DEPENDPATH += $$INCLUDEPATH +} + +UNAME = $$system(uname -s) +contains( UNAME, [lL]inux ) { + LIBS += -ldl -lX11 +} + +contains( UNAME, SunOS ) { + LIBS += -ldl +} + +macx { + ICON = images/recoll.icns +} + +TRANSLATIONS = \ + i18n/recoll_cs.ts \ + i18n/recoll_da.ts \ + i18n/recoll_de.ts \ + i18n/recoll_el.ts \ + i18n/recoll_es.ts \ + i18n/recoll_fr.ts \ + i18n/recoll_it.ts \ + i18n/recoll_lt.ts \ + i18n/recoll_ru.ts \ + i18n/recoll_tr.ts \ + i18n/recoll_uk.ts \ + i18n/recoll_xx.ts \ + i18n/recoll_zh_CN.ts \ + i18n/recoll_zh.ts \ + +unix { + isEmpty(PREFIX) { + PREFIX = /usr/local + } + message("Prefix is $$PREFIX") + DEFINES += PREFIX=\\\"$$PREFIX\\\" + + # Installation stuff + target.path = "$$PREFIX/bin" + + imdata.files = mtpics/*.png + imdata.path = $$PREFIX/share/recoll/images + trdata.files = i18n/*.qm + trdata.path = $$PREFIX/share/recoll/translations + desktop.files += ../desktop/recoll-searchgui.desktop + desktop.path = $$PREFIX/share/applications/ + icona.files += ../desktop/recoll.png + icona.path = $$PREFIX/share/icons/hicolor/48x48/apps/ + iconb.files += ../desktop/recoll.png + iconb.path = $$PREFIX/share/pixmaps/ + appdata.files = ../desktop/recoll.appdata.xml + appdata.path = $$PREFIX/share/appdata/ + INSTALLS += target imdata trdata desktop icona iconb appdata + + # The recollinstall script used to do the following to install zh_CN as + # zh. Is this still needed? + #${INSTALL} -m 0444 ${I18N}/recoll_zh_CN.qm \ + # ${datadir}/recoll/translations/recoll_zh.qm || exit 1 +} diff --git a/src/qtgui/rtitool.cpp b/src/qtgui/rtitool.cpp index f1f51ffd..085fd5f1 100644 --- a/src/qtgui/rtitool.cpp +++ b/src/qtgui/rtitool.cpp @@ -1,3 +1,4 @@ +#ifndef _WIN32 /* Copyright (C) 2005 J.F.Dockes * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -174,3 +175,4 @@ out: if (exitdial) QDialog::accept(); } +#endif diff --git a/src/qtgui/rtitool.h b/src/qtgui/rtitool.h index 8b64e890..baa89036 100644 --- a/src/qtgui/rtitool.h +++ b/src/qtgui/rtitool.h @@ -31,10 +31,17 @@ class RTIToolW : public QDialog, public Ui::RTIToolW { init(); } public slots: +#ifdef _WIN32 + void sesclicked(bool) {} + void accept() {} +private: + void init() {} +#else void sesclicked(bool); void accept(); private: void init(); +#endif }; diff --git a/src/utils/execmd.cpp b/src/utils/execmd.cpp index fc7c49c3..3a4292d3 100644 --- a/src/utils/execmd.cpp +++ b/src/utils/execmd.cpp @@ -190,6 +190,14 @@ void ExecCmd::zapChild() (void)wait(); } +bool ExecCmd::requestChildExit() +{ + if (m->m_pid > 0) { + if (kill(m->m_pid, SIGTERM) == 0) + return true; + } + return false; +} /* From FreeBSD's which command */ static bool exec_is_there(const char *candidate) diff --git a/src/utils/execmd.h b/src/utils/execmd.h index 0cf295df..68d7e87a 100644 --- a/src/utils/execmd.h +++ b/src/utils/execmd.h @@ -157,17 +157,26 @@ class ExecCmd { /** * Cancel/kill command. This can be called from another thread or - * from the advise callback, which could also raise an exception to - * accomplish the same thing + * from the advise callback, which could also raise an exception + * to accomplish the same thing. In the owner thread, any I/O loop + * will exit at the next iteration, and the process will be waited for. */ void setKill(); /** - * Get rid of current process (become ready for start). + * Get rid of current process (become ready for start). This will signal + * politely the process to stop, wait a moment, then terminate it. This + * is a blocking call. */ void zapChild(); - ExecCmd(); + /** + * Request process termination (SIGTERM or equivalent). This returns + * immediately + */ + bool requestChildExit(); + + ExecCmd(); ~ExecCmd(); /** diff --git a/src/utils/smallut.cpp b/src/utils/smallut.cpp index f8ab9431..8d814da5 100644 --- a/src/utils/smallut.cpp +++ b/src/utils/smallut.cpp @@ -616,6 +616,77 @@ bool pcSubst(const string& in, string& out, const map& subs) } return true; } +inline static int ulltorbuf(unsigned long long val, char *rbuf) +{ + int idx; + for (idx = 0; val; idx++) { + rbuf[idx] = '0' + val % 10; + val /= 10; + } while (val); + rbuf[idx] = 0; + return idx; +} + +inline static void ullcopyreverse(const char *rbuf, string& buf, int idx) +{ + buf.reserve(idx+1); + for (int i = idx - 1; i >= 0; i--) { + buf.push_back(rbuf[i]); + } + buf.push_back(0); +} + +void ulltodecstr(unsigned long long val, string& buf) +{ + buf.clear(); + if (val == 0) { + buf = "0"; + return; + } + + char rbuf[30]; + int idx = ulltorbuf(val, rbuf); + + ullcopyreverse(rbuf, buf, idx); + return; +} + +void lltodecstr(long long val, string& buf) +{ + buf.clear(); + if (val == 0) { + buf = "0"; + return; + } + + bool neg = val < 0; + if (neg) + val = -val; + + char rbuf[30]; + int idx = ulltorbuf(val, rbuf); + + if (neg) + rbuf[idx++] = '-'; + rbuf[idx] = 0; + + ullcopyreverse(rbuf, buf, idx); + return; +} + +string lltodecstr(long long val) +{ + string buf; + lltodecstr(val, buf); + return buf; +} + +string ulltodecstr(unsigned long long val) +{ + string buf; + ulltodecstr(val, buf); + return buf; +} // Convert byte count into unit (KB/MB...) appropriate for display string displayableBytes(off_t size) diff --git a/src/utils/smallut.h b/src/utils/smallut.h index 8cd14f50..95c989f8 100644 --- a/src/utils/smallut.h +++ b/src/utils/smallut.h @@ -134,6 +134,11 @@ extern string truncate_to_word(const string &input, string::size_type maxlen); /** Truncate in place in an utf8-legal way */ extern void utf8truncate(string &s, int maxlen); +void ulltodecstr(unsigned long long val, string& buf); +void lltodecstr(long long val, string& buf); +string lltodecstr(long long val); +string ulltodecstr(unsigned long long val); + /** Convert byte count into unit (KB/MB...) appropriate for display */ string displayableBytes(off_t size); diff --git a/src/windows/execmd_w.cpp b/src/windows/execmd_w.cpp index becd503c..5621749f 100644 --- a/src/windows/execmd_w.cpp +++ b/src/windows/execmd_w.cpp @@ -427,6 +427,18 @@ void ExecCmd::zapChild() setKill(); (void)wait(); } + +bool ExecCmd::requestChildExit() +{ + if (m_piProcInfo.hProcess) { + LOGDEB(("ExecCmd: GenerateConsoleCtrlEvent -> %d\n", + m_piProcInfo.dwProcessId)); + return GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, + m_piProcInfo.dwProcessId); + } + return false; +} + void ExecCmd::putenv(const string &envassign) { vector v;