diff options
author | Janne Anttila <janne.anttila@digia.com> | 2009-09-25 11:37:51 (GMT) |
---|---|---|
committer | Janne Anttila <janne.anttila@digia.com> | 2009-09-25 11:37:51 (GMT) |
commit | f33e399b34eda645d2b87b053e887d0b21e8e32a (patch) | |
tree | 1f6f87ef5892a7ff36fbc419a9796159e018cd0f /src | |
parent | 02f161410dce9e2bac89f11d293f811bb224257c (diff) | |
parent | 8a993264ca8bd6273f1d5bb4288d64592d07760f (diff) | |
download | Qt-f33e399b34eda645d2b87b053e887d0b21e8e32a.zip Qt-f33e399b34eda645d2b87b053e887d0b21e8e32a.tar.gz Qt-f33e399b34eda645d2b87b053e887d0b21e8e32a.tar.bz2 |
Merge branch '4.6' of git@scm.dev.troll.no:qt/qt into 4.6
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qglobal.cpp | 34 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_glib.cpp | 133 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_glib_p.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_unix.cpp | 8 | ||||
-rw-r--r-- | src/corelib/statemachine/qabstracttransition.cpp | 6 | ||||
-rw-r--r-- | src/corelib/statemachine/qabstracttransition_p.h | 4 | ||||
-rw-r--r-- | src/corelib/statemachine/qstate.cpp | 4 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qsimplex_p.cpp | 173 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 19 |
10 files changed, 300 insertions, 85 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 4974acf..97362af 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1769,25 +1769,6 @@ static QSysInfo::S60Version cachedS60Version = QSysInfo::S60Version(-1); QSysInfo::S60Version QSysInfo::s60Version() { -# ifdef Q_CC_NOKIAX86 - // For emulator builds. Emulators don't support the trick we use to figure - // out which SDK we are running under, so simply hardcode it there. -# if defined(__SERIES60_31__) - return SV_S60_3_1; - -# elif defined(__S60_32__) - return SV_S60_3_2; - -# elif defined(__S60_50__) - return SV_S60_5_0; - -# else - return SV_S60_Unknown; - -# endif - -# else - // For hardware builds. if (cachedS60Version != -1) return cachedS60Version; @@ -1818,6 +1799,19 @@ QSysInfo::S60Version QSysInfo::s60Version() delete contents; } +# ifdef Q_CC_NOKIAX86 + // Some emulator environments may not contain the version specific .sis files, so + // simply hardcode the version on those environments. +# if defined(__SERIES60_31__) + return cachedS60Version = SV_S60_3_1; +# elif defined(__S60_32__) + return cachedS60Version = SV_S60_3_2; +# elif defined(__S60_50__) + return cachedS60Version = SV_S60_5_0; +# else + return cachedS60Version = SV_S60_Unknown; +# endif +# else return cachedS60Version = SV_S60_Unknown; # endif } @@ -2718,7 +2712,7 @@ int qrand() \since 4.6 \brief The QT_TRID_NOOP macro marks an id for dynamic translation. - + The only purpose of this macro is to provide an anchor for attaching meta data like to qtTrId(). diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 6e457f4..665b73e 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -127,16 +127,11 @@ struct GTimerSource GSource source; QTimerInfoList timerList; QEventLoop::ProcessEventsFlags processEventsFlags; + bool runWithIdlePriority; }; -static gboolean timerSourcePrepare(GSource *source, gint *timeout) +static gboolean timerSourcePrepareHelper(GTimerSource *src, gint *timeout) { - gint dummy; - if (!timeout) - timeout = &dummy; - - GTimerSource *src = reinterpret_cast<GTimerSource *>(source); - timeval tv = { 0l, 0l }; if (!(src->processEventsFlags & QEventLoop::X11ExcludeTimers) && src->timerList.timerWait(tv)) *timeout = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); @@ -146,10 +141,8 @@ static gboolean timerSourcePrepare(GSource *source, gint *timeout) return (*timeout == 0); } -static gboolean timerSourceCheck(GSource *source) +static gboolean timerSourceCheckHelper(GTimerSource *src) { - GTimerSource *src = reinterpret_cast<GTimerSource *>(source); - if (src->timerList.isEmpty() || (src->processEventsFlags & QEventLoop::X11ExcludeTimers)) return false; @@ -160,9 +153,35 @@ static gboolean timerSourceCheck(GSource *source) return true; } +static gboolean timerSourcePrepare(GSource *source, gint *timeout) +{ + gint dummy; + if (!timeout) + timeout = &dummy; + + GTimerSource *src = reinterpret_cast<GTimerSource *>(source); + if (src->runWithIdlePriority) { + if (timeout) + *timeout = -1; + return false; + } + + return timerSourcePrepareHelper(src, timeout); +} + +static gboolean timerSourceCheck(GSource *source) +{ + GTimerSource *src = reinterpret_cast<GTimerSource *>(source); + if (src->runWithIdlePriority) + return false; + return timerSourceCheckHelper(src); +} + static gboolean timerSourceDispatch(GSource *source, GSourceFunc, gpointer) { - (void) reinterpret_cast<GTimerSource *>(source)->timerList.activateTimers(); + GTimerSource *timerSource = reinterpret_cast<GTimerSource *>(source); + timerSource->runWithIdlePriority = true; + (void) timerSource->timerList.activateTimers(); return true; // ??? don't remove, right again? } @@ -175,6 +194,53 @@ static GSourceFuncs timerSourceFuncs = { NULL }; +struct GIdleTimerSource +{ + GSource source; + GTimerSource *timerSource; +}; + +static gboolean idleTimerSourcePrepare(GSource *source, gint *timeout) +{ + GIdleTimerSource *idleTimerSource = reinterpret_cast<GIdleTimerSource *>(source); + GTimerSource *timerSource = idleTimerSource->timerSource; + if (!timerSource->runWithIdlePriority) { + // Yield to the normal priority timer source + if (timeout) + *timeout = -1; + return false; + } + + return timerSourcePrepareHelper(timerSource, timeout); +} + +static gboolean idleTimerSourceCheck(GSource *source) +{ + GIdleTimerSource *idleTimerSource = reinterpret_cast<GIdleTimerSource *>(source); + GTimerSource *timerSource = idleTimerSource->timerSource; + if (!timerSource->runWithIdlePriority) { + // Yield to the normal priority timer source + return false; + } + return timerSourceCheckHelper(timerSource); +} + +static gboolean idleTimerSourceDispatch(GSource *source, GSourceFunc, gpointer) +{ + GTimerSource *timerSource = reinterpret_cast<GIdleTimerSource *>(source)->timerSource; + (void) timerSourceDispatch(&timerSource->source, 0, 0); + return true; +} + +static GSourceFuncs idleTimerSourceFuncs = { + idleTimerSourcePrepare, + idleTimerSourceCheck, + idleTimerSourceDispatch, + NULL, + NULL, + NULL +}; + struct GPostEventSource { GSource source; @@ -235,14 +301,15 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context) g_main_context_ref(mainContext); } else { QCoreApplication *app = QCoreApplication::instance(); - if (app && QThread::currentThread() == app->thread()) { - mainContext = g_main_context_default(); - g_main_context_ref(mainContext); - } else { - mainContext = g_main_context_new(); - } + if (app && QThread::currentThread() == app->thread()) { + mainContext = g_main_context_default(); + g_main_context_ref(mainContext); + } else { + mainContext = g_main_context_new(); + } } + // setup post event source postEventSource = reinterpret_cast<GPostEventSource *>(g_source_new(&postEventSourceFuncs, sizeof(GPostEventSource))); postEventSource->serialNumber = 1; @@ -257,14 +324,21 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context) g_source_set_can_recurse(&socketNotifierSource->source, true); g_source_attach(&socketNotifierSource->source, mainContext); - // setup timerSource + // setup normal and idle timer sources timerSource = reinterpret_cast<GTimerSource *>(g_source_new(&timerSourceFuncs, sizeof(GTimerSource))); (void) new (&timerSource->timerList) QTimerInfoList(); timerSource->processEventsFlags = QEventLoop::AllEvents; + timerSource->runWithIdlePriority = false; g_source_set_can_recurse(&timerSource->source, true); - g_source_set_priority(&timerSource->source, G_PRIORITY_DEFAULT_IDLE); g_source_attach(&timerSource->source, mainContext); + + idleTimerSource = reinterpret_cast<GIdleTimerSource *>(g_source_new(&idleTimerSourceFuncs, + sizeof(GIdleTimerSource))); + idleTimerSource->timerSource = timerSource; + g_source_set_can_recurse(&idleTimerSource->source, true); + g_source_set_priority(&idleTimerSource->source, G_PRIORITY_DEFAULT_IDLE); + g_source_attach(&idleTimerSource->source, mainContext); } QEventDispatcherGlib::QEventDispatcherGlib(QObject *parent) @@ -272,12 +346,9 @@ QEventDispatcherGlib::QEventDispatcherGlib(QObject *parent) { } -QEventDispatcherGlib::QEventDispatcherGlib(GMainContext *mainContext, - QObject *parent) - : QAbstractEventDispatcher(*(new QEventDispatcherGlibPrivate(mainContext)), - parent) -{ -} +QEventDispatcherGlib::QEventDispatcherGlib(GMainContext *mainContext, QObject *parent) + : QAbstractEventDispatcher(*(new QEventDispatcherGlibPrivate(mainContext)), parent) +{ } QEventDispatcherGlib::~QEventDispatcherGlib() { @@ -289,6 +360,9 @@ QEventDispatcherGlib::~QEventDispatcherGlib() g_source_destroy(&d->timerSource->source); g_source_unref(&d->timerSource->source); d->timerSource = 0; + g_source_destroy(&d->idleTimerSource->source); + g_source_unref(&d->idleTimerSource->source); + d->idleTimerSource = 0; // destroy socket notifier source for (int i = 0; i < d->socketNotifierSource->pollfds.count(); ++i) { @@ -324,11 +398,16 @@ bool QEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags) // tell postEventSourcePrepare() and timerSource about any new flags QEventLoop::ProcessEventsFlags savedFlags = d->timerSource->processEventsFlags; d->timerSource->processEventsFlags = flags; - + + if (!(flags & QEventLoop::EventLoopExec)) { + // force timers to be sent at normal priority + d->timerSource->runWithIdlePriority = false; + } + bool result = g_main_context_iteration(d->mainContext, canWait); while (!result && canWait) result = g_main_context_iteration(d->mainContext, canWait); - + d->timerSource->processEventsFlags = savedFlags; if (canWait) diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h index 8dbc44d..6a4e726 100644 --- a/src/corelib/kernel/qeventdispatcher_glib_p.h +++ b/src/corelib/kernel/qeventdispatcher_glib_p.h @@ -98,6 +98,7 @@ protected: struct GPostEventSource; struct GSocketNotifierSource; struct GTimerSource; +struct GIdleTimerSource; class Q_CORE_EXPORT QEventDispatcherGlibPrivate : public QAbstractEventDispatcherPrivate { @@ -108,6 +109,7 @@ public: GPostEventSource *postEventSource; GSocketNotifierSource *socketNotifierSource; GTimerSource *timerSource; + GIdleTimerSource *idleTimerSource; }; QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index a912971..5a0afb8 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -446,10 +446,10 @@ bool QTimerInfoList::timerWait(timeval &tm) // Find first waiting timer not already active QTimerInfo *t = 0; for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) { - if (!(*it)->inTimerEvent) { - t = *it; - break; - } + if (!(*it)->inTimerEvent) { + t = *it; + break; + } } if (!t) diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index a81fe0f..8b858c7 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -187,7 +187,7 @@ QAbstractState *QAbstractTransition::targetState() const Q_D(const QAbstractTransition); if (d->targetStates.isEmpty()) return 0; - return d->targetStates.first(); + return d->targetStates.first().data(); } /*! @@ -211,7 +211,7 @@ QList<QAbstractState*> QAbstractTransition::targetStates() const Q_D(const QAbstractTransition); QList<QAbstractState*> result; for (int i = 0; i < d->targetStates.size(); ++i) { - QAbstractState *target = d->targetStates.at(i); + QAbstractState *target = d->targetStates.at(i).data(); if (target) result.append(target); } @@ -225,7 +225,7 @@ void QAbstractTransition::setTargetStates(const QList<QAbstractState*> &targets) { Q_D(QAbstractTransition); - for (int i=0; i<targets.size(); ++i) { + for (int i = 0; i < targets.size(); ++i) { QAbstractState *target = targets.at(i); if (!target) { qWarning("QAbstractTransition::setTargetStates: target state(s) cannot be null"); diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h index 7465243..5b4df1b 100644 --- a/src/corelib/statemachine/qabstracttransition_p.h +++ b/src/corelib/statemachine/qabstracttransition_p.h @@ -56,7 +56,7 @@ #include <private/qobject_p.h> #include <QtCore/qlist.h> -#include <QtCore/qpointer.h> +#include <QtCore/qsharedpointer.h> QT_BEGIN_NAMESPACE @@ -80,7 +80,7 @@ public: QStateMachine *machine() const; void emitTriggered(); - QList<QPointer<QAbstractState> > targetStates; + QList<QWeakPointer<QAbstractState> > targetStates; #ifndef QT_NO_ANIMATION QList<QAbstractAnimation*> animations; diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index 70026b8..a6e4a57 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -291,9 +291,9 @@ QAbstractTransition *QState::addTransition(QAbstractTransition *transition) } transition->setParent(this); - const QList<QPointer<QAbstractState> > &targets = QAbstractTransitionPrivate::get(transition)->targetStates; + const QList<QWeakPointer<QAbstractState> > &targets = QAbstractTransitionPrivate::get(transition)->targetStates; for (int i = 0; i < targets.size(); ++i) { - QAbstractState *t = targets.at(i); + QAbstractState *t = targets.at(i).data(); if (!t) { qWarning("QState::addTransition: cannot add transition to null state"); return 0; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 7041d58..49aabf5 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -542,7 +542,7 @@ static bool simplifySequentialChunk(Graph<AnchorVertex, AnchorData> *graph, void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) { static bool noSimplification = !qgetenv("QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty(); - if (noSimplification) + if (noSimplification || items.isEmpty()) return; if (graphSimplified[orientation]) diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp index e3a991e..1ba24a3 100644 --- a/src/gui/graphicsview/qsimplex_p.cpp +++ b/src/gui/graphicsview/qsimplex_p.cpp @@ -48,6 +48,32 @@ QT_BEGIN_NAMESPACE +/*! + \class QSimplex + + The QSimplex class is a Linear Programming problem solver based on the two-phase + simplex method. + + It takes a set of QSimplexConstraints as its restrictive constraints and an + additional QSimplexConstraint as its objective function. Then methods to maximize + and minimize the problem solution are provided. + + The two-phase simplex method is based on the following steps: + First phase: + 1.a) Modify the original, complex, and possibly not feasible problem, into a new, + easy to solve problem. + 1.b) Set as the objective of the new problem, a feasible solution for the original + complex problem. + 1.c) Run simplex to optimize the modified problem and check whether a solution for + the original problem exists. + + Second phase: + 2.a) Go back to the original problem with the feasibl (but not optimal) solution + found in the first phase. + 2.b) Set the original objective. + 3.c) Run simplex to optimize the original problem towards its optimal solution. +*/ + QSimplex::QSimplex() : objective(0), rows(0), columns(0), firstArtificial(0), matrix(0) { } @@ -84,15 +110,31 @@ void QSimplex::clearDataStructures() objective = 0; } +/*! + Sets the new constraints in the simplex solver and returns whether the problem + is feasible. + + This method sets the new constraints, normalizes them, creates the simplex matrix + and runs the first simplex phase. +*/ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints) { + //////////////////////////// + // Reset to initial state // + //////////////////////////// clearDataStructures(); if (newConstraints.isEmpty()) return true; // we are ok with no constraints constraints = newConstraints; - // Set Variables direct mapping + /////////////////////////////////////// + // Prepare variables and constraints // + /////////////////////////////////////// + + // Set Variables direct mapping. + // "variables" is a list that provides a stable, indexed list of all variables + // used in this problem. QSet<QSimplexVariable *> variablesSet; for (int i = 0; i < constraints.size(); ++i) variablesSet += \ @@ -100,12 +142,25 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints) variables = variablesSet.toList(); // Set Variables reverse mapping + // We also need to be able to find the index for a given variable, to do that + // we store in each variable its index. for (int i = 0; i < variables.size(); ++i) { // The variable "0" goes at the column "1", etc... variables[i]->index = i + 1; } // Normalize Constraints + // In this step, we prepare the constraints in two ways: + // Firstly, we modify all constraints of type "LessOrEqual" or "MoreOrEqual" + // by the adding slack or surplus variables and making them "Equal" constraints. + // Secondly, we need every single constraint to have a direct, easy feasible + // solution. Constraints that have slack variables are already easy to solve, + // to all the others we add artificial variables. + // + // At the end we modify the constraints as follows: + // - LessOrEqual: SLACK variable is added. + // - Equal: ARTIFICIAL variable is added. + // - More or Equal: ARTIFICIAL and SURPLUS variables are added. int variableIndex = variables.size(); QList <QSimplexVariable *> artificialList; @@ -138,12 +193,18 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints) } } + // All original, slack and surplus have already had its index set + // at this point. We now set the index of the artificial variables + // as to ensure they are at the end of the variable list and therefore + // can be easily removed at the end of this method. firstArtificial = variableIndex + 1; for (int i = 0; i < artificialList.size(); ++i) artificialList[i]->index = ++variableIndex; artificialList.clear(); - // Matrix + ///////////////////////////// + // Fill the Simplex matrix // + ///////////////////////////// // One for each variable plus the Basic and BFS columns (first and last) columns = variableIndex + 2; @@ -188,24 +249,61 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints) setValueAt(i, columns - 1, c->constant); } - // Set temporary objective: -1 * sum_of_artificial_vars + // Set objective for the first-phase Simplex. + // Z = -1 * sum_of_artificial_vars for (int j = firstArtificial; j < columns - 1; ++j) setValueAt(0, j, 1.0); // Maximize our objective (artificial vars go to zero) solveMaxHelper(); + // If there is a solution where the sum of all artificial + // variables is zero, then all of them can be removed and yet + // we will have a feasible (but not optimal) solution for the + // original problem. + // Otherwise, we clean up our structures and report there is + // no feasible solution. if (valueAt(0, columns - 1) != 0.0) { qWarning() << "QSimplex: No feasible solution!"; clearDataStructures(); return false; } - // Remove artificial variables + // Remove artificial variables. We already have a feasible + // solution for the first problem, thus we don't need them + // anymore. clearColumns(firstArtificial, columns - 2); + + #ifdef QT_DEBUG + // Ensure that at the end of the simplex each row should either: + // - Have a positive value on the column associated to its variable, or + // - Have zero values in all columns. + // + // This avoids a regression where restrictions would be lost + // due to randomness in the pivotRowForColumn method. + for (int i = 1; i < rows; ++i) { + int variableIndex = valueAt(i, 0); + if (valueAt(i, variableIndex) > 0) + continue; + + for (int j = 1; j < columns; ++j) { + Q_ASSERT(valueAt(i, j) == 0); + } + } + #endif + return true; } +/*! + \internal + + Run simplex on the current matrix with the current objective. + + This is the iterative method. The matrix lines are combined + as to modify the variable values towards the best solution possible. + The method returns when the matrix is in the optimal state. +*/ void QSimplex::solveMaxHelper() { reducedRowEchelon(); @@ -235,23 +333,21 @@ void QSimplex::clearColumns(int first, int last) void QSimplex::dumpMatrix() { - printf("---- Simplex Matrix ----\n"); + qDebug("---- Simplex Matrix ----\n"); - printf(" "); + QString str(QLatin1String(" ")); for (int j = 0; j < columns; ++j) - printf(" <% 2d >", j); - printf("\n"); - + str += QString::fromAscii(" <%1 >").arg(j, 2); + qDebug("%s", qPrintable(str)); for (int i = 0; i < rows; ++i) { - printf("Row %2d:", i); + str = QString::fromAscii("Row %1:").arg(i, 2); qreal *row = matrix + i * columns; - for (int j = 0; j < columns; ++j) { - printf(" % 2.2f", row[j]); - } - printf("\n"); + for (int j = 0; j < columns; ++j) + str += QString::fromAscii("%1").arg(row[j], 7, 'f', 2); + qDebug("%s", qPrintable(str)); } - printf("------------------------\n\n"); + qDebug("------------------------\n"); } void QSimplex::combineRows(int toIndex, int fromIndex, qreal factor) @@ -292,6 +388,23 @@ int QSimplex::findPivotColumn() return minIndex; } +/*! + \internal + + For a given pivot column, find the pivot row. That is, the row with the + minimum associated "quotient" where: + + - quotient is the division of the value in the last column by the value + in the pivot column. + - rows with value less or equal to zero are ignored + - if two rows have the same quotient, lines are chosen based on the + highest variable index (value in the first column) + + The last condition avoids a bug where artificial variables would be + left behind for the second-phase simplex, and with 'good' + constraints would be removed before it, what would lead to incorrect + results. +*/ int QSimplex::pivotRowForColumn(int column) { qreal min = qreal(999999999999.0); // ### @@ -306,6 +419,8 @@ int QSimplex::pivotRowForColumn(int column) if (quotient < min) { min = quotient; minIndex = i; + } else if ((quotient == min) && (valueAt(i, 0) > valueAt(minIndex, 0))) { + minIndex = i; } } @@ -320,6 +435,12 @@ void QSimplex::reducedRowEchelon() } } +/*! + \internal + + Does one iteration towards a better solution for the problem. + See 'solveMaxHelper'. +*/ bool QSimplex::iterate() { // Find Pivot column @@ -351,7 +472,7 @@ bool QSimplex::iterate() setValueAt(pivotRow, 0, pivotColumn); // dumpMatrix(); - // printf("------------ end of iteration --------------\n"); + // qDebug("------------ end of iteration --------------\n"); return true; } @@ -361,7 +482,13 @@ bool QSimplex::iterate() Both solveMin and solveMax are interfaces to this method. The enum solverFactor admits 2 values: Minimum (-1) and Maximum (+1). - */ + + This method sets the original objective and runs the second phase + Simplex to obtain the optimal solution for the problem. As the internal + simplex solver is only able to _maximize_ objectives, we handle the + minimization case by inverting the original objective and then + maximizing it. +*/ qreal QSimplex::solver(solverFactor factor) { // Remove old objective @@ -381,16 +508,28 @@ qreal QSimplex::solver(solverFactor factor) return factor * valueAt(0, columns - 1); } +/*! + Minimize the original objective. +*/ qreal QSimplex::solveMin() { return solver(Minimum); } +/*! + Maximize the original objective. +*/ qreal QSimplex::solveMax() { return solver(Maximum); } +/*! + \internal + + Reads results from the simplified matrix and saves them in the + "result" member of each QSimplexVariable. +*/ void QSimplex::collectResults() { // All variables are zero unless overridden below. diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 27e8602..8daac42 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -480,7 +480,7 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent) alienWidget = qwidget; S60->mousePressTarget = alienWidget; } - + alienWidget = S60->mousePressTarget; if (alienWidget != S60->lastPointerEventTarget) @@ -600,7 +600,7 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod if (keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down || keyCode == Qt::Key_Select) { /*Explanation about virtualMouseAccel: Tapping an arrow key allows precise pixel positioning - Holding an arrow key down, acceleration is applied to allow cursor + Holding an arrow key down, acceleration is applied to allow cursor to be quickly moved to another part of the screen by key repeats. */ if (S60->virtualMouseLastKey == keyCode) { @@ -668,7 +668,7 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod } } #endif - + Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers); QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode, mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods), @@ -993,13 +993,13 @@ void qt_init(QApplicationPrivate * /* priv */, int) S60->hasTouchscreen = true; S60->virtualMouseRequired = false; } - + if (touch) { QApplicationPrivate::navigationMode = Qt::NavigationModeNone; } else { QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional; } - + #ifndef QT_NO_CURSOR //Check if window server pointer cursors are supported or not #ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS @@ -1063,7 +1063,7 @@ void qt_cleanup() // it dies. delete QApplicationPrivate::inputContext; QApplicationPrivate::inputContext = 0; - + //Change mouse pointer back S60->wsSession().SetPointerCursorMode(EPointerCursorNone); @@ -1383,7 +1383,8 @@ int QApplication::s60ProcessEvent(TWsEvent *event) } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) && !w->d_func()->maybeBackingStore()) { w->d_func()->topData()->backingStore = new QWidgetBackingStore(w); - w->update(); + w->d_func()->invalidateBuffer(w->rect()); + w->repaint(); } return 1; } @@ -1599,7 +1600,7 @@ void QApplicationPrivate::setNavigationMode(Qt::NavigationMode mode) const bool isCursorOn = (mode == Qt::NavigationModeCursorAuto && !S60->hasTouchscreen) || mode == Qt::NavigationModeCursorForceVisible; - + if (!wasCursorOn && isCursorOn) { //Show the cursor, when changing from another mode to cursor mode qt_symbian_set_cursor_visible(true); @@ -1629,7 +1630,7 @@ void QApplication::restoreOverrideCursor() if (qApp->d_func()->cursor_list.isEmpty()) return; qApp->d_func()->cursor_list.removeFirst(); - + if (!qApp->d_func()->cursor_list.isEmpty()) { qt_symbian_setGlobalCursor(qApp->d_func()->cursor_list.first()); } |