diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicssceneindex.cpp | 7 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicssceneindex_p.h | 4 | ||||
-rw-r--r-- | src/gui/graphicsview/qsimplex_p.cpp | 173 | ||||
-rw-r--r-- | src/gui/image/qmovie.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 19 | ||||
-rw-r--r-- | src/gui/util/qdesktopservices_s60.cpp | 5 |
7 files changed, 178 insertions, 36 deletions
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/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 3ea957f..f0404fd 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -265,12 +265,13 @@ bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item, /*! \internal + This function returns the items in ascending order. */ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, QGraphicsSceneIndexIntersector *intersector, QList<QGraphicsItem *> *items, const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, + Qt::ItemSelectionMode mode, qreal parentOpacity) const { Q_ASSERT(item); @@ -326,7 +327,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) continue; recursive_items_helper(child, exposeRect, intersector, items, viewTransform, - mode, order, opacity); + mode, opacity); } } @@ -343,7 +344,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) continue; recursive_items_helper(child, exposeRect, intersector, items, viewTransform, - mode, order, opacity); + mode, opacity); } } } diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 768c724..adebfde 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -138,7 +138,7 @@ public: void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, QGraphicsSceneIndexIntersector *intersector, QList<QGraphicsItem *> *items, const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; + Qt::ItemSelectionMode mode, qreal parentOpacity = 1.0) const; inline void items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector, QList<QGraphicsItem *> *items, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order) const; @@ -156,7 +156,7 @@ inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphi Q_Q(const QGraphicsSceneIndex); const QList<QGraphicsItem *> tli = q->estimateTopLevelItems(rect, Qt::AscendingOrder); for (int i = 0; i < tli.size(); ++i) - recursive_items_helper(tli.at(i), rect, intersector, items, viewTransform, mode, order); + recursive_items_helper(tli.at(i), rect, intersector, items, viewTransform, mode); if (order == Qt::DescendingOrder) { const int n = items->size(); for (int i = 0; i < n / 2; ++i) 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/image/qmovie.cpp b/src/gui/image/qmovie.cpp index 48aee1c..42b8dea 100644 --- a/src/gui/image/qmovie.cpp +++ b/src/gui/image/qmovie.cpp @@ -47,6 +47,10 @@ \ingroup painting + This class is used to show simple animations without sound. If you want + to display video and media content, use the \l{Phonon Module}{Phonon} + multimedia framework instead. + First, create a QMovie object by passing either the name of a file or a pointer to a QIODevice containing an animated image format to QMovie's constructor. You can call isValid() to check if the image data is valid, 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()); } diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp index b78e51b..fd06cf3 100644 --- a/src/gui/util/qdesktopservices_s60.cpp +++ b/src/gui/util/qdesktopservices_s60.cpp @@ -70,7 +70,6 @@ QT_BEGIN_NAMESPACE _LIT(KCacheSubDir, "Cache\\"); _LIT(KSysBin, "\\Sys\\Bin\\"); -_LIT(KTempDir, "\\System\\Temp\\"); _LIT(KBrowserPrefix, "4 " ); _LIT(KFontsDir, "z:\\resource\\Fonts\\"); const TUid KUidBrowser = { 0x10008D39 }; @@ -381,9 +380,7 @@ QString QDesktopServices::storageLocation(StandardLocation type) #endif break; case TempLocation: - path.Append(writableExeDrive().Name()); - path.Append(KTempDir); - //return QDir::tempPath(); break; + return QDir::tempPath(); break; case HomeLocation: path.Append(writableDataRoot()); |