QuickDocumentDialog::QuickDocumentDialog(QWidget *parent, const char *name)
		:QDialog(parent) {
	setWindowTitle(name);
	setModal(true);
	ui.setupUi(this);
	connect(ui.pushButtonClass , SIGNAL(clicked()), SLOT(addUserClass()));
	ui.comboBoxSize->addItem("10pt");
	ui.comboBoxSize->addItem("11pt");
	ui.comboBoxSize->addItem("12pt");
	connect(ui.pushButtonPaper , SIGNAL(clicked()), SLOT(addUserPaper()));
	connect(ui.pushButtonEncoding , SIGNAL(clicked()), SLOT(addUserEncoding()));
	connect(ui.pushButtonOptions , SIGNAL(clicked()), SLOT(addUserOptions()));
	ui.listWidgetOptions->setSelectionMode(QAbstractItemView::ExtendedSelection);
	setWindowTitle(tr("Quick Start"));
}
Example #2
0
bool startJVM(TCHAR* basedir, TCHAR* appFolder, TCHAR* jar, int argCount, LPTSTR *szArgList) {
    TCHAR jvmPath[LAUNCHER_MAXPATH+1] = {0};
    JavaVMInitArgs jvmArgs;
    JavaVMOption options[MAX_OPTIONS+1];
    JVM_CREATE createProc;
    JNIEnv* env;
    JavaVM* jvm = NULL;
    char jarASCII[LAUNCHER_MAXPATH] = {0};
    char classpath[LAUNCHER_MAXPATH*2] = {0};
    char mainclassASCII[LAUNCHER_MAXPATH] = {0},
        appClasspath[LAUNCHER_MAXPATH] = {0};
    size_t outlen = 0;
    jclass cls;
    jmethodID mid;
    TCHAR argname[MAX_OPTION_NAME + 1] = {0};
    TCHAR argvalue[LAUNCHER_MAXPATH] = {0},
    mainclass[LAUNCHER_MAXPATH] = {0};
    CHAR  argvalueASCII[LAUNCHER_MAXPATH] = {0};
    HMODULE msvcrtdll;
    bool runtimeBundled;
    TCHAR tmpPath[LAUNCHER_MAXPATH] = {0};
    TCHAR appid[LAUNCHER_MAXPATH] = {0};

    memset(&options, 0, sizeof(JavaVMOption)*(MAX_OPTIONS + 1));
    memset(&jvmArgs, 0, sizeof(JavaVMInitArgs));

    makeFullFileName(basedir, _T("\\runtime"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR));
    runtimeBundled = fileExists(tmpPath);
    if (runtimeBundled) {
       if (!getJvmPath(basedir, jvmPath, LAUNCHER_MAXPATH)) {
            showError(_T("jvm.dll is not found in bundled runtime."), jvmPath);
            return false;
       }
       //make sure msvcr100 is loaded (or we may fail if copy of it is not installed into system)
       makeFullFileName(basedir, _T("runtime\\jre\\bin\\msvcr100.dll"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR));
       msvcrtdll = ::LoadLibrary(tmpPath);
    } else {
        if (!getSystemJvmPath(jvmPath, LAUNCHER_MAXPATH)) {
            showError(_T("No bundled runtime and can not find system JRE."), jvmPath);
            return false;
        }
       //make sure msvcr100 is loaded (or we may fail if copy of it is not installed into system)
       makeFullFileName(basedir, _T("\\bin\\msvcr100.dll"), tmpPath, sizeof(tmpPath)/sizeof(TCHAR));
       msvcrtdll = ::LoadLibrary(tmpPath);
    }

    // Dynamically load the JVM
    HMODULE jvmLibHandle = LoadLibrary(jvmPath);
    if (jvmLibHandle == NULL) {
        DWORD dwErr = GetLastError();
        showError(_T("Error loading jvm.dll"), jvmPath);
        return false;
    }

    //convert argument to ASCII string as this is what CreateJVM needs
    wcstombs_s(&outlen, jarASCII, LAUNCHER_MAXPATH, jar, (size_t) wcslen(jar) + 1);
    strcpy_s(classpath, LAUNCHER_MAXPATH*2, "-Djava.class.path=");
    strcat_s(classpath, LAUNCHER_MAXPATH, jarASCII);

    if (getConfigValue(basedir, CONFIG_CLASSPATH_KEY, argvalue, LAUNCHER_MAXPATH)) {
           size_t inLen = (size_t) wcslen(argvalue);
           //convert argument to ASCII string as this is what CreateJVM needs
           wcstombs_s(&outlen, argvalueASCII, sizeof(argvalueASCII), argvalue, inLen + 1);
           //compress spaces and replaces them with ;
           {
               char *in = argvalueASCII;
               char *out = argvalueASCII;
               bool needSemicolon = false;

               while (*in != 0) {
                   if (*in == ' ') {
                       if (needSemicolon) {
                          *out = ';';
                          out++;
                          needSemicolon = false;
                       }
                   } else {
                       needSemicolon = true;
                       *out = *in;
                       out++;
                   }
                   in++;
               }
               *out = 0;
           }
           if (strlen(argvalueASCII) > 0) {
               strcat_s(classpath, LAUNCHER_MAXPATH, ";");
               strcat_s(classpath, LAUNCHER_MAXPATH, argvalueASCII);
           }
    }

    // Set up the VM init args
    jvmArgs.version = JNI_VERSION_1_2;

    options[0].optionString = _strdup(classpath);

    int cnt = 1;
    if (isDebug) {
       options[cnt].optionString = _strdup("vfprintf");
       options[cnt].extraInfo    = vfprintfHook;
       cnt++;
    }

    //Note: should not try to quote the path. Spaces are fine here
    _stprintf_s(argvalue, _T("-Djava.library.path=%s"), appFolder);
    wcstombs_s(&outlen, argvalueASCII, sizeof(argvalueASCII),
               argvalue, wcslen(argvalue) + 1);
    options[cnt].optionString = _strdup(argvalueASCII);
    cnt++;

    //add app specific JVM parameters
    int idx = 1;
    int found = 0;
    do {
       _stprintf_s(argname, MAX_OPTION_NAME, _T("jvmarg.%d"), idx);
       found = getConfigValue(basedir, argname, argvalue, LAUNCHER_MAXPATH);
       if (found) {
            TCHAR* option = replaceStr(argvalue, _T("$APPDIR"), basedir);
            char* jvmOption = convertToDupedChar(option);
            if (jvmOption != NULL) {
                options[cnt].optionString = jvmOption;
                cnt++;
            }
            idx++;
        }
    } while (found && idx < MAX_OPTIONS);

	cnt = addUserOptions(basedir, options, cnt);

    jvmArgs.version = 0x00010002;
    jvmArgs.options = options;
    jvmArgs.nOptions = cnt;
    jvmArgs.ignoreUnrecognized = JNI_TRUE;

    // Create the JVM
    // NB: need to use ASCII string as UNICODE is not supported
    createProc = (JVM_CREATE) GetProcAddress(jvmLibHandle, "JNI_CreateJavaVM");
    if (createProc == NULL) {
        showError(_T("Failed to locate JNI_CreateJavaVM"), jvmPath);
        return false;
    }

    if ((*createProc)(&jvm, &env, &jvmArgs) < 0) {
        showError(_T("Failed to create JVM"), jvmPath);
        return false;
    }

    if (!getConfigValue(basedir, CONFIG_MAINCLASS_KEY, mainclass, LAUNCHER_MAXPATH)) {
        showError(_T("Package error"), _T("No main class specified. Nothing to launch"));
        return false;
    } else {
           size_t inLen = (size_t) wcslen(mainclass);
           //convert argument to ASCII string as this is what CreateJVM needs
           wcstombs_s(&outlen, mainclassASCII, sizeof(mainclassASCII), mainclass, inLen + 1);
    }

    cls = env->FindClass(mainclassASCII);
    if (cls != NULL) {
        mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
         if (mid != NULL) {
            jclass stringClass = env->FindClass("java/lang/String");
            //prepare app arguments if any. Skip value at index 0 - this is path to executable ...
            //NOTE:
            //  - what if user run in non-English/UTF-8 locale? do we need to convert args?
            //  - extend to pass jvm args and debug args (allow them in front, use marker option to separate them?)
            int startArgIndex = countNumberOfSystemArguments(argCount, szArgList);
            jobjectArray args = env->NewObjectArray(argCount - startArgIndex, stringClass, NULL);
            for(int i=startArgIndex; i<argCount; i++) {
                size_t inLen = (size_t) wcslen(szArgList[i]);
                env->SetObjectArrayElement(args, i-startArgIndex, env->NewString((jchar*)szArgList[i], inLen));
            }
            env->CallStaticVoidMethod(cls, mid, args);
        } else {
            showError(_T("no main method in the main class!"), mainclass);
            return false;
        }
    } else {
        showError(_T("no main class."), mainclass);
        return false;
    }

    if (env->ExceptionOccurred()) {
        showError(_T("Failed due to exception from main class."), mainclass);
        env->ExceptionDescribe();
    }

    // If application main() exits quickly but application is run on some other thread
    //  (e.g. Swing app performs invokeLater() in main and exits)
    // then if we return execution to tWinMain it will exit.
    // This will cause process to exit and application will not actually run.
    //
    // To avoid this we are trying to detach jvm from current thread (java.exe does the same)
    // Because we are doing this on the main JVM thread (i.e. one that was used to create JVM)
    // this call will spawn "Destroy Java VM" java thread that will shut JVM once there are
    // no non-daemon threads running, and then return control here.
    // I.e. this will happen when EDT and other app thread will exit.
    if (jvm->DetachCurrentThread() != 0) {
        showError(_T("Detach failed."), NULL);
    }
    jvm->DestroyJavaVM();

    return true;
}