summaryrefslogtreecommitdiffstats
path: root/qt4
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-09-09 20:27:19 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-09-09 20:27:19 +0000
commitc6ca83d07d95e076b09bd802f66ba72d363b0235 (patch)
treef13000febb0c9c5a5da621b4bba53ba3eace022e /qt4
downloadkgtk-qt3-c6ca83d07d95e076b09bd802f66ba72d363b0235.tar.gz
kgtk-qt3-c6ca83d07d95e076b09bd802f66ba72d363b0235.zip
* Added kgtk-qt3
* Slight kpowersave message cleanup git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kgtk-qt3@1173604 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'qt4')
-rw-r--r--qt4/CMakeLists.txt22
-rwxr-xr-xqt4/kqt4-wrapper.cmake29
-rw-r--r--qt4/kqt4.cpp599
3 files changed, 650 insertions, 0 deletions
diff --git a/qt4/CMakeLists.txt b/qt4/CMakeLists.txt
new file mode 100644
index 0000000..3f8dadb
--- /dev/null
+++ b/qt4/CMakeLists.txt
@@ -0,0 +1,22 @@
+find_package(Qt4)
+
+if (QT4_FOUND)
+ message("** INFORMATION: Qt4 LD_PRELOAD library will be built.")
+ # set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
+ set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mangled.h
+ COMMAND ${CMAKE_SOURCE_DIR}/mangled.sh ${CMAKE_CXX_COMPILER} ${CMAKE_CURRENT_BINARY_DIR}/mangled.h)
+
+ include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/common ${CMAKE_BINARY_DIR} ${QT_INCLUDE_DIR})
+ set(kqt4_SRCS kqt4.cpp mangled.h)
+ add_definitions(${QT_DEFINITIONS} -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT)
+ add_library(kqt4 SHARED ${kqt4_SRCS})
+ target_link_libraries(kqt4 ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY} -lc -ldl)
+ install(TARGETS kqt4 LIBRARY DESTINATION ${LIB_INSTALL_DIR}/kgtk)
+
+ configure_file (kqt4-wrapper.cmake ${CMAKE_CURRENT_BINARY_DIR}/kqt4-wrapper @ONLY)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/kqt4-wrapper DESTINATION bin)
+else (QT4_FOUND)
+ message("** ERROR : Could not locate Qt4 headers, Qt4 LD_PRELOAD library will not be built.")
+endif (QT4_FOUND)
diff --git a/qt4/kqt4-wrapper.cmake b/qt4/kqt4-wrapper.cmake
new file mode 100755
index 0000000..84205b6
--- /dev/null
+++ b/qt4/kqt4-wrapper.cmake
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+#
+# This script is part of the KGtk package.
+#
+# (C) Craig Drummond, 2007
+#
+# Craig.Drummond@lycos.co.uk
+#
+# --
+# Released under the GPL v2 or later
+# --
+#
+
+app=`basename $0`
+
+if [ "$app" = "kqt4-wrapper" ] ; then
+ LD_PRELOAD=@CMAKE_INSTALL_PREFIX@/lib/kgtk/libkqt4.so:$LD_PRELOAD "$@"
+else
+ dir=`dirname $0`
+ oldPath=$PATH
+ PATH=`echo $PATH | sed s:$dir::g`
+ real=`which $app`
+ PATH=$oldPath
+
+ if [ "$real" != "" ] && [ "`dirname $real`" != "$dir" ] ; then
+ LD_PRELOAD=@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@/kgtk/libkqt4.so:$LD_PRELOAD $real "$@"
+ fi
+fi
diff --git a/qt4/kqt4.cpp b/qt4/kqt4.cpp
new file mode 100644
index 0000000..4d09f80
--- /dev/null
+++ b/qt4/kqt4.cpp
@@ -0,0 +1,599 @@
+/************************************************************************
+ *
+ * All dialogs opened are created and used modal.
+ *
+ ************************************************************************
+ * (C) Craig Drummond, 2006
+ ************************************************************************
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ ************************************************************************/
+
+#define KQT_OVERLOAD_NON_STATIC_FILEDIALOGS
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtGui/QWidget>
+#include <QtGui/QApplication>
+#include <QtCore/QTextStream>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QFileDialog>
+#include <QtCore/QThread>
+#include <QtCore/Qt>
+#include <QtCore/QEventLoop>
+#include "connect.h"
+#include "config.h"
+#include "mangled.h"
+
+static bool useKde=false;
+
+#define MAX_LINE_LEN 1024
+#define MAX_APP_NAME_LEN 32
+
+static char * getAppNameFromPid(int pid)
+{
+ static char appName[MAX_APP_NAME_LEN+1]="\0";
+
+ int procFile=-1;
+ char cmdline[MAX_LINE_LEN+1];
+
+ sprintf(cmdline, "/proc/%d/cmdline",pid);
+
+ if(-1!=(procFile=open(cmdline, O_RDONLY)))
+ {
+ if(read(procFile, cmdline, MAX_LINE_LEN)>7)
+ {
+ int len=strlen(cmdline),
+ pos=0;
+
+ for(pos=len-1; pos>0 && cmdline[pos] && cmdline[pos]!='/'; --pos)
+ ;
+
+ if(pos>=0 && pos<len)
+ {
+ strncpy(appName, &cmdline[pos ? pos+1 : 0], MAX_APP_NAME_LEN);
+ appName[MAX_APP_NAME_LEN]='\0';
+ }
+ }
+ close(procFile);
+ }
+
+ return appName;
+}
+
+static const char * getAppName(bool useQt=true)
+{
+ static const char *appName=NULL;
+
+ if(!appName)
+ {
+ const char *a=useQt && QCoreApplication::arguments().count()
+ ? QCoreApplication::arguments()[0].toLatin1().constData() : getAppNameFromPid(getpid());
+ char *slash;
+
+ // Was the cmdline app java? if so, try to use its parent name - just in case
+ // its run from a shell script, etc. - e.g. as eclipse does
+ if(a && 0==strcmp(a, "java"))
+ a=getAppNameFromPid(getppid());
+
+ if(a && a[0]=='\0')
+ a=NULL;
+
+ appName=a && (slash=strrchr(a, '/')) && '\0'!=slash[1]
+ ? &(slash[1])
+ : a ? a : "Qt4App";
+ }
+
+ return appName;
+}
+
+int QApplication::exec()
+{
+ static bool init=false;
+
+ if(!init)
+ {
+ connectToKDialogD(getAppName(false));
+ init=true;
+ }
+
+ static int (*realFunction)(void);
+
+ if(!realFunction)
+ realFunction = (int (*)(void)) dlsym(RTLD_NEXT, KQT_QAPPLICATION_EXEC);
+ return (int)realFunction();
+};
+
+static QString qt2KdeFilter(const QString &f)
+{
+ QString filter;
+ QTextStream str(&filter, QIODevice::WriteOnly);
+ QStringList list(f.split(";;"));
+ QStringList::Iterator it(list.begin()),
+ end(list.end());
+ bool first=true;
+
+ for(; it!=end; ++it)
+ {
+ int ob=(*it).lastIndexOf('('),
+ cb=(*it).lastIndexOf(')');
+
+ if(-1!=cb && ob<cb)
+ {
+ if(first)
+ first=false;
+ else
+ str << '\n';
+ str << (*it).mid(ob+1, (cb-ob)-1) << '|' << (*it).mid(0, ob);
+ }
+ }
+
+ return filter;
+}
+
+static void kde2QtFilter(const QString &orig, QString *sel)
+{
+ if(sel)
+ {
+ QStringList list(orig.split(";;"));
+ QStringList::Iterator it(list.begin()),
+ end(list.end());
+ int pos;
+
+ for(; it!=end; ++it)
+ if(-1!=(pos=(*it).indexOf(*sel)) && pos>0 &&
+ ('('==(*it)[pos-1] || ' '==(*it)[pos-1]) &&
+ (*it).length()>=sel->length()+pos &&
+ (')'==(*it)[pos+sel->length()] || ' '==(*it)[pos+sel->length()]))
+ {
+ *sel=*it;
+ return;
+ }
+ }
+}
+
+#ifdef KQT_OVERLOAD_NON_STATIC_FILEDIALOGS
+static const QString getFilters(QFileDialog *dlg, bool scribusSave=false)
+{
+ QString filter;
+
+ if(dlg)
+ {
+ QStringList filters(dlg->filters());
+ QStringList::ConstIterator it(filters.begin()),
+ end(filters.end());
+ bool first(true);
+ QTextStream str(&filter, QIODevice::WriteOnly);
+
+ for(; it!=end; ++it)
+ {
+ if(!first)
+ str << ";;";
+
+ if(scribusSave && -1!=(*it).indexOf("(*.sla *.sla.gz *.scd *scd.gz)"))
+ str << "Compressed Documents (*.sla.gz *scd.gz);;Documents (*.sla *.scd)";
+ else
+ str << (*it);
+ first=false;
+ }
+ }
+
+ return filter;
+}
+
+static QString getDir(const QString &f)
+{
+ QString d(f);
+
+ int slashPos=d.lastIndexOf('/');
+
+ if(slashPos!=-1)
+ d.remove(slashPos+1, d.length());
+
+ return d;
+}
+#endif
+
+static bool writeString(int fd, const QString &str)
+{
+ QByteArray utf8(str.toUtf8());
+ int size=utf8.length()+1;
+
+ return writeBlock(fd, (char *)&size, 4) && writeBlock(fd, utf8.data(), size);
+}
+
+static bool writeBool(int fd, bool b)
+{
+ char bv=b ? 1 : 0;
+
+ return writeBlock(fd, (char *)&bv, 1);
+}
+
+class KQtDialog : public QDialog
+{
+ public:
+
+ KQtDialog(QWidget *parent) : QDialog(parent, Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint)
+ {
+ setModal(true);
+ resize(1, 1);
+ setWindowOpacity(0);
+ setWindowState(Qt::WindowMinimized);
+ move(32768, 32768);
+ }
+
+/* void r() { QDialog::reject(); }*/
+};
+
+class KQtThread : public QThread
+{
+ public:
+
+ KQtThread(QStringList &l, QString &s, int f, KQtDialog *dlg) : dialog(dlg), kdialogdError(false), res(l), selFilter(s), fd(f)
+ { }
+
+ bool readData(QByteArray &buffer, int size)
+ {
+ buffer.resize(size);
+ return ::readBlock(fd, buffer.data(), size);
+ }
+
+ bool readString(QString &str, int size)
+ {
+ QByteArray buffer;
+ buffer.resize(size);
+
+ if(!readBlock(fd, buffer.data(), size))
+ return false;
+
+ str=QString::fromUtf8(buffer.data());
+ return true;
+ }
+
+ void run()
+ {
+ QString buffer;
+ int num=0;
+
+ if(readBlock(fd, (char *)&num, 4))
+ {
+ int n;
+
+ for(n=0; n<num && !kdialogdError; ++n)
+ {
+ int size=0;
+
+ if(readBlock(fd, (char *)&size, 4))
+ {
+ if(size>0)
+ {
+ if(readString(buffer, size))
+ {
+ //buffer[size-1]='\0';
+ if('/'==buffer[0])
+ res.append(buffer);
+ else
+ selFilter=buffer;
+ }
+ else
+ kdialogdError=true;
+ }
+ }
+ else
+ kdialogdError=true;
+ }
+ }
+ else
+ kdialogdError=true;
+ QCoreApplication::postEvent(dialog, new QCloseEvent);
+ }
+
+ KQtDialog *dialog;
+ bool kdialogdError;
+ QStringList &res;
+ QString &selFilter;
+ int fd;
+};
+
+static bool sendMessage(QWidget *parent, Operation op, QStringList &res, QString &selFilter,
+ const QString &title, const QString &p1, const QString *p2, bool ow)
+{
+ if(connectToKDialogD(getAppName()))
+ {
+ char o=(char)op;
+ int xid=parent ? parent->topLevelWidget()->winId() : qApp->activeWindow()->winId();
+
+ if(writeBlock(kdialogdSocket, &o, 1) &&
+ writeBlock(kdialogdSocket, (char *)&xid, 4) &&
+ writeString(kdialogdSocket, title) &&
+ writeString(kdialogdSocket, p1) &&
+ (p2? writeString(kdialogdSocket, *p2) : true) &&
+ (OP_FILE_SAVE==op ? writeBool(kdialogdSocket, ow) : true))
+ {
+ KQtDialog dlg(parent);
+ KQtThread thread(res, selFilter, kdialogdSocket, &dlg);
+
+ thread.start();
+ dlg.exec();
+ thread.wait();
+
+ if(thread.kdialogdError)
+ {
+ closeConnection();
+ return false;
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static QString getTitle(const QString &title, Operation op)
+{
+ if(!title.isEmpty())
+ return title;
+
+ return ".";
+}
+
+static bool openKdeDialog(QWidget *widget, const QString &title, const QString &p1, const QString *p2,
+ Operation op, QStringList &res, QString *selFilter, bool ow=false)
+{
+ QString filter;
+ bool rv=sendMessage(widget, op, res, filter, getTitle(title, op), p1, p2, ow);
+
+ // If we failed to talk to, or start kdialogd, then dont keep trying - just fall back to Qt
+ if(!rv)
+ /*useKde=false*/;
+ else if(selFilter)
+ *selFilter=filter;
+
+ return rv;
+}
+
+static void kqtExit()
+{
+ if(useKde)
+ closeConnection();
+}
+
+static bool kqtInit()
+{
+ static bool initialised=false;
+
+ if(!initialised)
+ {
+ initialised=true;
+ useKde=NULL!=getenv("KDE_FULL_SESSION") && connectToKDialogD(getAppName());
+ if(useKde)
+ atexit(&kqtExit);
+ }
+
+ return useKde;
+}
+
+static QString lastDir;
+
+static void storeLastDir(const QString &f)
+{
+ lastDir=f;
+
+ int slashPos(lastDir.lastIndexOf('/'));
+
+ if(slashPos!=-1)
+ lastDir.remove(slashPos+1, lastDir.length());
+}
+
+static const QString & startDir(const QString &d)
+{
+ return d.isEmpty() ? lastDir : d;
+}
+
+QString QFileDialog::getOpenFileName(QWidget *parent, const QString &caption,
+ const QString &dir, const QString &filter,
+ QString *selectedFilter, Options options)
+{
+ QStringList res;
+ QString f(qt2KdeFilter(filter));
+ kqtInit();
+
+ if(openKdeDialog(parent, caption, startDir(dir), &f, OP_FILE_OPEN, res, selectedFilter) && res.count())
+ {
+ kde2QtFilter(filter, selectedFilter);
+ QString fn(res.first());
+
+ storeLastDir(fn);
+ return fn;
+ }
+ return QString();
+}
+
+QString QFileDialog::getSaveFileName(QWidget *parent, const QString &caption,
+ const QString &dir, const QString &filter,
+ QString *selectedFilter, Options options)
+{
+ QStringList res;
+ QString f(qt2KdeFilter(filter));
+ kqtInit();
+
+ if (openKdeDialog(parent, caption, startDir(dir), &f, OP_FILE_SAVE, res, selectedFilter) && res.count())
+ {
+ kde2QtFilter(filter, selectedFilter);
+ QString fn(res.first());
+
+ storeLastDir(fn);
+ return fn;
+ }
+ return QString();
+}
+
+QString QFileDialog::getExistingDirectory(QWidget *parent, const QString &caption,
+ const QString &dir, Options options)
+{
+ QStringList res;
+ QString dummy;
+
+ kqtInit();
+
+ return openKdeDialog(parent, caption, dir, NULL, OP_FOLDER, res, &dummy) && res.count()
+ ? res.first()
+ : QString();
+}
+
+QStringList QFileDialog::getOpenFileNames(QWidget *parent, const QString &caption,
+ const QString &dir, const QString &filter,
+ QString *selectedFilter, Options options)
+{
+ QStringList res;
+ QString f(qt2KdeFilter(filter));
+ kqtInit();
+
+ openKdeDialog(parent, caption, startDir(dir), &f, OP_FILE_OPEN_MULTIPLE, res, selectedFilter);
+
+ if(res.count())
+ {
+ kde2QtFilter(filter, selectedFilter);
+ storeLastDir(res.first());
+ }
+ return res;
+}
+
+#ifdef KQT_OVERLOAD_NON_STATIC_FILEDIALOGS
+static QString getFile(const QString &f)
+{
+ QString d(f);
+
+ int slashPos=d.lastIndexOf('/');
+
+ if(slashPos!=-1)
+ d.remove(0, slashPos+1);
+
+ return d;
+}
+
+int QDialog::exec()
+{
+ int res=QDialog::Rejected;
+
+ if(inherits("QFileDialog"))
+ {
+ QFileDialog *that=(QFileDialog *)this;
+
+ QDir directory(that->directory());
+ QString dir,
+ selectedFilter,
+ file;
+ QStringList files;
+
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
+ switch(that->fileMode())
+ {
+ case QFileDialog::Directory:
+ case QFileDialog::DirectoryOnly:
+ dir=QFileDialog::getExistingDirectory(parentWidget(), windowTitle(), directory.absolutePath(), 0);
+
+ if(!dir.isEmpty())
+ res=QDialog::Accepted;
+ break;
+ case QFileDialog::AnyFile:
+ {
+ QString app(getFile(qApp->argv()[0])),
+ initial(directory.absolutePath());
+/*
+TODO!!!
+ initialFile(getCurrentFileName(that));
+
+ if(!initialFile.isEmpty())
+ initial=initial+QLatin1Char('/')+initialFile;
+*/
+
+ file=QFileDialog::getSaveFileName(parentWidget(), windowTitle(), initial,
+ getFilters(that, "scribus"==app ||
+ "scribus-ng"==app), &selectedFilter, 0);
+ if(!file.isEmpty())
+ res=QDialog::Accepted;
+ break;
+ }
+ case QFileDialog::ExistingFile:
+ file=QFileDialog::getOpenFileName(parentWidget(), windowTitle(), directory.absolutePath(),
+ getFilters(that), &selectedFilter, 0);
+
+ if(!file.isEmpty())
+ res=QDialog::Accepted;
+ break;
+ case QFileDialog::ExistingFiles:
+ files=QFileDialog::getOpenFileNames(parentWidget(), windowTitle(), directory.absolutePath(),
+ getFilters(that), &selectedFilter, 0);
+
+ if(files.count())
+ res=QDialog::Accepted;
+ break;
+ }
+
+ if(QDialog::Accepted==res)
+ {
+ if(file.isEmpty() && files.count())
+ file=files.first();
+ if(dir.isEmpty() && !file.isEmpty())
+ dir=getDir(file);
+ if(!dir.isEmpty())
+ that->setDirectory(dir);
+ if(!selectedFilter.isEmpty())
+ that->selectFilter(selectedFilter);
+ if(!file.isEmpty())
+ that->selectFile(getFile(file));
+
+ if(files.count())
+ {
+ QStringList::ConstIterator it(files.begin()),
+ end(files.end());
+
+ for(; it!=end; ++it)
+ that->selectFile(getFile(*it));
+ }
+ }
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
+ }
+ else
+ {
+ static int (*realFunction)(void *);
+
+ if(!realFunction)
+ realFunction = (int (*)(void *)) dlsym(RTLD_NEXT, KQT_QDIALOG_EXEC);
+ return (int)realFunction(this);
+ }
+
+ return res;
+}
+#endif