summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-4.7.03
-rw-r--r--src/corelib/tools/qpoint.cpp2
-rw-r--r--src/gui/dialogs/qdialog.cpp7
-rw-r--r--src/gui/dialogs/qmessagebox.cpp4
-rw-r--r--src/gui/image/qpnghandler.cpp137
-rw-r--r--src/gui/text/qtextcontrol.cpp4
-rw-r--r--src/gui/text/qtextdocument.cpp17
-rw-r--r--src/gui/text/qtextdocument.h7
-rw-r--r--src/gui/text/qtextdocument_p.cpp62
-rw-r--r--src/gui/text/qtextdocument_p.h3
-rw-r--r--src/gui/widgets/qdockarealayout.cpp62
-rw-r--r--src/gui/widgets/qdockarealayout_p.h5
-rw-r--r--src/gui/widgets/qlabel.cpp4
-rw-r--r--src/gui/widgets/qlineedit.cpp6
-rw-r--r--src/gui/widgets/qmainwindow.cpp13
-rw-r--r--src/opengl/qglextensions.cpp6
-rw-r--r--src/opengl/qglextensions_p.h46
-rw-r--r--src/opengl/qglshaderprogram.cpp162
-rw-r--r--src/opengl/qglshaderprogram.h24
-rw-r--r--tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp10
-rw-r--r--tests/auto/qlabel/tst_qlabel.cpp24
-rw-r--r--tests/auto/qlineedit/tst_qlineedit.cpp23
-rw-r--r--tests/auto/qmainwindow/tst_qmainwindow.cpp40
-rw-r--r--tests/auto/qtextedit/tst_qtextedit.cpp22
-rw-r--r--tools/assistant/tools/assistant/assistant.pro2
-rw-r--r--tools/assistant/tools/assistant/centralwidget.cpp250
-rw-r--r--tools/assistant/tools/assistant/centralwidget.h74
-rw-r--r--tools/assistant/tools/assistant/findwidget.cpp233
-rw-r--r--tools/assistant/tools/assistant/findwidget.h101
-rw-r--r--tools/assistant/tools/assistant/helpenginewrapper.cpp22
30 files changed, 948 insertions, 427 deletions
diff --git a/dist/changes-4.7.0 b/dist/changes-4.7.0
index 92f5244..3504763 100644
--- a/dist/changes-4.7.0
+++ b/dist/changes-4.7.0
@@ -24,6 +24,9 @@ General Improvements
- Documentation and Examples
+- Support for the GL_EXT_geometry_shader4, aka Geometry Shaders, was added
+ to QGLShaderProgram.
+
Third party components
----------------------
diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp
index d60087f..9850ee7 100644
--- a/src/corelib/tools/qpoint.cpp
+++ b/src/corelib/tools/qpoint.cpp
@@ -374,7 +374,7 @@ QDebug operator<<(QDebug dbg, const QPoint &p) {
QDebug operator<<(QDebug d, const QPointF &p)
{
d.nospace() << "QPointF(" << p.x() << ", " << p.y() << ')';
- return d;
+ return d.space();
}
#endif
diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp
index 9ff2ad8..fb0dba4 100644
--- a/src/gui/dialogs/qdialog.cpp
+++ b/src/gui/dialogs/qdialog.cpp
@@ -648,13 +648,14 @@ void QDialog::contextMenuEvent(QContextMenuEvent *e)
while (w && w->whatsThis().size() == 0 && !w->testAttribute(Qt::WA_CustomWhatsThis))
w = w->isWindow() ? 0 : w->parentWidget();
if (w) {
- QMenu p(this);
- QAction *wt = p.addAction(tr("What's This?"));
- if (p.exec(e->globalPos()) == wt) {
+ QWeakPointer<QMenu> p = new QMenu(this);
+ QAction *wt = p.data()->addAction(tr("What's This?"));
+ if (p.data()->exec(e->globalPos()) == wt) {
QHelpEvent e(QEvent::WhatsThis, w->rect().center(),
w->mapToGlobal(w->rect().center()));
QApplication::sendEvent(w, &e);
}
+ delete p.data();
}
#endif
}
diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp
index d1b2e3f..ed437ff 100644
--- a/src/gui/dialogs/qmessagebox.cpp
+++ b/src/gui/dialogs/qmessagebox.cpp
@@ -92,8 +92,8 @@ public:
{
#ifndef QT_NO_CONTEXTMENU
QMenu *menu = createStandardContextMenu();
- menu->exec(e->globalPos());
- delete menu;
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(e->globalPos());
#else
Q_UNUSED(e);
#endif
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index d5406cb..dd31834 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -50,8 +50,13 @@
#include <qvariant.h>
#include <qvector.h>
+#ifdef QT_USE_BUNDLED_LIBPNG
+#include <../../3rdparty/libpng/png.h>
+#include <../../3rdparty/libpng/pngconf.h>
+#else
#include <png.h>
#include <pngconf.h>
+#endif
#ifdef Q_OS_WINCE
#define CALLBACK_CALL_TYPE __cdecl
@@ -162,11 +167,16 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float scre
png_uint_32 height;
int bit_depth;
int color_type;
+ png_bytep trans_alpha = 0;
+ png_color_16p trans_color_p = 0;
+ int num_trans;
+ png_colorp palette = 0;
+ int num_palette;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
if (color_type == PNG_COLOR_TYPE_GRAY) {
// Black & White or 8-bit grayscale
- if (bit_depth == 1 && info_ptr->channels == 1) {
+ if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
png_set_invert_mono(png_ptr);
png_read_update_info(png_ptr, info_ptr);
if (image.size() != QSize(width, height) || image.format() != QImage::Format_Mono) {
@@ -207,20 +217,16 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float scre
int c = i*255/(ncols-1);
image.setColor(i, qRgba(c,c,c,0xff));
}
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
-#if PNG_LIBPNG_VER_MAJOR < 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR < 4)
- const int g = info_ptr->trans_values.gray;
-#else
- const int g = info_ptr->trans_color.gray;
-#endif
+ if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) {
+ const int g = trans_color_p->gray;
if (g < ncols) {
image.setColor(g, 0);
}
}
}
} else if (color_type == PNG_COLOR_TYPE_PALETTE
- && png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)
- && info_ptr->num_palette <= 256)
+ && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)
+ && num_palette <= 256)
{
// 1-bit and 8-bit color
if (bit_depth != 1)
@@ -233,29 +239,26 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float scre
if (image.isNull())
return;
}
- image.setColorCount(info_ptr->num_palette);
+ png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
+ image.setColorCount(num_palette);
int i = 0;
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- while (i < info_ptr->num_trans) {
+ if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) {
+ while (i < num_trans) {
image.setColor(i, qRgba(
- info_ptr->palette[i].red,
- info_ptr->palette[i].green,
- info_ptr->palette[i].blue,
-#if PNG_LIBPNG_VER_MAJOR < 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR < 4)
- info_ptr->trans[i]
-#else
- info_ptr->trans_alpha[i]
-#endif
+ palette[i].red,
+ palette[i].green,
+ palette[i].blue,
+ trans_alpha[i]
)
);
i++;
}
}
- while (i < info_ptr->num_palette) {
+ while (i < num_palette) {
image.setColor(i, qRgba(
- info_ptr->palette[i].red,
- info_ptr->palette[i].green,
- info_ptr->palette[i].blue,
+ palette[i].red,
+ palette[i].green,
+ palette[i].blue,
0xff
)
);
@@ -531,33 +534,36 @@ QImage::Format QPngHandlerPrivate::readImageFormat()
QImage::Format format = QImage::Format_Invalid;
png_uint_32 width, height;
int bit_depth, color_type;
- if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) {
+ png_colorp palette;
+ int num_palette;
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
+ if (color_type == PNG_COLOR_TYPE_GRAY) {
// Black & White or 8-bit grayscale
- if (info_ptr->bit_depth == 1 && info_ptr->channels == 1) {
+ if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
format = QImage::Format_Mono;
- } else if (info_ptr->bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
format = QImage::Format_ARGB32;
} else {
format = QImage::Format_Indexed8;
}
- } else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE
- && png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)
- && info_ptr->num_palette <= 256)
+ } else if (color_type == PNG_COLOR_TYPE_PALETTE
+ && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)
+ && num_palette <= 256)
{
// 1-bit and 8-bit color
- if (info_ptr->bit_depth != 1)
+ if (bit_depth != 1)
png_set_packing(png_ptr);
png_read_update_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
} else {
// 32-bit
- if (info_ptr->bit_depth == 16)
+ if (bit_depth == 16)
png_set_strip_16(png_ptr);
format = QImage::Format_ARGB32;
// Only add filler if no alpha, or we can get 5 channel data.
- if (!(info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ if (!(color_type & PNG_COLOR_MASK_ALPHA)
&& !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
// We want 4 bytes, but it isn't an alpha channel
format = QImage::Format_RGB32;
@@ -648,7 +654,7 @@ static void set_text(const QImage &image, png_structp png_ptr, png_infop info_pt
text_ptr[i].text = qstrdup(value.constData());
text_ptr[i].text_length = 0;
text_ptr[i].itxt_length = value.size();
- text_ptr[i].lang = "UTF-8";
+ text_ptr[i].lang = const_cast<char*>("UTF-8");
text_ptr[i].lang_key = qstrdup(it.key().toUtf8().constData());
#endif
++i;
@@ -735,64 +741,51 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in,
png_set_compression_level(png_ptr, quality);
}
- if (gamma != 0.0) {
- png_set_gAMA(png_ptr, info_ptr, 1.0/gamma);
- }
-
png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn);
- info_ptr->channels =
- (image.depth() == 32)
- ? (image.format() == QImage::Format_RGB32 ? 3 : 4)
- : 1;
-
png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
image.depth() == 1 ? 1 : 8 /* per channel */,
image.depth() == 32
? image.format() == QImage::Format_RGB32
? PNG_COLOR_TYPE_RGB
: PNG_COLOR_TYPE_RGB_ALPHA
- : PNG_COLOR_TYPE_PALETTE, 0, 0, 0);
+ : PNG_COLOR_TYPE_PALETTE, 0, 0, 0); // also sets #channels
+ if (gamma != 0.0) {
+ png_set_gAMA(png_ptr, info_ptr, 1.0/gamma);
+ }
- //png_set_sBIT(png_ptr, info_ptr, 8);
- info_ptr->sig_bit.red = 8;
- info_ptr->sig_bit.green = 8;
- info_ptr->sig_bit.blue = 8;
+ png_color_8 sig_bit;
+ sig_bit.red = 8;
+ sig_bit.green = 8;
+ sig_bit.blue = 8;
+ sig_bit.alpha = image.hasAlphaChannel() ? 8 : 0;
+ png_set_sBIT(png_ptr, info_ptr, &sig_bit);
if (image.format() == QImage::Format_MonoLSB)
png_set_packswap(png_ptr);
- png_colorp palette = 0;
- png_bytep copy_trans = 0;
if (image.colorCount()) {
// Paletted
- int num_palette = image.colorCount();
- palette = new png_color[num_palette];
- png_set_PLTE(png_ptr, info_ptr, palette, num_palette);
- int* trans = new int[num_palette];
+ int num_palette = qMin(256, image.colorCount());
+ png_color palette[256];
+ png_byte trans[256];
int num_trans = 0;
for (int i=0; i<num_palette; i++) {
- QRgb rgb=image.color(i);
- info_ptr->palette[i].red = qRed(rgb);
- info_ptr->palette[i].green = qGreen(rgb);
- info_ptr->palette[i].blue = qBlue(rgb);
- trans[i] = rgb >> 24;
+ QRgb rgba=image.color(i);
+ palette[i].red = qRed(rgba);
+ palette[i].green = qGreen(rgba);
+ palette[i].blue = qBlue(rgba);
+ trans[i] = qAlpha(rgba);
if (trans[i] < 255) {
num_trans = i+1;
}
}
+ png_set_PLTE(png_ptr, info_ptr, palette, num_palette);
+
if (num_trans) {
- copy_trans = new png_byte[num_trans];
- for (int i=0; i<num_trans; i++)
- copy_trans[i] = trans[i];
- png_set_tRNS(png_ptr, info_ptr, copy_trans, num_trans, 0);
+ png_set_tRNS(png_ptr, info_ptr, trans, num_trans, 0);
}
- delete [] trans;
- }
-
- if (image.format() != QImage::Format_RGB32) {
- info_ptr->sig_bit.alpha = 8;
}
// Swap ARGB to RGBA (normal PNG format) before saving on
@@ -868,11 +861,6 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in,
png_write_end(png_ptr, info_ptr);
frames_written++;
- if (palette)
- delete [] palette;
- if (copy_trans)
- delete [] copy_trans;
-
png_destroy_write_struct(&png_ptr, &info_ptr);
return true;
@@ -958,7 +946,8 @@ QVariant QPngHandler::option(ImageOption option) const
else if (option == Description)
return d->description;
else if (option == Size)
- return QSize(d->info_ptr->width, d->info_ptr->height);
+ return QSize(png_get_image_width(d->png_ptr, d->info_ptr),
+ png_get_image_height(d->png_ptr, d->info_ptr));
else if (option == ImageFormat)
return d->readImageFormat();
return 0;
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index b42f95a..f345cd1 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -1764,8 +1764,8 @@ void QTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPoint
QMenu *menu = q->createStandardContextMenu(docPos, contextWidget);
if (!menu)
return;
- menu->exec(screenPos);
- delete menu;
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(screenPos);
#endif
}
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index b8c9b94..80931c9 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -436,6 +436,23 @@ void QTextDocument::redo(QTextCursor *cursor)
}
/*!
+ \since 4.7
+ Clears the specified stacks.
+
+ This method clears any commands on the undo stack, the redo stack, or both (the
+ default). If any commands got cleared, the appropriate signals
+ (\a QTextDocument::undoAvailable or \a QTextDocument::redoAvailable) get
+ emitted.
+
+ \sa QTextDocument::undoAvailable QTextDocument::redoAvailable
+*/
+void QTextDocument::clearUndoRedoStacks(Stacks stacksToClear)
+{
+ Q_D(QTextDocument);
+ d->clearUndoRedoStacks(stacksToClear, true);
+}
+
+/*!
\overload
*/
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index b5bcb41..0140772 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -256,6 +256,13 @@ public:
void undo(QTextCursor *cursor);
void redo(QTextCursor *cursor);
+ enum Stacks {
+ UndoStack = 0x01,
+ RedoStack = 0x02,
+ UndoAndRedoStacks = UndoStack | RedoStack
+ };
+ void clearUndoRedoStacks(Stacks historyToClear = UndoAndRedoStacks);
+
int maximumBlockCount() const;
void setMaximumBlockCount(int maximum);
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 372b9dc..e2fdf0e 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -260,7 +260,7 @@ void QTextDocumentPrivate::clear()
title.clear();
undoState = 0;
- truncateUndoStack();
+ clearUndoRedoStacks(QTextDocument::RedoStack);
text = QString();
unreachableCharacterCount = 0;
modifiedState = 0;
@@ -292,7 +292,7 @@ QTextDocumentPrivate::~QTextDocumentPrivate()
cursors.clear();
undoState = 0;
undoEnabled = true;
- truncateUndoStack();
+ clearUndoRedoStacks(QTextDocument::RedoStack);
}
void QTextDocumentPrivate::setLayout(QAbstractTextDocumentLayout *layout)
@@ -1027,7 +1027,7 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c)
if (!undoEnabled)
return;
if (undoState < undoStack.size())
- truncateUndoStack();
+ clearUndoRedoStacks(QTextDocument::RedoStack);
if (!undoStack.isEmpty() && modified) {
QTextUndoCommand &last = undoStack[undoState - 1];
@@ -1050,26 +1050,46 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c)
emit document()->undoCommandAdded();
}
-void QTextDocumentPrivate::truncateUndoStack()
+void QTextDocumentPrivate::clearUndoRedoStacks(QTextDocument::Stacks stacksToClear,
+ bool emitSignals)
{
- if (undoState == undoStack.size())
- return;
-
- for (int i = undoState; i < undoStack.size(); ++i) {
- QTextUndoCommand c = undoStack[i];
- if (c.command & QTextUndoCommand::Removed) {
- // ########
-// QTextFragment *f = c.fragment_list;
-// while (f) {
-// QTextFragment *n = f->right;
-// delete f;
-// f = n;
-// }
- } else if (c.command & QTextUndoCommand::Custom) {
- delete c.custom;
+ bool undoCommandsAvailable = undoState != 0;
+ bool redoCommandsAvailable = undoState != undoStack.size();
+ if (stacksToClear == QTextDocument::UndoStack && undoCommandsAvailable) {
+ for (int i = 0; i < undoState; ++i) {
+ QTextUndoCommand c = undoStack[undoState];
+ if (c.command & QTextUndoCommand::Custom)
+ delete c.custom;
+ }
+ undoStack.remove(0, undoState);
+ undoStack.resize(undoStack.size() - undoState);
+ undoState = 0;
+ if (emitSignals)
+ emitUndoAvailable(false);
+ } else if (stacksToClear == QTextDocument::RedoStack
+ && redoCommandsAvailable) {
+ for (int i = undoState; i < undoStack.size(); ++i) {
+ QTextUndoCommand c = undoStack[i];
+ if (c.command & QTextUndoCommand::Custom)
+ delete c.custom;
+ }
+ undoStack.resize(undoState);
+ if (emitSignals)
+ emitRedoAvailable(false);
+ } else if (stacksToClear == QTextDocument::UndoAndRedoStacks
+ && (undoCommandsAvailable || redoCommandsAvailable)) {
+ for (int i = 0; i < undoStack.size(); ++i) {
+ QTextUndoCommand c = undoStack[i];
+ if (c.command & QTextUndoCommand::Custom)
+ delete c.custom;
}
+ undoState = 0;
+ undoStack.resize(0);
+ if (emitSignals && undoCommandsAvailable)
+ emitUndoAvailable(false);
+ if (emitSignals && redoCommandsAvailable)
+ emitRedoAvailable(false);
}
- undoStack.resize(undoState);
}
void QTextDocumentPrivate::emitUndoAvailable(bool available)
@@ -1097,7 +1117,7 @@ void QTextDocumentPrivate::enableUndoRedo(bool enable)
if (!enable) {
undoState = 0;
- truncateUndoStack();
+ clearUndoRedoStacks(QTextDocument::RedoStack);
emitUndoAvailable(false);
emitRedoAvailable(false);
}
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index 4ecc2fa..ac5ed3c 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -252,10 +252,11 @@ public:
inline QFont defaultFont() const { return formats.defaultFont(); }
inline void setDefaultFont(const QFont &f) { formats.setDefaultFont(f); }
+ void clearUndoRedoStacks(QTextDocument::Stacks stacksToClear, bool emitSignals = false);
+
private:
bool split(int pos);
bool unite(uint f);
- void truncateUndoStack();
void insert_string(int pos, uint strPos, uint length, int format, QTextUndoCommand::Operation op);
int insert_block(int pos, uint strPos, int format, int blockformat, QTextUndoCommand::Operation op, int command);
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index d754800..13f31df 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -220,15 +220,17 @@ static quintptr tabId(const QDockAreaLayoutItem &item)
}
#endif
+static const int zero = 0;
+
QDockAreaLayoutInfo::QDockAreaLayoutInfo()
- : sep(0), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0)
+ : sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0)
#ifndef QT_NO_TABBAR
, tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth), tabBarVisible(false)
#endif
{
}
-QDockAreaLayoutInfo::QDockAreaLayoutInfo(int _sep, QInternal::DockPosition _dockPos,
+QDockAreaLayoutInfo::QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos,
Qt::Orientation _o, int tbshape,
QMainWindow *window)
: sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window)
@@ -281,7 +283,7 @@ QSize QDockAreaLayoutInfo::minimumSize() const
#endif
{
if (!first)
- a += sep;
+ a += *sep;
a += pick(o, min_size);
}
b = qMax(b, perp(o, min_size));
@@ -349,7 +351,7 @@ QSize QDockAreaLayoutInfo::maximumSize() const
#endif
{
if (!first)
- a += sep;
+ a += *sep;
a += pick(o, max_size);
}
b = qMin(b, perp(o, max_size));
@@ -415,7 +417,7 @@ QSize QDockAreaLayoutInfo::sizeHint() const
{
if (previous && !gap && !(previous->flags & QDockAreaLayoutItem::GapItem)
&& !previous->hasFixedSize(o)) {
- a += sep;
+ a += *sep;
}
a += gap ? item.size : pick(o, size_hint);
}
@@ -491,7 +493,7 @@ static int realMinSize(const QDockAreaLayoutInfo &info)
min = pick(info.o, item.minimumSize());
if (!first)
- result += info.sep;
+ result += *info.sep;
result += min;
first = false;
@@ -516,7 +518,7 @@ static int realMaxSize(const QDockAreaLayoutInfo &info)
max = pick(info.o, item.maximumSize());
if (!first)
- result += info.sep;
+ result += *info.sep;
result += max;
if (result >= QWIDGETSIZE_MAX)
@@ -555,7 +557,7 @@ void QDockAreaLayoutInfo::fitItems()
if (!(previous->flags & QDockAreaLayoutItem::GapItem)) {
QLayoutStruct &ls = layout_struct_list[j++];
ls.init();
- ls.minimumSize = ls.maximumSize = ls.sizeHint = previous->hasFixedSize(o) ? 0 : sep;
+ ls.minimumSize = ls.maximumSize = ls.sizeHint = previous->hasFixedSize(o) ? 0 : *sep;
ls.empty = false;
}
}
@@ -938,7 +940,7 @@ int QDockAreaLayoutInfo::separatorMove(int index, int delta)
if (item.skip()) {
ls.empty = true;
} else {
- const int separatorSpace = item.hasFixedSize(o) ? 0 : sep;
+ const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep;
ls.empty = false;
ls.pos = item.pos;
ls.size = item.size + separatorSpace;
@@ -956,7 +958,7 @@ int QDockAreaLayoutInfo::separatorMove(int index, int delta)
if (item.skip())
continue;
QLayoutStruct &ls = list[i];
- const int separatorSpace = item.hasFixedSize(o) ? 0 : sep;
+ const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep;
item.size = ls.size - separatorSpace;
item.pos = ls.pos;
if (item.subinfo != 0) {
@@ -1041,11 +1043,11 @@ QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path)
int next = this->next(index);
if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
- item.pos += sep;
- item.size -= sep;
+ item.pos += *sep;
+ item.size -= *sep;
}
if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
- item.size -= sep;
+ item.size -= *sep;
QPoint pos;
rpick(o, pos) = item.pos;
@@ -1083,11 +1085,11 @@ QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path)
#endif
{
if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
- item.pos -= sep;
- item.size += sep;
+ item.pos -= *sep;
+ item.size += *sep;
}
if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
- item.size += sep;
+ item.size += *sep;
}
return item.widgetItem;
@@ -1255,9 +1257,9 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid
QRect r = dockedGeometry(dockWidgetItem->widget());
gap_size = pick(o, r.size());
if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem))
- sep_size += sep;
+ sep_size += *sep;
if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
- sep_size += sep;
+ sep_size += *sep;
}
if (gap_size + sep_size > space)
gap_size = pick(o, gap_item.minimumSize());
@@ -1364,7 +1366,7 @@ QRect QDockAreaLayoutInfo::separatorRect(int index) const
QPoint pos = rect.topLeft();
rpick(o, pos) = item.pos + item.size;
QSize s = rect.size();
- rpick(o, s) = sep;
+ rpick(o, s) = *sep;
return QRect(pos, s);
}
@@ -1413,7 +1415,7 @@ QList<int> QDockAreaLayoutInfo::findSeparator(const QPoint &_pos) const
continue;
QRect sepRect = separatorRect(i);
- if (!sepRect.isNull() && sep == 1)
+ if (!sepRect.isNull() && *sep == 1)
sepRect.adjust(-2, -2, 2, 2);
//we also make sure we don't find a separator that's not there
if (sepRect.contains(_pos) && !item.hasFixedSize(o)) {
@@ -1560,7 +1562,7 @@ void QDockAreaLayoutInfo::apply(bool animate)
}
}
#ifndef QT_NO_TABBAR
- if (sep == 1)
+ if (*sep == 1)
updateSeparatorWidgets();
#endif //QT_NO_TABBAR
}
@@ -2010,7 +2012,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
updateTabBar();
setCurrentTabId(tabId(item_list.at(index)));
}
- if (!testing && sep == 1)
+ if (!testing && *sep == 1)
updateSeparatorWidgets();
#endif
@@ -2273,13 +2275,13 @@ QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true)
const int tabShape = 0;
#endif
docks[QInternal::LeftDock]
- = QDockAreaLayoutInfo(sep, QInternal::LeftDock, Qt::Vertical, tabShape, win);
+ = QDockAreaLayoutInfo(&sep, QInternal::LeftDock, Qt::Vertical, tabShape, win);
docks[QInternal::RightDock]
- = QDockAreaLayoutInfo(sep, QInternal::RightDock, Qt::Vertical, tabShape, win);
+ = QDockAreaLayoutInfo(&sep, QInternal::RightDock, Qt::Vertical, tabShape, win);
docks[QInternal::TopDock]
- = QDockAreaLayoutInfo(sep, QInternal::TopDock, Qt::Horizontal, tabShape, win);
+ = QDockAreaLayoutInfo(&sep, QInternal::TopDock, Qt::Horizontal, tabShape, win);
docks[QInternal::BottomDock]
- = QDockAreaLayoutInfo(sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win);
+ = QDockAreaLayoutInfo(&sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win);
centralWidgetItem = 0;
@@ -3028,7 +3030,7 @@ void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *do
#else
int tbshape = 0;
#endif
- QDockAreaLayoutInfo new_info(sep, pos, orientation, tbshape, mainWindow);
+ QDockAreaLayoutInfo new_info(&sep, pos, orientation, tbshape, mainWindow);
new_info.item_list.append(new QDockAreaLayoutInfo(info));
new_info.item_list.append(dockWidgetItem);
info = new_info;
@@ -3324,6 +3326,12 @@ void QDockAreaLayout::keepSize(QDockWidget *w)
item.flags |= QDockAreaLayoutItem::KeepSize;
}
+void QDockAreaLayout::styleChangedEvent()
+{
+ sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainWindow);
+ fitLayout();
+}
+
QT_END_NAMESPACE
#endif // QT_NO_DOCKWIDGET
diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h
index 0bc1aa9..0088f00 100644
--- a/src/gui/widgets/qdockarealayout_p.h
+++ b/src/gui/widgets/qdockarealayout_p.h
@@ -128,7 +128,7 @@ class Q_AUTOTEST_EXPORT QDockAreaLayoutInfo
{
public:
QDockAreaLayoutInfo();
- QDockAreaLayoutInfo(int _sep, QInternal::DockPosition _dockPos, Qt::Orientation _o,
+ QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos, Qt::Orientation _o,
int tbhape, QMainWindow *window);
QSize minimumSize() const;
@@ -189,7 +189,7 @@ public:
QMainWindowLayout *mainWindowLayout() const;
- int sep;
+ const int *sep;
mutable QVector<QWidget*> separatorWidgets;
QInternal::DockPosition dockPos;
Qt::Orientation o;
@@ -300,6 +300,7 @@ public:
QSet<QTabBar*> usedTabBars() const;
QSet<QWidget*> usedSeparatorWidgets() const;
#endif //QT_NO_TABBAR
+ void styleChangedEvent();
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp
index c779312..b81f04f 100644
--- a/src/gui/widgets/qlabel.cpp
+++ b/src/gui/widgets/qlabel.cpp
@@ -951,8 +951,8 @@ void QLabel::contextMenuEvent(QContextMenuEvent *ev)
return;
}
ev->accept();
- menu->exec(ev->globalPos());
- delete menu;
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(ev->globalPos());
#endif
}
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index 2d2df92..141f844 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -2046,9 +2046,9 @@ void QLineEdit::dropEvent(QDropEvent* e)
*/
void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
{
- QPointer<QMenu> menu = createStandardContextMenu();
- menu->exec(event->globalPos());
- delete menu;
+ QMenu *menu = createStandardContextMenu();
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(event->globalPos());
}
#if defined(Q_WS_WIN)
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 269cd12..a63f3bf 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -1393,6 +1393,7 @@ bool QMainWindow::event(QEvent *event)
#endif // QT_NO_STATUSTIP
case QEvent::StyleChange:
+ d->layout->layoutState.dockAreaLayout.styleChangedEvent();
if (!d->explicitIconSize)
setIconSize(QSize());
break;
@@ -1554,11 +1555,15 @@ void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
#ifndef QT_NO_MENU
QMenu *popup = createPopupMenu();
- if (popup && !popup->isEmpty()) {
- popup->exec(event->globalPos());
- event->accept();
+ if (popup) {
+ if (!popup->isEmpty()) {
+ popup->setAttribute(Qt::WA_DeleteOnClose);
+ popup->popup(event->globalPos());
+ event->accept();
+ } else {
+ delete popup;
+ }
}
- delete popup;
#endif
}
#endif // QT_NO_CONTEXTMENU
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp
index 03fca39..02d5501 100644
--- a/src/opengl/qglextensions.cpp
+++ b/src/opengl/qglextensions.cpp
@@ -224,6 +224,12 @@ bool qt_resolve_buffer_extensions(QGLContext *ctx)
bool qt_resolve_glsl_extensions(QGLContext *ctx)
{
+ // Geometry shaders are optional...
+ glProgramParameteriEXT = (_glProgramParameteriEXT) ctx->getProcAddress(QLatin1String("glProgramParameteriEXT"));
+ glFramebufferTextureEXT = (_glFramebufferTextureEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureEXT"));
+ glFramebufferTextureLayerEXT = (_glFramebufferTextureLayerEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureLayerEXT"));
+ glFramebufferTextureFaceEXT = (_glFramebufferTextureFaceEXT) ctx->getProcAddress(QLatin1String("glFramebufferTextureFaceEXT"));
+
#if defined(QT_OPENGL_ES_2)
// The GLSL shader functions are always present in OpenGL/ES 2.0.
// The only exceptions are glGetProgramBinaryOES and glProgramBinaryOES.
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index 116dfa6..f6613fd 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -197,6 +197,15 @@ typedef void (APIENTRY *_glBlitFramebufferEXT) (int srcX0, int srcY0, int srcX1,
typedef void (APIENTRY *_glRenderbufferStorageMultisampleEXT) (GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height);
+// GL_EXT_geometry_shader4
+typedef void (APIENTRY *_glProgramParameteriEXT)(GLuint program, GLenum pname, GLint value);
+typedef void (APIENTRY *_glFramebufferTextureEXT)(GLenum target, GLenum attachment,
+ GLuint texture, GLint level);
+typedef void (APIENTRY *_glFramebufferTextureLayerEXT)(GLenum target, GLenum attachment,
+ GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum attachment,
+ GLuint texture, GLint level, GLenum face);
+
// ARB_texture_compression
typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
GLsizei, GLint, GLsizei, const GLvoid *);
@@ -310,6 +319,10 @@ struct QGLExtensionFuncs
qt_glMapBufferARB = 0;
qt_glUnmapBufferARB = 0;
+ qt_glProgramParameteriEXT = 0;
+ qt_glFramebufferTextureEXT = 0;
+ qt_glFramebufferTextureLayerEXT = 0;
+ qt_glFramebufferTextureFaceEXT = 0;
#if !defined(QT_OPENGL_ES)
// Texture compression
qt_glCompressedTexImage2DARB = 0;
@@ -425,6 +438,11 @@ struct QGLExtensionFuncs
_glMapBufferARB qt_glMapBufferARB;
_glUnmapBufferARB qt_glUnmapBufferARB;
+ // Geometry shaders...
+ _glProgramParameteriEXT qt_glProgramParameteriEXT;
+ _glFramebufferTextureEXT qt_glFramebufferTextureEXT;
+ _glFramebufferTextureLayerEXT qt_glFramebufferTextureLayerEXT;
+ _glFramebufferTextureFaceEXT qt_glFramebufferTextureFaceEXT;
#if !defined(QT_OPENGL_ES)
// Texture compression
_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB;
@@ -661,6 +679,29 @@ struct QGLExtensionFuncs
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#endif
+// Geometry shader defines
+#ifndef GL_GEOMETRY_SHADER_EXT
+# define GL_GEOMETRY_SHADER_EXT 0x8DD9
+# define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+# define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+# define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+# define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+# define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+# define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+# define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+# define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+# define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+# define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+# define GL_LINES_ADJACENCY_EXT 0xA
+# define GL_LINE_STRIP_ADJACENCY_EXT 0xB
+# define GL_TRIANGLES_ADJACENCY_EXT 0xC
+# define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD
+# define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+# define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+# define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+# define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+# define GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#endif
#if !defined(QT_OPENGL_ES_2)
#define glProgramStringARB QGLContextPrivate::extensionFuncs(ctx).qt_glProgramStringARB
@@ -781,6 +822,11 @@ struct QGLExtensionFuncs
#define glClearDepth glClearDepthf
#endif
+#define glProgramParameteriEXT QGLContextPrivate::extensionFuncs(ctx).qt_glProgramParameteriEXT
+#define glFramebufferTextureEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureEXT
+#define glFramebufferTextureLayerEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureLayerEXT
+#define glFramebufferTextureFaceEXT QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTextureFaceEXT
+
#if !defined(QT_OPENGL_ES)
#define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB
#endif
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index 8fd4acf..170b650 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -143,6 +143,8 @@ QT_BEGIN_NAMESPACE
\value Vertex Vertex shader written in the OpenGL Shading Language (GLSL).
\value Fragment Fragment shader written in the OpenGL Shading Language (GLSL).
+ \value Geometry Geometry shaders written in the OpenGL Shading
+ Language (GLSL), based on the GL_EXT_geometry_shader4 extension.
*/
#ifndef GL_FRAGMENT_SHADER
@@ -226,6 +228,8 @@ bool QGLShaderPrivate::create()
GLuint shader;
if (shaderType == QGLShader::Vertex)
shader = glCreateShader(GL_VERTEX_SHADER);
+ else if (shaderType == QGLShader::Geometry)
+ shader = glCreateShader(GL_GEOMETRY_SHADER_EXT);
else
shader = glCreateShader(GL_FRAGMENT_SHADER);
if (!shader) {
@@ -509,6 +513,10 @@ GLuint QGLShader::shaderId() const
return d->shaderGuard.id();
}
+
+
+
+
#undef ctx
#define ctx programGuard.context()
@@ -521,8 +529,9 @@ public:
, linked(false)
, inited(false)
, removingShaders(false)
- , vertexShader(0)
- , fragmentShader(0)
+ , geometryVertexCount(64)
+ , geometryInputType(0)
+ , geometryOutputType(0)
{
}
~QGLShaderProgramPrivate();
@@ -531,11 +540,14 @@ public:
bool linked;
bool inited;
bool removingShaders;
+
+ int geometryVertexCount;
+ GLenum geometryInputType;
+ GLenum geometryOutputType;
+
QString log;
QList<QGLShader *> shaders;
QList<QGLShader *> anonShaders;
- QGLShader *vertexShader;
- QGLShader *fragmentShader;
bool hasShader(QGLShader::ShaderType type) const;
};
@@ -604,6 +616,7 @@ bool QGLShaderProgram::init()
context = QGLContext::currentContext();
d->programGuard.setContext(context);
}
+
if (!context)
return false;
if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
@@ -831,6 +844,7 @@ bool QGLShaderProgram::link()
GLuint program = d->programGuard.id();
if (!program)
return false;
+
GLint value;
if (d->shaders.isEmpty()) {
// If there are no explicit shaders, then it is possible that the
@@ -843,6 +857,22 @@ bool QGLShaderProgram::link()
if (d->linked)
return true;
}
+
+ // Set up the geometry shader parameters
+ if (glProgramParameteriEXT) {
+ foreach (QGLShader *shader, d->shaders) {
+ if (shader->shaderType() & QGLShader::Geometry) {
+ glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT,
+ d->geometryInputType);
+ glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT,
+ d->geometryOutputType);
+ glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT,
+ d->geometryVertexCount);
+ break;
+ }
+ }
+ }
+
glLinkProgram(program);
value = 0;
glGetProgramiv(program, GL_LINK_STATUS, &value);
@@ -3047,6 +3077,97 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *
#undef ctx
/*!
+ Returns the hardware limit for how many vertices a geometry shader
+ can output.
+
+ \sa setGeometryShaderOutputVertexCount
+*/
+int QGLShaderProgram::maxGeometryOutputVertices() const
+{
+ int n;
+ glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
+ return n;
+}
+
+
+
+/*!
+ Sets the maximum number of vertices the current geometry shader
+ program will produce, if active.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QGLShaderProgram::setGeometryOutputVertexCount(int count)
+{
+#ifndef QT_NO_DEBUG
+ int max = maxGeometryOutputVertices();
+ if (count > max) {
+ qWarning("QGLShaderProgram::setGeometryOutputVertexCount: count: %d higher than maximum: %d",
+ count, max);
+ }
+#endif
+ d_func()->geometryVertexCount = count;
+}
+
+
+/*!
+ Returns the maximum number of vertices the current geometry shader
+ program will produce, if active.
+
+ This parameter takes effect the ntext time the program is linked.
+*/
+int QGLShaderProgram::geometryOutputVertexCount() const
+{
+ return d_func()->geometryVertexCount;
+}
+
+
+/*!
+ Sets the output type from the geometry shader, if active.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QGLShaderProgram::setGeometryInputType(GLenum inputType)
+{
+ d_func()->geometryInputType = inputType;
+}
+
+
+/*!
+ Returns the geometry shader input type, if active.
+
+ This parameter takes effect the next time the program is linked.
+ */
+
+GLenum QGLShaderProgram::geometryInputType() const
+{
+ return d_func()->geometryInputType;
+}
+
+
+/*!
+ Sets the output type from the geometry shader, if active.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QGLShaderProgram::setGeometryOutputType(GLenum outputType)
+{
+ d_func()->geometryOutputType = outputType;
+}
+
+
+/*!
+ Returns the geometry shader output type, if active.
+
+ This parameter takes effect the next time the program is linked.
+ */
+GLenum QGLShaderProgram::geometryOutputType() const
+{
+ return d_func()->geometryOutputType;
+}
+
+
+/*!
Returns true if shader programs written in the OpenGL Shading
Language (GLSL) are supported on this system; false otherwise.
@@ -3078,6 +3199,39 @@ void QGLShaderProgram::shaderDestroyed()
removeShader(shader);
}
+
+#undef ctx
+#undef context
+
+/*!
+ Returns true if shader programs of type \a type are supported on
+ this system; false otherwise.
+
+ The \a context is used to resolve the GLSL extensions.
+ If \a context is null, then QGLContext::currentContext() is used.
+*/
+bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context)
+{
+ if (!context)
+ context = QGLContext::currentContext();
+ if (!context)
+ return false;
+
+ if ((type & ~(Geometry | Vertex | Fragment)) || type == 0)
+ return false;
+
+ bool resolved = qt_resolve_glsl_extensions(const_cast<QGLContext *>(context));
+ if (!resolved)
+ return false;
+
+ if ((type & Geometry) && !QByteArray((const char *) glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4"))
+ return false;
+
+ return true;
+}
+
+
+
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLShaderProgram::setAttributeArray
diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h
index 19ce9f2..d612b05 100644
--- a/src/opengl/qglshaderprogram.h
+++ b/src/opengl/qglshaderprogram.h
@@ -66,7 +66,8 @@ public:
enum ShaderTypeBit
{
Vertex = 0x0001,
- Fragment = 0x0002
+ Fragment = 0x0002,
+ Geometry = 0x0004
};
Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)
@@ -88,6 +89,8 @@ public:
GLuint shaderId() const;
+ static bool hasOpenGLShaders(ShaderType type, const QGLContext *context = 0);
+
private:
friend class QGLShaderProgram;
@@ -100,6 +103,14 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QGLShader::ShaderType)
class QGLShaderProgramPrivate;
+#ifndef GL_EXT_geometry_shader4
+# define GL_LINES_ADJACENCY_EXT 0xA
+# define GL_LINE_STRIP_ADJACENCY_EXT 0xB
+# define GL_TRIANGLES_ADJACENCY_EXT 0xC
+# define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD
+#endif
+
+
class Q_OPENGL_EXPORT QGLShaderProgram : public QObject
{
Q_OBJECT
@@ -128,6 +139,17 @@ public:
GLuint programId() const;
+ int maxGeometryOutputVertices() const;
+
+ void setGeometryOutputVertexCount(int count);
+ int geometryOutputVertexCount() const;
+
+ void setGeometryInputType(GLenum inputType);
+ GLenum geometryInputType() const;
+
+ void setGeometryOutputType(GLenum outputType);
+ GLenum geometryOutputType() const;
+
void bindAttributeLocation(const char *name, int location);
void bindAttributeLocation(const QByteArray& name, int location);
void bindAttributeLocation(const QString& name, int location);
diff --git a/tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp b/tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp
index 37dd6d8..26890b3 100644
--- a/tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp
+++ b/tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp
@@ -68,7 +68,7 @@ void tst_QDoubleValidator::validateThouSep_data()
QTest::addColumn<QString>("value");
QTest::addColumn<QValidator::State>("result");
- QTest::newRow("1,000C") << "C" << QString("1,000") << INV;
+ QTest::newRow("1,000C") << "C" << QString("1,000") << ACC;
QTest::newRow("1.000C") << "C" << QString("1.000") << ACC;
QTest::newRow("1,000de") << "de" << QString("1,000") << ACC;
@@ -160,9 +160,9 @@ void tst_QDoubleValidator::validate_data()
QTest::newRow("data_de0") << "de" << 0.0 << 100.0 << 1 << QString("50,0") << ACC << ACC;
QTest::newRow("data_de1") << "de" << 00.0 << 100.0 << 1 << QString("500,0") << ITM << ITM;
QTest::newRow("data_de1a") << "de" << 00.0 << 100.0 << 1 << QString("5001,0") << ITM << INV;
- QTest::newRow("data_de0C") << "de" << 0.0 << 100.0 << 1 << QString("50.0") << ACC << ACC;
- QTest::newRow("data_de1C") << "de" << 00.0 << 100.0 << 1 << QString("500.0") << ITM << ITM;
- QTest::newRow("data_de1aC") << "de" << 00.0 << 100.0 << 1 << QString("5001.0") << ITM << INV;
+ QTest::newRow("data_de0C") << "de" << 0.0 << 100.0 << 1 << QString("50,0") << ACC << ACC;
+ QTest::newRow("data_de1C") << "de" << 00.0 << 100.0 << 1 << QString("500,0") << ITM << ITM;
+ QTest::newRow("data_de1aC") << "de" << 00.0 << 100.0 << 1 << QString("5001,0") << ITM << INV;
QTest::newRow("data_de2") << "de" << 00.0 << 100.0 << 1 << QString("-35,0") << INV << INV;
QTest::newRow("data_de3") << "de" << 00.0 << 100.0 << 1 << QString("a") << INV << INV;
QTest::newRow("data_de4") << "de" << 0.0 << 100.0 << 1 << QString("-") << INV << INV;
@@ -172,7 +172,7 @@ void tst_QDoubleValidator::validate_data()
QTest::newRow("data_de8") << "de" << -100.0 << 100.0 << 1 << QString("-100") << ACC << ACC;
QTest::newRow("data_de9") << "de" << -100.0 << -10.0 << 1 << QString("10") << ITM << ITM;
QTest::newRow("data_de10") << "de" << 0.3 << 0.5 << 5 << QString("0,34567") << ACC << ACC;
- QTest::newRow("data_de11") << "de" << -0.3 << -0.5 << 5 << QString("-0,345678") << INV << INV;
+ QTest::newRow("data_de11") << "de" << -0.3 << -0.5 << 5 << QString("-0,345678") << ITM << INV;
QTest::newRow("data_de12") << "de" << -0.32 << 0.32 << 1 << QString("0") << ACC << ACC;
QTest::newRow("data_de13") << "de" << 0.0 << 100.0 << 1 << QString("3456a") << INV << INV;
QTest::newRow("data_de14") << "de" << -100.0 << 100.0 << 1 << QString("-3456a") << INV << INV;
diff --git a/tests/auto/qlabel/tst_qlabel.cpp b/tests/auto/qlabel/tst_qlabel.cpp
index 7099917..153149e7 100644
--- a/tests/auto/qlabel/tst_qlabel.cpp
+++ b/tests/auto/qlabel/tst_qlabel.cpp
@@ -121,6 +121,10 @@ private slots:
void mnemonic();
void selection();
+#ifndef QT_NO_CONTEXTMENU
+ void taskQTBUG_7902_contextMenuCrash();
+#endif
+
private:
QLabel *testWidget;
QPointer<Widget> test_box;
@@ -582,5 +586,25 @@ void tst_QLabel::selection()
QCOMPARE(label.selectionStart(), 6);
}
+#ifndef QT_NO_CONTEXTMENU
+void tst_QLabel::taskQTBUG_7902_contextMenuCrash()
+{
+ QLabel *w = new QLabel("Test or crash?");
+ w->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ w->show();
+ QTest::qWaitForWindowShown(w);
+
+ QTimer ti;
+ w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
+ ti.start(300);
+
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ qApp->postEvent(w, cme);
+
+ QTest::qWait(350);
+ // No crash, it's allright.
+}
+#endif
+
QTEST_MAIN(tst_QLabel)
#include "tst_qlabel.moc"
diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp
index 7283916..fcca58a 100644
--- a/tests/auto/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/qlineedit/tst_qlineedit.cpp
@@ -271,6 +271,9 @@ private slots:
void taskQTBUG_4401_enterKeyClearsPassword();
void taskQTBUG_4679_moveToStartEndOfBlock();
void taskQTBUG_4679_selectToStartEndOfBlock();
+#ifndef QT_NO_CONTEXTMENU
+ void taskQTBUG_7902_contextMenuCrash();
+#endif
protected slots:
#ifdef QT3_SUPPORT
@@ -3638,5 +3641,25 @@ void tst_QLineEdit::taskQTBUG_4679_selectToStartEndOfBlock()
#endif // Q_OS_MAC
}
+#ifndef QT_NO_CONTEXTMENU
+void tst_QLineEdit::taskQTBUG_7902_contextMenuCrash()
+{
+ // Would pass before the associated commit, but left as a guard.
+ QLineEdit *w = new QLineEdit;
+ w->show();
+ QTest::qWaitForWindowShown(w);
+
+ QTimer ti;
+ w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
+ ti.start(200);
+
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ qApp->postEvent(w, cme);
+
+ QTest::qWait(300);
+ // No crash, it's allright.
+}
+#endif
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/qmainwindow/tst_qmainwindow.cpp b/tests/auto/qmainwindow/tst_qmainwindow.cpp
index b1c44be..1273e85 100644
--- a/tests/auto/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/qmainwindow/tst_qmainwindow.cpp
@@ -108,6 +108,7 @@ private slots:
void addToolbarAfterShow();
void centralWidgetSize();
void dockWidgetSize();
+ void QTBUG2774_stylechange();
};
// Testing get/set functions
@@ -1709,6 +1710,45 @@ void tst_QMainWindow::dockWidgetSize()
}
}
+void tst_QMainWindow::QTBUG2774_stylechange()
+{
+
+ QMainWindow mw;
+ QDockWidget *dockw = new QDockWidget();
+ mw.addDockWidget(Qt::LeftDockWidgetArea, dockw);
+ mw.addDockWidget(Qt::LeftDockWidgetArea, new QDockWidget());
+ QTextEdit *central = new QTextEdit(&mw);
+ mw.setCentralWidget(central);
+ dockw->resize(10,10);
+ mw.show();
+ QTest::qWaitForWindowShown(&mw);
+ int centralOriginalWidth = central->width();
+
+ QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() - 3)));
+ QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height())));
+ QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 30)));
+
+
+ {
+ QTest::qWait(1000);
+ mw.setStyleSheet("QMainWindow::separator { width: 50px; height:50px; }");
+ QTest::qWait(5000);
+ QApplication::processEvents();
+ QVERIFY(central->width() < centralOriginalWidth);
+ QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height())));
+ QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 49)));
+ }
+
+ {
+ mw.setStyleSheet("QMainWindow::separator { width: 0px; height: 0px; }");
+ QApplication::processEvents();
+ QVERIFY(central->width() > centralOriginalWidth);
+ QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height())));
+ QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 1)));
+ }
+}
+
+
QTEST_MAIN(tst_QMainWindow)
#include "tst_qmainwindow.moc"
diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp
index deb9379..101baa5 100644
--- a/tests/auto/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/qtextedit/tst_qtextedit.cpp
@@ -201,6 +201,9 @@ private slots:
void noWrapBackgrounds();
void preserveCharFormatAfterUnchangingSetPosition();
void twoSameInputMethodEvents();
+#ifndef QT_NO_CONTEXTMENU
+ void taskQTBUG_7902_contextMenuCrash();
+#endif
private:
void createSelection();
@@ -2202,5 +2205,24 @@ void tst_QTextEdit::twoSameInputMethodEvents()
QCOMPARE(ed->document()->firstBlock().layout()->lineCount(), 1);
}
+#ifndef QT_NO_CONTEXTMENU
+void tst_QTextEdit::taskQTBUG_7902_contextMenuCrash()
+{
+ QTextEdit *w = new QTextEdit;
+ w->show();
+ QTest::qWaitForWindowShown(w);
+
+ QTimer ti;
+ w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
+ ti.start(200);
+
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ qApp->postEvent(w->viewport(), cme);
+
+ QTest::qWait(300);
+ // No crash, it's allright.
+}
+#endif
+
QTEST_MAIN(tst_QTextEdit)
#include "tst_qtextedit.moc"
diff --git a/tools/assistant/tools/assistant/assistant.pro b/tools/assistant/tools/assistant/assistant.pro
index e62d30c..edaf076 100644
--- a/tools/assistant/tools/assistant/assistant.pro
+++ b/tools/assistant/tools/assistant/assistant.pro
@@ -25,6 +25,7 @@ HEADERS += aboutdialog.h \
centralwidget.h \
cmdlineparser.h \
contentwindow.h \
+ findwidget.h \
filternamedialog.h \
helpenginewrapper.h \
helpviewer.h \
@@ -50,6 +51,7 @@ SOURCES += aboutdialog.cpp \
centralwidget.cpp \
cmdlineparser.cpp \
contentwindow.cpp \
+ findwidget.cpp \
filternamedialog.cpp \
helpenginewrapper.cpp \
helpviewer.cpp \
diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp
index 8bb2ffe..03af06c 100644
--- a/tools/assistant/tools/assistant/centralwidget.cpp
+++ b/tools/assistant/tools/assistant/centralwidget.cpp
@@ -41,34 +41,26 @@
#include "tracer.h"
#include "centralwidget.h"
+#include "findwidget.h"
#include "helpenginewrapper.h"
#include "helpviewer.h"
#include "searchwidget.h"
#include "mainwindow.h"
-#include "preferencesdialog.h"
#include "../shared/collectionconfiguration.h"
-#include <QtCore/QDir>
-#include <QtCore/QEvent>
#include <QtCore/QTimer>
-#include <QtGui/QMenu>
-#include <QtGui/QLabel>
+#include <QtGui/QApplication>
+#include <QtGui/QKeyEvent>
#include <QtGui/QLayout>
+#include <QtGui/QMenu>
#include <QtGui/QPrinter>
-#include <QtGui/QLineEdit>
-#include <QtGui/QCheckBox>
#include <QtGui/QTabBar>
#include <QtGui/QTabWidget>
#include <QtGui/QToolButton>
-#include <QtGui/QMouseEvent>
-#include <QtGui/QSpacerItem>
-#include <QtGui/QTextCursor>
+#include <QtGui/QPageSetupDialog>
#include <QtGui/QPrintDialog>
-#include <QtGui/QApplication>
-#include <QtGui/QTextDocumentFragment>
#include <QtGui/QPrintPreviewDialog>
-#include <QtGui/QPageSetupDialog>
#include <QtHelp/QHelpSearchEngine>
@@ -88,135 +80,13 @@ namespace {
CentralWidget *staticCentralWidget = 0;
}
-FindWidget::FindWidget(QWidget *parent)
- : QWidget(parent)
- , appPalette(qApp->palette())
-{
- TRACE_OBJ
- QHBoxLayout *hboxLayout = new QHBoxLayout(this);
- QString resourcePath = QLatin1String(":/trolltech/assistant/images/");
-
-#ifndef Q_OS_MAC
- hboxLayout->setMargin(0);
- hboxLayout->setSpacing(6);
- resourcePath.append(QLatin1String("win"));
-#else
- resourcePath.append(QLatin1String("mac"));
-#endif
-
- toolClose = setupToolButton(QLatin1String(""),
- resourcePath + QLatin1String("/closetab.png"));
- hboxLayout->addWidget(toolClose);
-
- editFind = new QLineEdit(this);
- hboxLayout->addWidget(editFind);
- editFind->setMinimumSize(QSize(150, 0));
- connect(editFind, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
- toolPrevious = setupToolButton(tr("Previous"),
- resourcePath + QLatin1String("/previous.png"));
- hboxLayout->addWidget(toolPrevious);
-
- toolNext = setupToolButton(tr("Next"),
- resourcePath + QLatin1String("/next.png"));
- hboxLayout->addWidget(toolNext);
-
- checkCase = new QCheckBox(tr("Case Sensitive"), this);
- hboxLayout->addWidget(checkCase);
-
- checkWholeWords = new QCheckBox(tr("Whole words"), this);
- hboxLayout->addWidget(checkWholeWords);
-#if !defined(QT_NO_WEBKIT)
- checkWholeWords->hide();
-#endif
-
- labelWrapped = new QLabel(this);
- labelWrapped->setScaledContents(true);
- labelWrapped->setTextFormat(Qt::RichText);
- labelWrapped->setMinimumSize(QSize(0, 20));
- labelWrapped->setMaximumSize(QSize(105, 20));
- labelWrapped->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
- labelWrapped->setText(tr("<img src=\":/trolltech/assistant/images/wrap.png\""
- ">&nbsp;Search wrapped"));
- hboxLayout->addWidget(labelWrapped);
-
- QSpacerItem *spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding,
- QSizePolicy::Minimum);
- hboxLayout->addItem(spacerItem);
- setMinimumWidth(minimumSizeHint().width());
- labelWrapped->hide();
-
- updateButtons();
-}
-
-FindWidget::~FindWidget()
-{
- TRACE_OBJ
-}
-
-void FindWidget::hideEvent(QHideEvent* event)
-{
- TRACE_OBJ
-#if !defined(QT_NO_WEBKIT)
- // TODO: remove this once webkit supports setting the palette
- if (!event->spontaneous())
- qApp->setPalette(appPalette);
-#else
- Q_UNUSED(event);
-#endif
-}
-
-void FindWidget::showEvent(QShowEvent* event)
-{
- TRACE_OBJ
-#if !defined(QT_NO_WEBKIT)
- // TODO: remove this once webkit supports setting the palette
- if (!event->spontaneous()) {
- QPalette p = appPalette;
- p.setColor(QPalette::Inactive, QPalette::Highlight,
- p.color(QPalette::Active, QPalette::Highlight));
- p.setColor(QPalette::Inactive, QPalette::HighlightedText,
- p.color(QPalette::Active, QPalette::HighlightedText));
- qApp->setPalette(p);
- }
-#else
- Q_UNUSED(event);
-#endif
-}
-
-void FindWidget::updateButtons()
-{
- TRACE_OBJ
- if (editFind->text().isEmpty()) {
- toolPrevious->setEnabled(false);
- toolNext->setEnabled(false);
- } else {
- toolPrevious->setEnabled(true);
- toolNext->setEnabled(true);
- }
-}
-
-QToolButton* FindWidget::setupToolButton(const QString &text, const QString &icon)
-{
- TRACE_OBJ
- QToolButton *toolButton = new QToolButton(this);
-
- toolButton->setText(text);
- toolButton->setAutoRaise(true);
- toolButton->setIcon(QIcon(icon));
- toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
-
- return toolButton;
-}
-
-
-// --
+// -- CentralWidget
CentralWidget::CentralWidget(MainWindow *parent)
: QWidget(parent)
, lastTabPage(0)
- , findBar(0)
, tabWidget(0)
, findWidget(0)
, printer(0)
@@ -260,20 +130,15 @@ CentralWidget::CentralWidget(MainWindow *parent)
vboxLayout->addWidget(tabWidget);
- findBar = new QWidget(this);
- findWidget = new FindWidget(findBar);
- findBar->setMinimumHeight(findWidget->minimumSizeHint().height());
- findWidget->move(0, 0);
- vboxLayout->addWidget(findBar);
- findBar->hide();
- findWidget->editFind->installEventFilter(this);
-
- connect(findWidget->toolClose, SIGNAL(clicked()), findBar, SLOT(hide()));
- connect(findWidget->toolNext, SIGNAL(clicked()), this, SLOT(findNext()));
- connect(findWidget->editFind, SIGNAL(returnPressed()), this, SLOT(findNext()));
- connect(findWidget->editFind, SIGNAL(textChanged(QString)), this,
- SLOT(findCurrentText(QString)));
- connect(findWidget->toolPrevious, SIGNAL(clicked()), this, SLOT(findPrevious()));
+ findWidget = new FindWidget(this);
+ vboxLayout->addWidget(findWidget);
+ findWidget->hide();
+
+ connect(findWidget, SIGNAL(findNext()), this, SLOT(findNext()));
+ connect(findWidget, SIGNAL(findPrevious()), this, SLOT(findPrevious()));
+ connect(findWidget, SIGNAL(find(QString, bool)), this,
+ SLOT(find(QString, bool)));
+ connect(findWidget, SIGNAL(escapePressed()), this, SLOT(activateTab()));
QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
if (tabBar) {
@@ -360,12 +225,6 @@ void CentralWidget::zoomOut()
m_searchWidget->zoomOut();
}
-void CentralWidget::findNext()
-{
- TRACE_OBJ
- find(findWidget->editFind->text(), true);
-}
-
void CentralWidget::nextPage()
{
TRACE_OBJ
@@ -395,12 +254,6 @@ void CentralWidget::previousPage()
tabWidget->setCurrentIndex(index);
}
-void CentralWidget::findPrevious()
-{
- TRACE_OBJ
- find(findWidget->editFind->text(), false);
-}
-
void CentralWidget::closeTab()
{
TRACE_OBJ
@@ -527,9 +380,7 @@ void CentralWidget::copySelection()
void CentralWidget::showTextSearch()
{
TRACE_OBJ
- findBar->show();
- findWidget->editFind->selectAll();
- findWidget->editFind->setFocus(Qt::ShortcutFocusReason);
+ findWidget->show();
}
void CentralWidget::initPrinter()
@@ -708,12 +559,6 @@ HelpViewer *CentralWidget::newEmptyTab()
return viewer;
}
-void CentralWidget::findCurrentText(const QString &text)
-{
- TRACE_OBJ
- find(text, true);
-}
-
void CentralWidget::connectSignals()
{
TRACE_OBJ
@@ -855,14 +700,6 @@ bool CentralWidget::eventFilter(QObject *object, QEvent *e)
return QWidget::eventFilter(object, e);
} break;
- case Qt::Key_Escape: {
- if (findWidget->editFind == object) {
- findBar->hide();
- if (HelpViewer *viewer = currentHelpViewer())
- viewer->setFocus();
- }
- } break;
-
case Qt::Key_Backspace: {
HelpViewer *viewer = currentHelpViewer();
if (viewer == object) {
@@ -906,38 +743,43 @@ void CentralWidget::keyPressEvent(QKeyEvent *e)
TRACE_OBJ
const QString &text = e->text();
if (text.startsWith(QLatin1Char('/'))) {
- if (!findBar->isVisible()) {
- findBar->show();
- findWidget->editFind->clear();
+ if (!findWidget->isVisible()) {
+ findWidget->showAndClear();
} else {
- findWidget->editFind->selectAll();
+ findWidget->show();
}
- findWidget->editFind->setFocus();
- return;
+ } else {
+ QWidget::keyPressEvent(e);
}
- QWidget::keyPressEvent(e);
}
-void CentralWidget::find(const QString &ttf, bool forward)
+void CentralWidget::findNext()
+{
+ find(findWidget->text(), true);
+}
+
+void CentralWidget::findPrevious()
{
TRACE_OBJ
- QPalette p = findWidget->editFind->palette();
- p.setColor(QPalette::Active, QPalette::Base, Qt::white);
+ find(findWidget->text(), false);
+}
+void CentralWidget::find(const QString &ttf, bool forward)
+{
+ TRACE_OBJ
bool found = false;
-
#if defined(QT_NO_WEBKIT)
found = findInTextBrowser(ttf, forward);
#else
found = findInWebPage(ttf, forward);
#endif
- if (!found && !ttf.isEmpty())
- p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102));
+ if (!found && ttf.isEmpty())
+ found = true; // the line edit is empty, no need to mark it red...
if (!findWidget->isVisible())
findWidget->show();
- findWidget->editFind->setPalette(p);
+ findWidget->setPalette(found);
}
bool CentralWidget::findInWebPage(const QString &ttf, bool forward)
@@ -951,21 +793,23 @@ bool CentralWidget::findInWebPage(const QString &ttf, bool forward)
if (!forward)
options |= QWebPage::FindBackward;
- if (findWidget->checkCase->isChecked())
+ if (findWidget->caseSensitive())
options |= QWebPage::FindCaseSensitively;
found = viewer->findText(ttf, options);
- findWidget->labelWrapped->hide();
+ findWidget->setTextWrappedVisible(false);
if (!found) {
options |= QWebPage::FindWrapsAroundDocument;
found = viewer->findText(ttf, options);
if (found)
- findWidget->labelWrapped->show();
+ findWidget->setTextWrappedVisible(true);
}
}
// force highlighting of all other matches, also when empty (clear)
options = QWebPage::HighlightAllOccurrences;
+ if (findWidget->caseSensitive())
+ options |= QWebPage::FindCaseSensitively;
viewer->findText(QLatin1String(""), options);
viewer->findText(ttf, options);
return found;
@@ -1006,13 +850,10 @@ bool CentralWidget::findInTextBrowser(const QString &ttf, bool forward)
if (!forward)
options |= QTextDocument::FindBackward;
- if (findWidget->checkCase->isChecked())
+ if (findWidget->caseSensitive())
options |= QTextDocument::FindCaseSensitively;
- if (findWidget->checkWholeWords->isChecked())
- options |= QTextDocument::FindWholeWords;
-
- findWidget->labelWrapped->hide();
+ findWidget->setTextWrappedVisible(false);
bool found = true;
QTextCursor newCursor = doc->find(ttf, cursor, options);
@@ -1025,7 +866,7 @@ bool CentralWidget::findInTextBrowser(const QString &ttf, bool forward)
found = false;
newCursor = cursor;
} else {
- findWidget->labelWrapped->show();
+ findWidget->setTextWrappedVisible(true);
}
}
browser->setTextCursor(newCursor);
@@ -1048,6 +889,11 @@ void CentralWidget::updateBrowserFont()
setBrowserFontFor(tabWidget->widget(i), font);
}
+bool CentralWidget::searchWidgetAttached() const
+{
+ return m_searchWidget && m_searchWidget->isAttached();
+}
+
void CentralWidget::createSearchWidget(QHelpSearchEngine *searchEngine)
{
TRACE_OBJ
diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h
index a7c0d6f..6c3e93c 100644
--- a/tools/assistant/tools/assistant/centralwidget.h
+++ b/tools/assistant/tools/assistant/centralwidget.h
@@ -38,72 +38,20 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#ifndef CENTRALWIDGET_H
#define CENTRALWIDGET_H
-#include <QtCore/QList>
#include <QtCore/QUrl>
-#include <QtCore/QPoint>
-#include <QtCore/QObject>
-
#include <QtGui/QWidget>
-#include "searchwidget.h"
-
QT_BEGIN_NAMESPACE
-class QEvent;
-class QLabel;
-class QAction;
-class QCheckBox;
-class QLineEdit;
-class QTextBrowser;
-class QToolButton;
-
+class FindWidget;
class HelpViewer;
-class QTabWidget;
-class QHelpEngine;
-class CentralWidget;
-class PrintHelper;
class MainWindow;
-
class QHelpSearchEngine;
-
-class FindWidget : public QWidget
-{
- Q_OBJECT
-
-public:
- FindWidget(QWidget *parent = 0);
- ~FindWidget();
-
-signals:
- void findNext();
- void findPrevious();
-
-protected:
- void hideEvent(QHideEvent* event);
- void showEvent(QShowEvent * event);
-
-private slots:
- void updateButtons();
-
-private:
- QToolButton* setupToolButton(const QString &text, const QString &icon);
-
-private:
- QLineEdit *editFind;
- QCheckBox *checkCase;
- QLabel *labelWrapped;
- QToolButton *toolNext;
- QToolButton *toolClose;
- QToolButton *toolPrevious;
- QCheckBox *checkWholeWords;
-
- QPalette appPalette;
- friend class CentralWidget;
-};
+class QTabWidget;
+class SearchWidget;
class CentralWidget : public QWidget
{
@@ -123,11 +71,8 @@ public:
QList<QAction*> globalActions() const;
void setGlobalActions(const QList<QAction*> &actions);
HelpViewer *currentHelpViewer() const;
- void activateTab(bool onlyHelpViewer = false);
- bool searchWidgetAttached() const {
- return m_searchWidget && m_searchWidget->isAttached();
- }
+ bool searchWidgetAttached() const;
void createSearchWidget(QHelpSearchEngine *searchEngine);
void activateSearchWidget(bool updateLastTabPage = false);
void removeSearchWidget();
@@ -144,11 +89,9 @@ public:
public slots:
void zoomIn();
void zoomOut();
- void findNext();
void nextPage();
void resetZoom();
void previousPage();
- void findPrevious();
void copySelection();
void showTextSearch();
void print();
@@ -157,12 +100,17 @@ public slots:
void updateBrowserFont();
void setSource(const QUrl &url);
void setSourceInNewTab(const QUrl &url, qreal zoom = 0.0);
- void findCurrentText(const QString &text);
HelpViewer *newEmptyTab();
void home();
void forward();
void backward();
+ void activateTab(bool onlyHelpViewer = false);
+
+ void findNext();
+ void findPrevious();
+ void find(const QString &text, bool forward);
+
signals:
void currentViewerChanged();
void copyAvailable(bool yes);
@@ -189,7 +137,6 @@ private slots:
private:
void connectSignals();
bool eventFilter(QObject *object, QEvent *e);
- void find(const QString &ttf, bool forward);
bool findInWebPage(const QString &ttf, bool forward);
bool findInTextBrowser(const QString &ttf, bool forward);
void initPrinter();
@@ -203,7 +150,6 @@ private:
int lastTabPage;
QList<QAction*> globalActionList;
- QWidget *findBar;
QTabWidget *tabWidget;
FindWidget *findWidget;
QPrinter *printer;
diff --git a/tools/assistant/tools/assistant/findwidget.cpp b/tools/assistant/tools/assistant/findwidget.cpp
new file mode 100644
index 0000000..2e40ab0
--- /dev/null
+++ b/tools/assistant/tools/assistant/findwidget.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+#include "findwidget.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QCheckBox>
+#include <QtGui/QHideEvent>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+FindWidget::FindWidget(QWidget *parent)
+ : QWidget(parent)
+ , appPalette(qApp->palette())
+{
+ TRACE_OBJ
+ installEventFilter(this);
+ QHBoxLayout *hboxLayout = new QHBoxLayout(this);
+ QString resourcePath = QLatin1String(":/trolltech/assistant/images/");
+
+#ifndef Q_OS_MAC
+ hboxLayout->setMargin(0);
+ hboxLayout->setSpacing(6);
+ resourcePath.append(QLatin1String("win"));
+#else
+ resourcePath.append(QLatin1String("mac"));
+#endif
+
+ toolClose = setupToolButton(QLatin1String(""),
+ resourcePath + QLatin1String("/closetab.png"));
+ hboxLayout->addWidget(toolClose);
+
+ editFind = new QLineEdit(this);
+ hboxLayout->addWidget(editFind);
+ editFind->setMinimumSize(QSize(150, 0));
+ connect(editFind, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+ connect(editFind, SIGNAL(returnPressed()), this, SIGNAL(findNext()));
+ connect(editFind, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
+
+ toolPrevious = setupToolButton(tr("Previous"),
+ resourcePath + QLatin1String("/previous.png"));
+ connect(toolPrevious, SIGNAL(clicked()), this, SIGNAL(findPrevious()));
+
+ hboxLayout->addWidget(toolPrevious);
+
+ toolNext = setupToolButton(tr("Next"),
+ resourcePath + QLatin1String("/next.png"));
+ hboxLayout->addWidget(toolNext);
+ connect(toolNext, SIGNAL(clicked()), this, SIGNAL(findNext()));
+
+ checkCase = new QCheckBox(tr("Case Sensitive"), this);
+ hboxLayout->addWidget(checkCase);
+
+ labelWrapped = new QLabel(this);
+ labelWrapped->setScaledContents(true);
+ labelWrapped->setTextFormat(Qt::RichText);
+ labelWrapped->setMinimumSize(QSize(0, 20));
+ labelWrapped->setMaximumSize(QSize(105, 20));
+ labelWrapped->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
+ labelWrapped->setText(tr("<img src=\":/trolltech/assistant/images/wrap.png\""
+ ">&nbsp;Search wrapped"));
+ hboxLayout->addWidget(labelWrapped);
+
+ QSpacerItem *spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding,
+ QSizePolicy::Minimum);
+ hboxLayout->addItem(spacerItem);
+ setMinimumWidth(minimumSizeHint().width());
+ labelWrapped->hide();
+
+ updateButtons();
+}
+
+FindWidget::~FindWidget()
+{
+ TRACE_OBJ
+}
+
+void FindWidget::show()
+{
+ TRACE_OBJ
+ QWidget::show();
+ editFind->selectAll();
+ editFind->setFocus(Qt::ShortcutFocusReason);
+}
+
+void FindWidget::showAndClear()
+{
+ TRACE_OBJ
+ show();
+ editFind->clear();
+}
+
+QString FindWidget::text() const
+{
+ TRACE_OBJ
+ return editFind->text();
+}
+
+bool FindWidget::caseSensitive() const
+{
+ TRACE_OBJ
+ return checkCase->isChecked();
+}
+
+void FindWidget::setPalette(bool found)
+{
+ TRACE_OBJ
+ QPalette palette = editFind->palette();
+ palette.setColor(QPalette::Active, QPalette::Base, found ? Qt::white
+ : QColor(255, 102, 102));
+ editFind->setPalette(palette);
+}
+
+void FindWidget::setTextWrappedVisible(bool visible)
+{
+ TRACE_OBJ
+ labelWrapped->setVisible(visible);
+}
+
+void FindWidget::hideEvent(QHideEvent* event)
+{
+ TRACE_OBJ
+#if !defined(QT_NO_WEBKIT)
+ // TODO: remove this once webkit supports setting the palette
+ if (!event->spontaneous())
+ qApp->setPalette(appPalette);
+#else
+ Q_UNUSED(event);
+#endif
+}
+
+void FindWidget::showEvent(QShowEvent* event)
+{
+ TRACE_OBJ
+#if !defined(QT_NO_WEBKIT)
+ // TODO: remove this once webkit supports setting the palette
+ if (!event->spontaneous()) {
+ QPalette p = appPalette;
+ p.setColor(QPalette::Inactive, QPalette::Highlight,
+ p.color(QPalette::Active, QPalette::Highlight));
+ p.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ p.color(QPalette::Active, QPalette::HighlightedText));
+ qApp->setPalette(p);
+ }
+#else
+ Q_UNUSED(event);
+#endif
+}
+
+void FindWidget::updateButtons()
+{
+ TRACE_OBJ
+ const bool enable = !editFind->text().isEmpty();
+ toolNext->setEnabled(enable);
+ toolPrevious->setEnabled(enable);
+}
+
+void FindWidget::textChanged(const QString &text)
+{
+ TRACE_OBJ
+ emit find(text, true);
+}
+
+bool FindWidget::eventFilter(QObject *object, QEvent *e)
+{
+ TRACE_OBJ
+ if (e->type() == QEvent::KeyPress) {
+ if ((static_cast<QKeyEvent*>(e))->key() == Qt::Key_Escape) {
+ hide();
+ emit escapePressed();
+ }
+ }
+ return QWidget::eventFilter(object, e);
+}
+
+QToolButton* FindWidget::setupToolButton(const QString &text, const QString &icon)
+{
+ TRACE_OBJ
+ QToolButton *toolButton = new QToolButton(this);
+
+ toolButton->setText(text);
+ toolButton->setAutoRaise(true);
+ toolButton->setIcon(QIcon(icon));
+ toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+
+ return toolButton;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/findwidget.h b/tools/assistant/tools/assistant/findwidget.h
new file mode 100644
index 0000000..cf78003
--- /dev/null
+++ b/tools/assistant/tools/assistant/findwidget.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef FINDWIDGET_H
+#define FINDWIDGET_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QCheckBox;
+class QLabel;
+class QLineEdit;
+class QToolButton;
+
+class FindWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ FindWidget(QWidget *parent = 0);
+ ~FindWidget();
+
+ void show();
+ void showAndClear();
+
+ QString text() const;
+ bool caseSensitive() const;
+
+ void setPalette(bool found);
+ void setTextWrappedVisible(bool visible);
+
+signals:
+ void escapePressed();
+
+ void findNext();
+ void findPrevious();
+ void find(const QString &text, bool forward);
+
+protected:
+ void hideEvent(QHideEvent* event);
+ void showEvent(QShowEvent * event);
+
+private slots:
+ void updateButtons();
+ void textChanged(const QString &text);
+
+private:
+ bool eventFilter(QObject *object, QEvent *e);
+ QToolButton* setupToolButton(const QString &text, const QString &icon);
+
+private:
+ QPalette appPalette;
+
+ QLineEdit *editFind;
+ QCheckBox *checkCase;
+ QLabel *labelWrapped;
+ QToolButton *toolNext;
+ QToolButton *toolClose;
+ QToolButton *toolPrevious;
+};
+
+QT_END_NAMESPACE
+
+#endif // FINDWIDGET_H
diff --git a/tools/assistant/tools/assistant/helpenginewrapper.cpp b/tools/assistant/tools/assistant/helpenginewrapper.cpp
index ddc056a..76211c5 100644
--- a/tools/assistant/tools/assistant/helpenginewrapper.cpp
+++ b/tools/assistant/tools/assistant/helpenginewrapper.cpp
@@ -103,7 +103,7 @@ private:
HelpEngineWrapperPrivate(const QString &collectionFile);
void initFileSystemWatchers();
- void assertDocFilesWatched();
+ void checkDocFilesWatched();
void qchFileChanged(const QString &fileName, bool fromTimeout);
static const int UpdateGracePeriod = 2000;
@@ -202,23 +202,23 @@ const QString HelpEngineWrapper::collectionFile() const
bool HelpEngineWrapper::registerDocumentation(const QString &docFile)
{
TRACE_OBJ
- d->assertDocFilesWatched();
+ d->checkDocFilesWatched();
if (!d->m_helpEngine->registerDocumentation(docFile))
return false;
d->m_qchWatcher->addPath(docFile);
- d->assertDocFilesWatched();
+ d->checkDocFilesWatched();
return true;
}
bool HelpEngineWrapper::unregisterDocumentation(const QString &namespaceName)
{
TRACE_OBJ
- d->assertDocFilesWatched();
+ d->checkDocFilesWatched();
const QString &file = d->m_helpEngine->documentationFileName(namespaceName);
if (!d->m_helpEngine->unregisterDocumentation(namespaceName))
return false;
d->m_qchWatcher->removePath(file);
- d->assertDocFilesWatched();
+ d->checkDocFilesWatched();
return true;
}
@@ -715,7 +715,7 @@ void HelpEngineWrapperPrivate::initFileSystemWatchers()
connect(m_qchWatcher, SIGNAL(fileChanged(QString)),
this, SLOT(qchFileChanged(QString)));
}
- assertDocFilesWatched();
+ checkDocFilesWatched();
}
void HelpEngineWrapperPrivate::qchFileChanged(const QString &fileName)
@@ -724,11 +724,15 @@ void HelpEngineWrapperPrivate::qchFileChanged(const QString &fileName)
qchFileChanged(fileName, false);
}
-void HelpEngineWrapperPrivate::assertDocFilesWatched()
+void HelpEngineWrapperPrivate::checkDocFilesWatched()
{
TRACE_OBJ
- Q_ASSERT(m_qchWatcher->files().count()
- == m_helpEngine->registeredDocumentations().count());
+ const int watchedFilesCount = m_qchWatcher->files().count();
+ const int docFilesCount = m_helpEngine->registeredDocumentations().count();
+ if (watchedFilesCount != docFilesCount) {
+ qWarning("Strange: Have %d docs, but %d are being watched",
+ watchedFilesCount, docFilesCount);
+ }
}
void HelpEngineWrapperPrivate::qchFileChanged(const QString &fileName,