summaryrefslogtreecommitdiff
path: root/library
authorllornkcor <llornkcor>2004-04-25 07:56:02 (UTC)
committer llornkcor <llornkcor>2004-04-25 07:56:02 (UTC)
commit73f0c227fc94bc4dea12e4eb2384bdff2e9561eb (patch) (side-by-side diff)
treec33525271239fbf69e5daf9223beaa5dd28e0bb6 /library
parentcf9cab31dc8a46d3a2d74931b2a428ca87eed0a9 (diff)
downloadopie-73f0c227fc94bc4dea12e4eb2384bdff2e9561eb.zip
opie-73f0c227fc94bc4dea12e4eb2384bdff2e9561eb.tar.gz
opie-73f0c227fc94bc4dea12e4eb2384bdff2e9561eb.tar.bz2
fix nonmaximized apps, and make the state and position persistent. ported from Qtopia 1.7 :)
Diffstat (limited to 'library') (more/less context) (ignore whitespace changes)
-rw-r--r--library/qpeapplication.cpp271
1 files changed, 240 insertions, 31 deletions
diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp
index 755fb19..90cd5f1 100644
--- a/library/qpeapplication.cpp
+++ b/library/qpeapplication.cpp
@@ -93,12 +93,21 @@
#include <sys/ioctl.h>
#ifndef QT_NO_SOUND
#include <sys/soundcard.h>
#endif
#include "qt_override_p.h"
+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 ),
@@ -115,16 +124,16 @@ public:
bool kbgrabbed : 1;
bool notbusysent : 1;
bool preloaded : 1;
bool forceshow : 1;
bool nomaximize : 1;
bool keep_running : 1;
- bool qcopQok : 1;
+ bool qcopQok : 1;
- QStringList langs;
+ QStringList langs;
QString appName;
struct QCopRec
{
QCopRec( const QCString &ch, const QCString &msg,
const QByteArray &d ) :
channel( ch ), message( msg ), data( d )
@@ -160,38 +169,234 @@ public:
QCopChannel::sendLocally( r->channel, r->message, r->data );
#endif
delete r;
}
}
- static void show_mx(QWidget* mw, bool nomaximize, const QString & = QString::null )
+
+ static void show_mx(QWidget* mw, bool nomaximize, QString &strName/* = QString::null */)
{
+ if ( mw->isVisible() ) {
+ mw->raise();
+ } else {
+ QPoint p;
+ QSize s;
+
+ if ( mw->layout() && mw->inherits("QDialog") ) {
+ bool max;
+ 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 {
+ qpe_show_dialog((QDialog*)mw,nomaximize);
+ }
+ } else {
+ bool max;
+ 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();
+ }
+ }
+ }
+// // ugly hack, remove that later after finding a sane solution
+// // Addendum: Only Sharp currently has models with high resolution but (physically) small displays,
+// // so this is only useful if QT_QWS_SIMPAD is NOT defined. E.g. SIMpad has 800x600 but has
+// // a (physically) large enough display to use the small icons
+// #if defined(OPIE_HIGH_RES_SMALL_PHY)
+// if ( QPEApplication::desktop() ->width() >= 600 && ( mw->inherits("QMainWindow") || mw->isA("QMainWindow") ) ) {
+// ( ( QMainWindow* ) mw )->setUsesBigPixmaps( true );
+// }
+// #endif
+
+// if ( mw->layout() && mw->inherits("QDialog") ) {
+// QPEApplication::showDialog((QDialog*)mw, nomaximize);
+// }
+// else {
+// #ifdef Q_WS_QWS
+// if ( !nomaximize ) {
+// qDebug("QDialog special case XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+// mw->showMaximized();
+// // QPEApplication::showWidget( mw, !nomaximize );
+// } else
+// #endif
+// mw->show();
+// }
+// }
+
+
+static void qpe_show_dialog( QDialog* d, bool nomax )
+{
+ QSize sh = d->sizeHint();
+ int w = QMAX(sh.width(),d->width());
+ int h = QMAX(sh.height(),d->height());
- // ugly hack, remove that later after finding a sane solution
- // Addendum: Only Sharp currently has models with high resolution but (physically) small displays,
- // so this is only useful if QT_QWS_SIMPAD is NOT defined. E.g. SIMpad has 800x600 but has
- // a (physically) large enough display to use the small icons
-#if defined(OPIE_HIGH_RES_SMALL_PHY)
- if ( QPEApplication::desktop() ->width() >= 600 && ( mw->inherits("QMainWindow") || mw->isA("QMainWindow") ) ) {
- ( ( QMainWindow* ) mw )->setUsesBigPixmaps( true );
- }
+ if ( d->parentWidget() && !d->parentWidget()->topLevelWidget()->isMaximized() )
+ nomax = TRUE;
+
+#ifndef Q_WS_QWS
+ QSize s(qApp->desktop()->width(), qApp->desktop()->height() );
+#else
+ QSize s(qt_maxWindowRect.width(), qt_maxWindowRect.height() );
#endif
- if ( mw->layout() && mw->inherits("QDialog") ) {
- QPEApplication::showDialog((QDialog*)mw, nomaximize);
- }
- else {
-#ifdef Q_WS_QWS
- if ( !nomaximize )
- mw->showMaximized();
- else
+ int maxX = s.width() - (d->frameGeometry().width() - d->geometry().width());
+ int maxY = s.height() - (d->frameGeometry().height() - d->geometry().height());
+
+ if ( (w >= maxX && h >= maxY) || ( (!nomax) && ( w > s.width()*3/4 || h > s.height()*3/4 ) ) ) {
+ d->showMaximized();
+ } else {
+ // try centering the dialog around its parent
+ QPoint p(0,0);
+ if ( d->parentWidget() ) {
+ QPoint pp = d->parentWidget()->mapToGlobal( QPoint(0,0) );
+ p = QPoint( pp.x() + d->parentWidget()->width()/2,
+ pp.y() + d->parentWidget()->height()/ 2 );
+ } else {
+ p = QPoint( maxX/2, maxY/2 );
+ }
+
+ p = QPoint( p.x() - w/2, p.y() - h/2 );
+// qDebug("p(x,y) is %d %d", p.x(), p.y() );
+
+ if ( w >= maxX ) {
+ if ( p.y() < 0 )
+ p.setY(0);
+ if ( p.y() + h > maxY )
+ p.setY( maxY - h);
+
+ d->resize(maxX, h);
+ d->move(0, p.y() );
+ } else if ( h >= maxY ) {
+ if ( p.x() < 0 )
+ p.setX(0);
+ if ( p.x() + w > maxX )
+ p.setX( maxX - w);
+
+ d->resize(w, maxY);
+ d->move(p.x(),0);
+ } else {
+ d->resize(w, h);
+ }
+
+ d->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() );
- mw->show();
- }
+ // 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)
+ {
+ // 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
@@ -223,16 +428,16 @@ public:
sendQCopQ();
#endif
if ( preloaded ) {
if (forceshow)
- show_mx(mw, nomax);
+ show_mx(mw, nomax, appName);
}
else if ( keep_running ) {
- show_mx(mw, nomax);
+ show_mx(mw, nomax, appName);
}
}
void loadTextCodecs()
{
QString path = QPEApplication::qpeDir() + "/plugins/textcodecs";
@@ -860,20 +1065,20 @@ void QPEApplication::mapToDefaultAction( QWSKeyEvent * ke, int key )
#ifdef QWS
ke->simpleData.keycode = key;
#endif
}
-class HackWidget : public QWidget
-{
-public:
- bool needsOk()
- {
- return ( getWState() & WState_Reserved1 );
- }
-};
+// class HackWidget : public QWidget
+// {
+// public:
+// bool needsOk()
+// {
+// return ( getWState() & WState_Reserved1 );
+// }
+// };
/*!
\internal
*/
#ifdef QWS
@@ -1975,12 +2180,14 @@ void QPEApplication::tryQuit()
{
QCopEnvelope e( "QPE/System", "closing(QString)" );
e << d->appName;
}
#endif
+ if ( d->keep_running )
+ d->store_widget_rect(d->qpe_main_widget, d->appName);
processEvents();
quit();
}
/*!
@@ -2000,12 +2207,14 @@ void QPEApplication::installTranslation( const QString& baseName ) {
User initiated quit. Makes the window 'Go Away'. If preloaded this means
hiding the window. If not it means quitting the application.
As this is user initiated we don't need to check state.
*/
void QPEApplication::hideOrQuit()
{
+ if ( d->keep_running )
+ d->store_widget_rect(d->qpe_main_widget, d->appName);
processEvents();
// If we are a preloaded application we don't actually quit, so emit
// a System message indicating we're quasi-closing.
if ( d->preloaded && d->qpe_main_widget )
#ifndef QT_NO_COP