summaryrefslogtreecommitdiff
authorzecke <zecke>2005-03-06 23:30:41 (UTC)
committer zecke <zecke>2005-03-06 23:30:41 (UTC)
commitf312f32d624c6198c63890e141e8658bc492cf37 (patch) (side-by-side diff)
treec76e9caad09226113e42e0477d08e13d6388af2e
parent578cc81bc489015320351efd4fabcbed3355ac23 (diff)
downloadopie-f312f32d624c6198c63890e141e8658bc492cf37.zip
opie-f312f32d624c6198c63890e141e8658bc492cf37.tar.gz
opie-f312f32d624c6198c63890e141e8658bc492cf37.tar.bz2
The mainwidget could be deleted before the qpeapplication will be destructed or
the event loop will be left. Use a QGuardedPtr to not save widget coordinates on a not anymore existing mainwidget
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/qpeapplication.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp
index 2bd7cbe..953f9d0 100644
--- a/library/qpeapplication.cpp
+++ b/library/qpeapplication.cpp
@@ -42,408 +42,411 @@
#include <qpalette.h>
#include <qbuffer.h>
#include <qptrdict.h>
#include <qregexp.h>
#include <qdir.h>
#include <qlabel.h>
#include <qdialog.h>
#include <qdragobject.h>
#include <qtextcodec.h>
#include <qevent.h>
#include <qtooltip.h>
#include <qsignal.h>
#include <qmainwindow.h>
#include <qwidgetlist.h>
#include <qpixmapcache.h>
#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
#define QTOPIA_INTERNAL_INITAPP
#include "qpeapplication.h"
#include "qpestyle.h"
#include "styleinterface.h"
#if QT_VERSION >= 0x030000
#include <qstylefactory.h>
#else
#include <qplatinumstyle.h>
#include <qwindowsstyle.h>
#include <qmotifstyle.h>
#include <qmotifplusstyle.h>
#include "lightstyle.h"
#include <qpe/qlibrary.h>
#endif
#include "global.h"
#include "resource.h"
#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
#include "qutfcodec.h"
#endif
#include "config.h"
#include "network.h"
#ifdef QWS
#include "fontmanager.h"
#include "fontdatabase.h"
#endif
#include "alarmserver.h"
#include "applnk.h"
#include "qpemenubar.h"
#include "textcodecinterface.h"
#include "imagecodecinterface.h"
#include <qtopia/qpeglobal.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#ifndef QT_NO_SOUND
#include <sys/soundcard.h>
#endif
#include <backend/rohfeedback.h>
static bool useBigPixmaps = 0;
class HackWidget : public QWidget
{
public:
bool needsOk()
{ return (getWState() & WState_Reserved1 ); }
QRect normalGeometry()
{ return topData()->normalGeometry; };
};
class QPEApplicationData
{
public:
QPEApplicationData ( ) :
presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ),
notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ),
keep_running( true ), qcopQok( false ),
fontFamily( "Vera" ), fontSize( 10 ), smallIconSize( 14 ),
bigIconSize( 32 ), qpe_main_widget( 0 )
{
Config cfg( "qpe" );
cfg.setGroup( "Appearance" );
useBigPixmaps = cfg.readBoolEntry( "useBigPixmaps", false );
fontFamily = cfg.readEntry( "FontFamily", "Vera" );
fontSize = cfg.readNumEntry( "FontSize", 10 );
smallIconSize = cfg.readNumEntry( "SmallIconSize", 14 );
bigIconSize = cfg.readNumEntry( "BigIconSize", 32 );
#ifdef OPIE_WITHROHFEEDBACK
RoH = 0;
#endif
}
int presstimer;
QWidget* presswidget;
QPoint presspos;
#ifdef OPIE_WITHROHFEEDBACK
Opie::Internal::RoHFeedback *RoH;
#endif
bool rightpressed : 1;
bool kbgrabbed : 1;
bool notbusysent : 1;
bool preloaded : 1;
bool forceshow : 1;
bool nomaximize : 1;
bool keep_running : 1;
bool qcopQok : 1;
QCString fontFamily;
int fontSize;
int smallIconSize;
int bigIconSize;
QString appName;
struct QCopRec
{
QCopRec( const QCString &ch, const QCString &msg,
const QByteArray &d ) :
channel( ch ), message( msg ), data( d )
{ }
QCString channel;
QCString message;
QByteArray data;
};
- QWidget* qpe_main_widget;
+ QGuardedPtr<QWidget> qpe_main_widget;
QGuardedPtr<QWidget> lastraised;
QQueue<QCopRec> qcopq;
QString styleName;
QString decorationName;
void enqueueQCop( const QCString &ch, const QCString &msg,
const QByteArray &data )
{
qcopq.enqueue( new QCopRec( ch, msg, data ) );
}
void sendQCopQ()
{
if (!qcopQok )
return;
QCopRec * r;
while((r=qcopq.dequeue())) {
// remove from queue before sending...
// event loop can come around again before getting
// back from sendLocally
#ifndef QT_NO_COP
QCopChannel::sendLocally( r->channel, r->message, r->data );
#endif
delete r;
}
}
static void show_mx(QWidget* mw, bool nomaximize, QString &strName) {
if ( mw->inherits("QMainWindow") || mw->isA("QMainWindow") )
{
( ( QMainWindow* ) mw )->setUsesBigPixmaps( useBigPixmaps );
}
QPoint p;
QSize s;
bool max;
if ( mw->isVisible() ) {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
}
mw->raise();
} else {
if ( mw->layout() && mw->inherits("QDialog") ) {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
if ( max && !nomaximize ) {
mw->showMaximized();
} else {
mw->show();
}
} else {
QPEApplication::showDialog((QDialog*)mw,nomaximize);
}
} else {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
} else { //no stored rectangle, make an estimation
int x = (qApp->desktop()->width()-mw->frameGeometry().width())/2;
int y = (qApp->desktop()->height()-mw->frameGeometry().height())/2;
mw->move( QMAX(x,0), QMAX(y,0) );
#ifdef Q_WS_QWS
if ( !nomaximize )
mw->showMaximized();
#endif
}
if ( max && !nomaximize )
mw->showMaximized();
else
mw->show();
}
}
}
static bool read_widget_rect(const QString &app, bool &maximized, QPoint &p, QSize &s)
{
maximized = TRUE;
// 350 is the trigger in qwsdefaultdecoration for providing a resize button
if ( qApp->desktop()->width() <= 350 )
return FALSE;
Config cfg( "qpe" );
cfg.setGroup("ApplicationPositions");
QString str = cfg.readEntry( app, QString::null );
QStringList l = QStringList::split(",", str);
if ( l.count() == 5) {
p.setX( l[0].toInt() );
p.setY( l[1].toInt() );
s.setWidth( l[2].toInt() );
s.setHeight( l[3].toInt() );
maximized = l[4].toInt();
return TRUE;
}
return FALSE;
}
static bool validate_widget_size(const QWidget *w, QPoint &p, QSize &s)
{
#ifndef Q_WS_QWS
QRect qt_maxWindowRect = qApp->desktop()->geometry();
#endif
int maxX = qt_maxWindowRect.width();
int maxY = qt_maxWindowRect.height();
int wWidth = s.width() + ( w->frameGeometry().width() - w->geometry().width() );
int wHeight = s.height() + ( w->frameGeometry().height() - w->geometry().height() );
// total window size is not allowed to be larger than desktop window size
if ( ( wWidth >= maxX ) && ( wHeight >= maxY ) )
return FALSE;
if ( wWidth > maxX ) {
s.setWidth( maxX - (w->frameGeometry().width() - w->geometry().width() ) );
wWidth = maxX;
}
if ( wHeight > maxY ) {
s.setHeight( maxY - (w->frameGeometry().height() - w->geometry().height() ) );
wHeight = maxY;
}
// any smaller than this and the maximize/close/help buttons will be overlapping
if ( wWidth < 80 || wHeight < 60 )
return FALSE;
if ( p.x() < 0 )
p.setX(0);
if ( p.y() < 0 )
p.setY(0);
if ( p.x() + wWidth > maxX )
p.setX( maxX - wWidth );
if ( p.y() + wHeight > maxY )
p.setY( maxY - wHeight );
return TRUE;
}
static void store_widget_rect(QWidget *w, QString &app)
{
+ if( !w )
+ return;
+
// 350 is the trigger in qwsdefaultdecoration for providing a resize button
if ( qApp->desktop()->width() <= 350 )
return;
// we use these to map the offset of geometry and pos. ( we can only use normalGeometry to
// get the non-maximized version, so we have to do it the hard way )
int offsetX = w->x() - w->geometry().left();
int offsetY = w->y() - w->geometry().top();
QRect r;
if ( w->isMaximized() )
r = ( (HackWidget *) w)->normalGeometry();
else
r = w->geometry();
// Stores the window placement as pos(), size() (due to the offset mapping)
Config cfg( "qpe" );
cfg.setGroup("ApplicationPositions");
QString s;
s.sprintf("%d,%d,%d,%d,%d", r.left() + offsetX, r.top() + offsetY, r.width(), r.height(), w->isMaximized() );
cfg.writeEntry( app, s );
}
static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ )
{
/*
// This works but disable it for now until it is safe to apply
// What is does is scan the .desktop files of all the apps for
// the applnk that has the corresponding argv[0] as this program
// then it uses the name stored in the .desktop file as the caption
// for the main widget. This saves duplicating translations for
// the app name in the program and in the .desktop files.
AppLnkSet apps( appsPath );
QList<AppLnk> appsList = apps.children();
for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) {
if ( (*it)->exec() == appName ) {
mw->setCaption( (*it)->name() );
return TRUE;
}
}
*/
return FALSE;
}
void show(QWidget* mw, bool nomax)
{
setWidgetCaptionFromAppName( mw, appName, QPEApplication::qpeDir() + "apps" );
nomaximize = nomax;
qpe_main_widget = mw;
qcopQok = TRUE;
#ifndef QT_NO_COP
sendQCopQ();
#endif
if ( preloaded ) {
if (forceshow)
show_mx(mw, nomax, appName);
}
else if ( keep_running ) {
show_mx(mw, nomax, appName);
}
}
void loadTextCodecs()
{
QString path = QPEApplication::qpeDir() + "plugins/textcodecs";
#ifdef Q_OS_MACX
QDir dir( path, "lib*.dylib" );
#else
QDir dir( path, "lib*.so" );
#endif
QStringList list;
if ( dir. exists ( ))
list = dir.entryList();
QStringList::Iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
TextCodecInterface *iface = 0;
QLibrary *lib = new QLibrary( path + "/" + *it );
if ( lib->queryInterface( IID_QtopiaTextCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
QValueList<int> mibs = iface->mibEnums();
for (QValueList<int>::ConstIterator i = mibs.begin(); i != mibs.end(); ++i) {
(void)iface->createForMib(*i);
// ### it exists now; need to remember if we can delete it
}
}
else {
lib->unload();
delete lib;
}
}
}
void loadImageCodecs()
{
QString path = QPEApplication::qpeDir() + "plugins/imagecodecs";
#ifdef Q_OS_MACX
QDir dir( path, "lib*.dylib" );
#else
QDir dir( path, "lib*.so" );
#endif
QStringList list;
if ( dir. exists ( ))
list = dir.entryList();
QStringList::Iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
ImageCodecInterface *iface = 0;
QLibrary *lib = new QLibrary( path + "/" + *it );
if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
QStringList formats = iface->keys();
for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) {
(void)iface->installIOHandler(*i);
// ### it exists now; need to remember if we can delete it
}
}
else {
lib->unload();
delete lib;
}
}
}
};
class ResourceMimeFactory : public QMimeSourceFactory
{