File oooqs-1.0_rc3-quickstart.patch of Package OpenOffice_org-Quickstarter
--- oooqs/oooqs.cpp
+++ oooqs/oooqs.cpp
@@ -18,6 +18,11 @@
#include "oooqs.h"
#include <prefsdialog.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+
#include <qcursor.h>
#include <qfile.h>
#include <qiodevice.h>
@@ -148,12 +153,13 @@
else
instance << soffice << "-quickstart";
+ /** Make sure that instance is automatically restarted when it gets closed */
+ connect(&instance, SIGNAL (processExited(KProcess*)), SLOT (restartOfficeWait()));
+
/** Check if the quickstart should be enabled */
if (quickstartEnabled){
- /** Make sure that instance is automatically restarted when it gets closed */
- connect(&instance, SIGNAL (processExited(KProcess*)), SLOT (restartOffice()));
/** Try to start instance for the first time */
- restartOffice();
+ restartOffice(true);
}
}
@@ -229,14 +235,37 @@
startInstances("private:factory/swriter/web");
}
+/** Restarts OpenOffice if removed from memory and try to wait if an other OOo isntance is already running */
+void OooQs::restartOfficeWait(){
+ restartOffice(false);
+}
+
/** Restarts OpenOffice if removed from memory. */
-void OooQs::restartOffice(){
+void OooQs::restartOffice(bool immediately){
/** at first check if the quickstart-mode is enabled */
if (quickstartEnabled){
/** check, if the Master Instance is running ! */
if (!instance.isRunning()) {
- /** we dont need any Communication ! */
- instance.start(KProcess::NotifyOnExit,KProcess::NoCommunication);
+ if (!immediately) {
+ int waitSec=120;
+ while ((isAnotherOOoInstanceRunning()) && (--waitSec >= 0))
+ sleep(1);
+ }
+ if (!isAnotherOOoInstanceRunning()) {
+ /** we dont need any Communication ! */
+ instance.start(KProcess::NotifyOnExit,KProcess::NoCommunication);
+ } else {
+ /** another OOo isntance is running then each new OOo instance
+ will be immediately exited, so the quickstarter mode will not
+ work and must be disabled */
+ KMessageBox::information(preferencesDialog, i18n("The quickstart mode cannot be enabled at this time because OpenOffice.org is already in use.\n"
+ "\n"
+ "You can enable the quickstart mode in the Quickstarter configuration dialog after you have stopped the current OpenOffice.org."));
+ preferencesDialog->enableQuick->setChecked(false);
+ quickstartEnabled=false;
+ /** save changed value into the config file */
+ changedConfig();
+ }
}
}
}
@@ -324,13 +353,13 @@
if (quickstartEnabled){
quickstartEnabled=false;
if (instance.isRunning()){
- if (KMessageBox::questionYesNo(0, i18n("There is still a quickstart-instance of %1 running.\nDo you want to kill it now?\n\nMake sure you close all your %2 documents before answering yes!").arg(suite).arg(suite), i18n("Running instance of %1 detected").arg(suite)) == 3){
+ if (KMessageBox::questionYesNo(preferencesDialog, i18n("There is still a quickstart-instance of %1 running.\nDo you want to kill it now?\n\nMake sure you close all your %2 documents before answering yes!").arg(suite).arg(suite), i18n("Running instance of %1 detected").arg(suite)) == 3){
instance.kill();
}
}
}else{
quickstartEnabled=true;
- restartOffice();
+ restartOffice(true);
}
}
if (open){
@@ -744,3 +773,135 @@
QString OooQs::getSoffice(void){
return soffice;
}
+
+/** helper function for the function scandir
+ we are interested in directories with informations about processes */
+int procSelect(const struct dirent *dirEnt)
+{
+ /** is it directory? */
+ if (dirEnt->d_type == DT_DIR) {
+ /** is it directory with informations about a process? */
+ char *endPtr;
+ strtol(dirEnt->d_name, &endPtr, 10);
+ if (*endPtr == '\0')
+ /** yes, it is */
+ return 1;
+ }
+ /** non-interesting dir entry */
+ return 0;
+}
+
+#define OooQs_SERACH_FILE_BUFFER_STEP 10000
+
+/** search file for the string */
+int OooQs::searchFile(const char *path, const char *string)
+{
+ FILE *file;
+ char *buf, *pBuf;
+ int bufSize=0;
+ int read;
+
+ /** open the file for reading */
+ if(!(file = fopen(path, "r")))
+ /** probably we have not rights to read this file, but in this case
+ the file is not interesting for us */
+ return 0;
+
+ /** read the whole file in a buffer */
+ /** unfortunatelly the fseek does not work in the proc file system,
+ so it is not possible to discover the file size */
+ if (!(buf=(char *)malloc(OooQs_SERACH_FILE_BUFFER_STEP))) {
+ fclose(file);
+ return 0;
+ }
+ bufSize=OooQs_SERACH_FILE_BUFFER_STEP;
+ pBuf=buf;
+ while ((read=fread(pBuf, 1, OooQs_SERACH_FILE_BUFFER_STEP, file)) == OooQs_SERACH_FILE_BUFFER_STEP) {
+ bufSize += OooQs_SERACH_FILE_BUFFER_STEP;
+ if(!(buf = (char *)realloc(buf, bufSize))) {
+ fclose(file);
+ return 0;
+ }
+ /** the pBuf must be derived from the new buf (after realloc) !!! */
+ pBuf = buf + bufSize - OooQs_SERACH_FILE_BUFFER_STEP;
+ }
+
+ /** close the file */
+ fclose(file);
+
+ /** add '\0' at the end of read string */
+ pBuf = &(buf[bufSize - OooQs_SERACH_FILE_BUFFER_STEP + read]);
+ *pBuf='\0';
+ /** file environ contains many '\0'. change them to '.', so
+ strstr can be used */
+ while (--pBuf >= buf)
+ if (*pBuf == '\0')
+ *pBuf='.';
+
+ /** try to find the string in the buffer */
+ if(strstr(buf, string)) {
+ /** string found */
+ free(buf);
+ return 1;
+ }
+
+ /** string not found */
+ free(buf);
+ return 0;
+}
+
+/** free the array with dir entries allocated by the function scandir */
+void OooQs::freeDirList(struct dirent **dirList, int dirEntNum)
+{
+ for (int i = 0; i < dirEntNum; i++) {
+ free(dirList[i]);
+ }
+
+ if (dirList) free(dirList);
+}
+
+/** check if the soffice.bin is runnig by the user $USER */
+int OooQs::isAnotherOOoInstanceRunning()
+{
+ struct dirent **procList=NULL;
+ int dirEntNum;
+ int i;
+ char searchedUSER[1024];
+ char searchedFile[1024];
+
+ /** which user is running this Quickstarter instance */
+ strcpy(searchedUSER, "USER=");
+ strncat(searchedUSER, getenv("USER"), 1000);
+
+ /** scan the directory /proc for directories with informations about processes */
+ dirEntNum = scandir("/proc", &procList, &procSelect, &alphasort);
+
+ if(dirEntNum < 0)
+ /** the /proc dir can not be read */
+ return 0;
+
+ /** scan each process */
+ for(i = 0; i < dirEntNum; i++) {
+ strcpy(searchedFile, "/proc/");
+ strncat(searchedFile, procList[i]->d_name, 1000);
+ strcat(searchedFile, "/cmdline");
+
+ /** does it run soffice.bin? */
+ if(searchFile(searchedFile, "soffice.bin")) {
+ strcpy(searchedFile, "/proc/");
+ strncat(searchedFile, procList[i]->d_name, 1000);
+ strcat(searchedFile, "/environ");
+
+ /** does it run the user $USER? */
+ if(searchFile(searchedFile, searchedUSER)) {
+ /** yes, it does. Another OOo instance is already running */
+ freeDirList(procList, dirEntNum);
+ return 1;
+ }
+ }
+ }
+
+ /** no other running OOo instance found */
+ freeDirList(procList, dirEntNum);
+ return 0;
+}
--- oooqs/oooqs.h
+++ oooqs/oooqs.h
@@ -128,8 +128,8 @@
void startWriter();
/** Executes the about-dialog. */
void showAbout();
- /** Restarts OpenOffice if removed from memory. */
- void restartOffice();
+ /** Restarts OpenOffice if removed from memory and try to wait if an other OOo isntance is already running. */
+ void restartOfficeWait();
/** Delete the process. */
void delProcess(KProcess* process);
/** Call this to open the start-dialog. */
@@ -149,6 +149,14 @@
void setDoubleClickAction();
/** Set the texts on the actions opening the connected module. */
void updateActions(void);
+ /** Restarts OpenOffice if removed from memory. */
+ void restartOffice(bool immediately);
+ /** search file for the string */
+ int searchFile(const char *path, const char *string);
+ /** free the array with dir entries allocated by the function scandir */
+ void freeDirList(struct dirent **dirList, int dirEntNum);
+ /** check if the soffice.bin is runnig by the user $USER */
+ int isAnotherOOoInstanceRunning();
signals:
/** Emit when a double click was registered */
void doubleClick();