diff options
author | Martin Smith <msmith@trolltech.com> | 2010-03-24 15:20:55 (GMT) |
---|---|---|
committer | Martin Smith <msmith@trolltech.com> | 2010-03-24 15:20:55 (GMT) |
commit | 6c8c62f470e31ff2f74e2a5d3ba71d36da5f6d77 (patch) | |
tree | c93d39ffb5fadb25851eb52cb3974095ecbccfea | |
parent | 47efbddaa17b9c898eb406b8b39627f78b3c2ecf (diff) | |
parent | 26b572903a800163972817cd717b5df454b96eb2 (diff) | |
download | Qt-6c8c62f470e31ff2f74e2a5d3ba71d36da5f6d77.zip Qt-6c8c62f470e31ff2f74e2a5d3ba71d36da5f6d77.tar.gz Qt-6c8c62f470e31ff2f74e2a5d3ba71d36da5f6d77.tar.bz2 |
Merge branch '4.7' of git@scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7
-rw-r--r-- | src/gui/kernel/qapplication_x11.cpp | 7 | ||||
-rw-r--r-- | src/gui/kernel/qt_x11_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_x11.cpp | 24 | ||||
-rw-r--r-- | src/gui/widgets/qsplitter.cpp | 32 | ||||
-rw-r--r-- | src/gui/widgets/qsplitter.h | 1 | ||||
-rw-r--r-- | src/plugins/imageformats/jpeg/qjpeghandler.cpp | 396 | ||||
-rw-r--r-- | src/plugins/imageformats/jpeg/qjpeghandler.h | 7 | ||||
-rw-r--r-- | src/script/api/qscriptengine.cpp | 1 | ||||
-rw-r--r-- | src/script/api/qscriptengine.h | 1 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 12 | ||||
-rw-r--r-- | src/script/api/qscriptvalueiterator.cpp | 1 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp | 87 | ||||
-rw-r--r-- | tests/auto/qshortcut/tst_qshortcut.cpp | 2 | ||||
-rw-r--r-- | tools/designer/src/components/propertyeditor/propertyeditor.cpp | 67 | ||||
-rw-r--r-- | tools/designer/src/components/propertyeditor/propertyeditor.h | 5 |
16 files changed, 435 insertions, 213 deletions
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index ea44173..78fc704 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -275,6 +275,8 @@ static const char * x11_atomnames = { "_NET_SYSTEM_TRAY_VISUAL\0" + "_NET_ACTIVE_WINDOW\0" + // Property formats "COMPOUND_TEXT\0" "TEXT\0" @@ -667,11 +669,6 @@ static int qt_x_errhandler(Display *dpy, XErrorEvent *err) return 0; break; - case BadMatch: - if (err->request_code == 42 /* X_SetInputFocus */) - return 0; - break; - default: #if !defined(QT_NO_XINPUT) if (err->request_code == X11->xinput_major diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index e1b2625..7383382 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -632,6 +632,8 @@ struct QX11Data _NET_SYSTEM_TRAY_VISUAL, + _NET_ACTIVE_WINDOW, + // Property formats COMPOUND_TEXT, TEXT, diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 2266379..37ac6bf 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -1641,7 +1641,29 @@ void QWidget::activateWindow() if (X11->userTime == 0) X11->userTime = X11->time; qt_net_update_user_time(tlw, X11->userTime); - XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time); + + if (X11->isSupportedByWM(ATOM(_NET_ACTIVE_WINDOW)) + && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)) { + XEvent e; + e.xclient.type = ClientMessage; + e.xclient.message_type = ATOM(_NET_ACTIVE_WINDOW); + e.xclient.display = X11->display; + e.xclient.window = tlw->internalWinId(); + e.xclient.format = 32; + e.xclient.data.l[0] = 1; // 1 == application + e.xclient.data.l[1] = X11->userTime; + if (QWidget *aw = QApplication::activeWindow()) + e.xclient.data.l[2] = aw->internalWinId(); + else + e.xclient.data.l[2] = XNone; + e.xclient.data.l[3] = 0; + e.xclient.data.l[4] = 0; + XSendEvent(X11->display, RootWindow(X11->display, tlw->x11Info().screen()), + false, SubstructureNotifyMask | SubstructureRedirectMask, &e); + } else { + if (!qt_widget_private(tlw)->topData()->waitingForMapNotify) + XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time); + } } } diff --git a/src/gui/widgets/qsplitter.cpp b/src/gui/widgets/qsplitter.cpp index 597b28b..88b7517 100644 --- a/src/gui/widgets/qsplitter.cpp +++ b/src/gui/widgets/qsplitter.cpp @@ -227,6 +227,33 @@ QSize QSplitterHandle::sizeHint() const /*! \reimp */ +void QSplitterHandle::resizeEvent(QResizeEvent *event) +{ + Q_D(const QSplitterHandle); + + // When splitters are only 1 pixel large we increase the + // actual grab area to five pixels + + // Note that QSplitter uses contentsRect for layouting + // and ensures that handles are drawn on top of widgets + // We simply use the contents margins for draggin and only + // paint the mask area + bool useTinyMode = (d->s->handleWidth() == 1); + setAttribute(Qt::WA_MouseNoMask, useTinyMode); + if (useTinyMode) { + if (orientation() == Qt::Horizontal) + setContentsMargins(2, 0, 2, 0); + else + setContentsMargins(0, 2, 0, 2); + setMask(QRegion(contentsRect())); + } + + QWidget::resizeEvent(event); +} + +/*! + \reimp +*/ bool QSplitterHandle::event(QEvent *event) { Q_D(QSplitterHandle); @@ -301,7 +328,7 @@ void QSplitterHandle::paintEvent(QPaintEvent *) Q_D(QSplitterHandle); QPainter p(this); QStyleOption opt(0); - opt.rect = rect(); + opt.rect = contentsRect(); opt.palette = palette(); if (orientation() == Qt::Horizontal) opt.state = QStyle::State_Horizontal; @@ -1662,6 +1689,9 @@ void QSplitter::setSizes(const QList<int> &list) By default, this property contains a value that depends on the user's platform and style preferences. + + If you set handleWidth to 1, the actual grab area will grow to overlap a + few pixels of it's respective widgets. */ int QSplitter::handleWidth() const diff --git a/src/gui/widgets/qsplitter.h b/src/gui/widgets/qsplitter.h index a793f24..c3b304d 100644 --- a/src/gui/widgets/qsplitter.h +++ b/src/gui/widgets/qsplitter.h @@ -172,6 +172,7 @@ protected: void mouseMoveEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); + void resizeEvent(QResizeEvent *); bool event(QEvent *); void moveSplitter(int p); diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index abe3ffe..93b7cc6 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -183,82 +183,34 @@ inline my_jpeg_source_mgr::my_jpeg_source_mgr(QIODevice *device) } -static bool read_jpeg_size(QIODevice *device, int &w, int &h) +inline static bool read_jpeg_size(int &w, int &h, j_decompress_ptr cinfo) { - bool rt = false; - struct jpeg_decompress_struct cinfo; + (void) jpeg_calc_output_dimensions(cinfo); - struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(device); - struct my_error_mgr jerr; - - jpeg_create_decompress(&cinfo); - - cinfo.src = iod_src; - - cinfo.err = jpeg_std_error(&jerr); - jerr.error_exit = my_error_exit; - - if (!setjmp(jerr.setjmp_buffer)) { -#if defined(Q_OS_UNIXWARE) - (void) jpeg_read_header(&cinfo, B_TRUE); -#else - (void) jpeg_read_header(&cinfo, true); -#endif - (void) jpeg_calc_output_dimensions(&cinfo); - - w = cinfo.output_width; - h = cinfo.output_height; - rt = true; - } - jpeg_destroy_decompress(&cinfo); - delete iod_src; - return rt; + w = cinfo->output_width; + h = cinfo->output_height; + return true; } #define HIGH_QUALITY_THRESHOLD 50 -static bool read_jpeg_format(QIODevice *device, QImage::Format &format) +inline static bool read_jpeg_format(QImage::Format &format, j_decompress_ptr cinfo) { - bool result = false; - struct jpeg_decompress_struct cinfo; - - struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(device); - struct my_error_mgr jerr; - - jpeg_create_decompress(&cinfo); - - cinfo.src = iod_src; - - cinfo.err = jpeg_std_error(&jerr); - jerr.error_exit = my_error_exit; - if (!setjmp(jerr.setjmp_buffer)) { -#if defined(Q_OS_UNIXWARE) - (void) jpeg_read_header(&cinfo, B_TRUE); -#else - (void) jpeg_read_header(&cinfo, true); -#endif - // This does not allocate memory for the whole image - // or such, so we are safe. - (void) jpeg_start_decompress(&cinfo); - result = true; - switch (cinfo.output_components) { - case 1: - format = QImage::Format_Indexed8; - break; - case 3: - case 4: - format = QImage::Format_RGB32; - break; - default: - result = false; - break; - } - cinfo.output_scanline = cinfo.output_height; - (void) jpeg_finish_decompress(&cinfo); + bool result = true; + switch (cinfo->output_components) { + case 1: + format = QImage::Format_Indexed8; + break; + case 3: + case 4: + format = QImage::Format_RGB32; + break; + default: + result = false; + break; } - jpeg_destroy_decompress(&cinfo); - delete iod_src; + cinfo->output_scanline = cinfo->output_height; return result; } @@ -291,29 +243,11 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, return !dest->isNull(); } -static bool read_jpeg_image(QIODevice *device, QImage *outImage, +static bool read_jpeg_image(QImage *outImage, QSize scaledSize, QRect scaledClipRect, - QRect clipRect, int inQuality ) + QRect clipRect, int inQuality, j_decompress_ptr info, struct my_error_mgr* err ) { - struct jpeg_decompress_struct cinfo; - - struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(device); - struct my_error_mgr jerr; - - jpeg_create_decompress(&cinfo); - - cinfo.src = iod_src; - - cinfo.err = jpeg_std_error(&jerr); - jerr.error_exit = my_error_exit; - - if (!setjmp(jerr.setjmp_buffer)) { -#if defined(Q_OS_UNIXWARE) - (void) jpeg_read_header(&cinfo, B_TRUE); -#else - (void) jpeg_read_header(&cinfo, true); -#endif - + if (!setjmp(err->setjmp_buffer)) { // -1 means default quality. int quality = inQuality; if (quality < 0) @@ -335,16 +269,16 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, } else if (clipRect.isEmpty()) { // No clipping, but scaling: if we can map back to an // integer pixel boundary, then clip before scaling. - if ((cinfo.image_width % scaledSize.width()) == 0 && - (cinfo.image_height % scaledSize.height()) == 0) { - int x = scaledClipRect.x() * cinfo.image_width / + if ((info->image_width % scaledSize.width()) == 0 && + (info->image_height % scaledSize.height()) == 0) { + int x = scaledClipRect.x() * info->image_width / scaledSize.width(); - int y = scaledClipRect.y() * cinfo.image_height / + int y = scaledClipRect.y() * info->image_height / scaledSize.height(); int width = (scaledClipRect.right() + 1) * - cinfo.image_width / scaledSize.width() - x; + info->image_width / scaledSize.width() - x; int height = (scaledClipRect.bottom() + 1) * - cinfo.image_height / scaledSize.height() - y; + info->image_height / scaledSize.height() - y; clipRect = QRect(x, y, width, height); scaledSize = scaledClipRect.size(); scaledClipRect = QRect(); @@ -358,69 +292,69 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, // Determine the scale factor to pass to libjpeg for quick downscaling. if (!scaledSize.isEmpty()) { if (clipRect.isEmpty()) { - cinfo.scale_denom = - qMin(cinfo.image_width / scaledSize.width(), - cinfo.image_height / scaledSize.height()); + info->scale_denom = + qMin(info->image_width / scaledSize.width(), + info->image_height / scaledSize.height()); } else { - cinfo.scale_denom = + info->scale_denom = qMin(clipRect.width() / scaledSize.width(), clipRect.height() / scaledSize.height()); } - if (cinfo.scale_denom < 2) { - cinfo.scale_denom = 1; - } else if (cinfo.scale_denom < 4) { - cinfo.scale_denom = 2; - } else if (cinfo.scale_denom < 8) { - cinfo.scale_denom = 4; + if (info->scale_denom < 2) { + info->scale_denom = 1; + } else if (info->scale_denom < 4) { + info->scale_denom = 2; + } else if (info->scale_denom < 8) { + info->scale_denom = 4; } else { - cinfo.scale_denom = 8; + info->scale_denom = 8; } - cinfo.scale_num = 1; + info->scale_num = 1; if (!clipRect.isEmpty()) { // Correct the scale factor so that we clip accurately. // It is recommended that the clip rectangle be aligned // on an 8-pixel boundary for best performance. - while (cinfo.scale_denom > 1 && - ((clipRect.x() % cinfo.scale_denom) != 0 || - (clipRect.y() % cinfo.scale_denom) != 0 || - (clipRect.width() % cinfo.scale_denom) != 0 || - (clipRect.height() % cinfo.scale_denom) != 0)) { - cinfo.scale_denom /= 2; + while (info->scale_denom > 1 && + ((clipRect.x() % info->scale_denom) != 0 || + (clipRect.y() % info->scale_denom) != 0 || + (clipRect.width() % info->scale_denom) != 0 || + (clipRect.height() % info->scale_denom) != 0)) { + info->scale_denom /= 2; } } } // If high quality not required, use fast decompression if( quality < HIGH_QUALITY_THRESHOLD ) { - cinfo.dct_method = JDCT_IFAST; - cinfo.do_fancy_upsampling = FALSE; + info->dct_method = JDCT_IFAST; + info->do_fancy_upsampling = FALSE; } - (void) jpeg_calc_output_dimensions(&cinfo); + (void) jpeg_calc_output_dimensions(info); // Determine the clip region to extract. - QRect imageRect(0, 0, cinfo.output_width, cinfo.output_height); + QRect imageRect(0, 0, info->output_width, info->output_height); QRect clip; if (clipRect.isEmpty()) { clip = imageRect; - } else if (cinfo.scale_denom == cinfo.scale_num) { + } else if (info->scale_denom == info->scale_num) { clip = clipRect.intersected(imageRect); } else { // The scale factor was corrected above to ensure that // we don't miss pixels when we scale the clip rectangle. - clip = QRect(clipRect.x() / int(cinfo.scale_denom), - clipRect.y() / int(cinfo.scale_denom), - clipRect.width() / int(cinfo.scale_denom), - clipRect.height() / int(cinfo.scale_denom)); + clip = QRect(clipRect.x() / int(info->scale_denom), + clipRect.y() / int(info->scale_denom), + clipRect.width() / int(info->scale_denom), + clipRect.height() / int(info->scale_denom)); clip = clip.intersected(imageRect); } // Allocate memory for the clipped QImage. - if (!ensureValidImage(outImage, &cinfo, clip.size())) - longjmp(jerr.setjmp_buffer, 1); + if (!ensureValidImage(outImage, info, clip.size())) + longjmp(err->setjmp_buffer, 1); // Avoid memcpy() overhead if grayscale with no clipping. - bool quickGray = (cinfo.output_components == 1 && + bool quickGray = (info->output_components == 1 && clip == imageRect); if (!quickGray) { // Ask the jpeg library to allocate a temporary row. @@ -429,23 +363,23 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, // jpeg_start_decompress(). We can't use "new" here // because we are inside the setjmp() block and an error // in the jpeg input stream would cause a memory leak. - JSAMPARRAY rows = (cinfo.mem->alloc_sarray) - ((j_common_ptr)&cinfo, JPOOL_IMAGE, - cinfo.output_width * cinfo.output_components, 1); + JSAMPARRAY rows = (info->mem->alloc_sarray) + ((j_common_ptr)info, JPOOL_IMAGE, + info->output_width * info->output_components, 1); - (void) jpeg_start_decompress(&cinfo); + (void) jpeg_start_decompress(info); - while (cinfo.output_scanline < cinfo.output_height) { - int y = int(cinfo.output_scanline) - clip.y(); + while (info->output_scanline < info->output_height) { + int y = int(info->output_scanline) - clip.y(); if (y >= clip.height()) break; // We've read the entire clip region, so abort. - (void) jpeg_read_scanlines(&cinfo, rows, 1); + (void) jpeg_read_scanlines(info, rows, 1); if (y < 0) continue; // Haven't reached the starting line yet. - if (cinfo.output_components == 3) { + if (info->output_components == 3) { // Expand 24->32 bpp. uchar *in = rows[0] + clip.x() * 3; QRgb *out = (QRgb*)outImage->scanLine(y); @@ -453,7 +387,7 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, *out++ = qRgb(in[0], in[1], in[2]); in += 3; } - } else if (cinfo.out_color_space == JCS_CMYK) { + } else if (info->out_color_space == JCS_CMYK) { // Convert CMYK->RGB. uchar *in = rows[0] + clip.x() * 4; QRgb *out = (QRgb*)outImage->scanLine(y); @@ -463,7 +397,7 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, k * in[2] / 255); in += 4; } - } else if (cinfo.output_components == 1) { + } else if (info->output_components == 1) { // Grayscale. memcpy(outImage->scanLine(y), rows[0] + clip.x(), clip.width()); @@ -471,37 +405,36 @@ static bool read_jpeg_image(QIODevice *device, QImage *outImage, } } else { // Load unclipped grayscale data directly into the QImage. - (void) jpeg_start_decompress(&cinfo); - while (cinfo.output_scanline < cinfo.output_height) { - uchar *row = outImage->scanLine(cinfo.output_scanline); - (void) jpeg_read_scanlines(&cinfo, &row, 1); + (void) jpeg_start_decompress(info); + while (info->output_scanline < info->output_height) { + uchar *row = outImage->scanLine(info->output_scanline); + (void) jpeg_read_scanlines(info, &row, 1); } } - if (cinfo.output_scanline == cinfo.output_height) - (void) jpeg_finish_decompress(&cinfo); + if (info->output_scanline == info->output_height) + (void) jpeg_finish_decompress(info); - if (cinfo.density_unit == 1) { - outImage->setDotsPerMeterX(int(100. * cinfo.X_density / 2.54)); - outImage->setDotsPerMeterY(int(100. * cinfo.Y_density / 2.54)); - } else if (cinfo.density_unit == 2) { - outImage->setDotsPerMeterX(int(100. * cinfo.X_density)); - outImage->setDotsPerMeterY(int(100. * cinfo.Y_density)); + if (info->density_unit == 1) { + outImage->setDotsPerMeterX(int(100. * info->X_density / 2.54)); + outImage->setDotsPerMeterY(int(100. * info->Y_density / 2.54)); + } else if (info->density_unit == 2) { + outImage->setDotsPerMeterX(int(100. * info->X_density)); + outImage->setDotsPerMeterY(int(100. * info->Y_density)); } if (scaledSize.isValid() && scaledSize != clip.size()) { *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, quality >= HIGH_QUALITY_THRESHOLD ? Qt::SmoothTransformation : Qt::FastTransformation); } - } - jpeg_destroy_decompress(&cinfo); - delete iod_src; - if (!scaledClipRect.isEmpty()) - *outImage = outImage->copy(scaledClipRect); - return !outImage->isNull(); + if (!scaledClipRect.isEmpty()) + *outImage = outImage->copy(scaledClipRect); + return !outImage->isNull(); + } + else + return false; } - struct my_jpeg_destination_mgr : public jpeg_destination_mgr { // Nothing dynamic - cannot rely on destruction over longjump QIODevice *device; @@ -745,18 +678,124 @@ static bool write_jpeg_image(const QImage &sourceImage, QIODevice *device, int s return success; } +class QJpegHandlerPrivate +{ +public: + enum State { + Ready, + ReadHeader, + Error + }; + + QJpegHandlerPrivate(QJpegHandler *qq) + : quality(75), iod_src(0), state(Ready), q(qq) + {} + + ~QJpegHandlerPrivate() + { + if(iod_src) + { + jpeg_destroy_decompress(&info); + delete iod_src; + iod_src = 0; + } + } + + bool readJpegHeader(QIODevice*); + bool read(QImage *image); + + int quality; + QVariant size; + QImage::Format format; + QSize scaledSize; + QRect scaledClipRect; + QRect clipRect; + struct jpeg_decompress_struct info; + struct my_jpeg_source_mgr * iod_src; + struct my_error_mgr err; + + State state; + + QJpegHandler *q; +}; + +/*! + \internal +*/ +bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) +{ + if(state == Ready) + { + state = Error; + iod_src = new my_jpeg_source_mgr(device); + + jpeg_create_decompress(&info); + info.src = iod_src; + info.err = jpeg_std_error(&err); + err.error_exit = my_error_exit; + + if (!setjmp(err.setjmp_buffer)) { + #if defined(Q_OS_UNIXWARE) + (void) jpeg_read_header(&info, B_TRUE); + #else + (void) jpeg_read_header(&info, true); + #endif + + int width = 0; + int height = 0; + read_jpeg_size(width, height, &info); + size = QSize(width, height); + + format = QImage::Format_Invalid; + read_jpeg_format(format, &info); + state = ReadHeader; + return true; + } + else + { + return false; + } + } + else if(state == Error) + return false; + return true; +} + +bool QJpegHandlerPrivate::read(QImage *image) +{ + if(state == Ready) + readJpegHeader(q->device()); + + if(state == ReadHeader) + { + bool success = read_jpeg_image(image, scaledSize, scaledClipRect, clipRect, quality, &info, &err); + state = success ? Ready : Error; + return success; + } + + return false; + +} + QJpegHandler::QJpegHandler() + : d(new QJpegHandlerPrivate(this)) +{ +} + +QJpegHandler::~QJpegHandler() { - quality = 75; + delete d; } bool QJpegHandler::canRead() const { - if (canRead(device())) { + if(d->state == QJpegHandlerPrivate::Ready) { + if (!canRead(device())) + return false; setFormat("jpeg"); return true; } - return false; + return d->state != QJpegHandlerPrivate::Error; } bool QJpegHandler::canRead(QIODevice *device) @@ -769,7 +808,6 @@ bool QJpegHandler::canRead(QIODevice *device) char buffer[2]; if (device->peek(buffer, 2) != 2) return false; - return uchar(buffer[0]) == 0xff && uchar(buffer[1]) == 0xd8; } @@ -777,12 +815,12 @@ bool QJpegHandler::read(QImage *image) { if (!canRead()) return false; - return read_jpeg_image(device(), image, scaledSize, scaledClipRect, clipRect, quality); + return d->read(image); } bool QJpegHandler::write(const QImage &image) { - return write_jpeg_image(image, device(), quality); + return write_jpeg_image(image, device(), d->quality); } bool QJpegHandler::supportsOption(ImageOption option) const @@ -799,32 +837,19 @@ QVariant QJpegHandler::option(ImageOption option) const { switch(option) { case Quality: - return quality; + return d->quality; case ScaledSize: - return scaledSize; + return d->scaledSize; case ScaledClipRect: - return scaledClipRect; + return d->scaledClipRect; case ClipRect: - return clipRect; + return d->clipRect; case Size: - if (canRead() && !device()->isSequential()) { - qint64 pos = device()->pos(); - int width = 0; - int height = 0; - read_jpeg_size(device(), width, height); - device()->seek(pos); - return QSize(width, height); - } - return QVariant(); + d->readJpegHeader(device()); + return d->size; case ImageFormat: - if (canRead() && !device()->isSequential()) { - qint64 pos = device()->pos(); - QImage::Format format = QImage::Format_Invalid; - read_jpeg_format(device(), format); - device()->seek(pos); - return format; - } - return QImage::Format_Invalid; + d->readJpegHeader(device()); + return d->format; default: return QVariant(); } @@ -834,16 +859,16 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value) { switch(option) { case Quality: - quality = value.toInt(); + d->quality = value.toInt(); break; case ScaledSize: - scaledSize = value.toSize(); + d->scaledSize = value.toSize(); break; case ScaledClipRect: - scaledClipRect = value.toRect(); + d->scaledClipRect = value.toRect(); break; case ClipRect: - clipRect = value.toRect(); + d->clipRect = value.toRect(); break; default: break; @@ -855,4 +880,7 @@ QByteArray QJpegHandler::name() const return "jpeg"; } + + + QT_END_NAMESPACE diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.h b/src/plugins/imageformats/jpeg/qjpeghandler.h index dfb6b47..c879f21 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.h +++ b/src/plugins/imageformats/jpeg/qjpeghandler.h @@ -48,10 +48,12 @@ QT_BEGIN_NAMESPACE +class QJpegHandlerPrivate; class QJpegHandler : public QImageIOHandler { public: QJpegHandler(); + ~QJpegHandler(); bool canRead() const; bool read(QImage *image); @@ -66,10 +68,7 @@ public: bool supportsOption(ImageOption option) const; private: - int quality; - QSize scaledSize; - QRect scaledClipRect; - QRect clipRect; + QJpegHandlerPrivate *d; }; QT_END_NAMESPACE diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 356b4d0..2650d7f 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -292,6 +292,7 @@ QT_BEGIN_NAMESPACE \value ExcludeSuperClassProperties The script object will not expose properties inherited from the superclass. \value ExcludeSuperClassContents Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties \value ExcludeDeleteLater The script object will not expose the QObject::deleteLater() slot. + \value ExcludeSlots The script object will not expose the QObject's slots. \value AutoCreateDynamicProperties Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object. \value PreferExistingWrapperObject If a wrapper object with the requested configuration already exists, return that object. \value SkipMethodsInEnumeration Don't include methods (signals and slots) when enumerating the object's properties. diff --git a/src/script/api/qscriptengine.h b/src/script/api/qscriptengine.h index 2ce3183..76461bc 100644 --- a/src/script/api/qscriptengine.h +++ b/src/script/api/qscriptengine.h @@ -125,6 +125,7 @@ public: ExcludeSuperClassContents = 0x0006, SkipMethodsInEnumeration = 0x0008, ExcludeDeleteLater = 0x0010, + ExcludeSlots = 0x0020, AutoCreateDynamicProperties = 0x0100, PreferExistingWrapperObject = 0x0200 diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 5db1165..3fe0e7d 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -1505,8 +1505,9 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, const QScriptValueList &args) { Q_D(const QScriptValue); - if (!d || !d->isJSC()) + if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::JSValue callee = d->jscValue; JSC::CallData callData; JSC::CallType callType = callee.getCallData(callData); @@ -1582,8 +1583,9 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, const QScriptValue &arguments) { Q_D(QScriptValue); - if (!d || !d->isJSC()) + if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::JSValue callee = d->jscValue; JSC::CallData callData; JSC::CallType callType = callee.getCallData(callData); @@ -1656,8 +1658,9 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, QScriptValue QScriptValue::construct(const QScriptValueList &args) { Q_D(const QScriptValue); - if (!d || !d->isJSC()) + if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::JSValue callee = d->jscValue; JSC::ConstructData constructData; JSC::ConstructType constructType = callee.getConstructData(constructData); @@ -1705,8 +1708,9 @@ QScriptValue QScriptValue::construct(const QScriptValueList &args) QScriptValue QScriptValue::construct(const QScriptValue &arguments) { Q_D(QScriptValue); - if (!d || !d->isJSC()) + if (!d || !d->isObject()) return QScriptValue(); + QScript::APIShim shim(d->engine); JSC::JSValue callee = d->jscValue; JSC::ConstructData constructData; JSC::ConstructType constructType = callee.getConstructData(constructData); diff --git a/src/script/api/qscriptvalueiterator.cpp b/src/script/api/qscriptvalueiterator.cpp index 5c1e6f2..7fd7093 100644 --- a/src/script/api/qscriptvalueiterator.cpp +++ b/src/script/api/qscriptvalueiterator.cpp @@ -100,6 +100,7 @@ public: if (initialized) return; QScriptEnginePrivate *eng_p = engine(); + QScript::APIShim shim(eng_p); JSC::ExecState *exec = eng_p->globalExec(); JSC::PropertyNameArray propertyNamesArray(exec); JSC::asObject(object()->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, JSC::IncludeDontEnumProperties); diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 765e074..83a811b 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -151,7 +151,8 @@ private: static bool hasMethodAccess(const QMetaMethod &method, int index, const QScriptEngine::QObjectWrapOptions &opt) { return (method.access() != QMetaMethod::Private) - && ((index != 2) || !(opt & QScriptEngine::ExcludeDeleteLater)); + && ((index != 2) || !(opt & QScriptEngine::ExcludeDeleteLater)) + && (!(opt & QScriptEngine::ExcludeSlots) || (method.methodType() != QMetaMethod::Slot)); } static bool isEnumerableMetaProperty(const QMetaProperty &prop, diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp index b4ce561..c1496f7 100644 --- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp +++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp @@ -533,6 +533,7 @@ private slots: void objectDeleted(); void connectToDestroyedSignal(); void emitAfterReceiverDeleted(); + void inheritedSlots(); private: QScriptEngine *m_engine; @@ -2658,6 +2659,21 @@ void tst_QScriptExtQObject::enumerate_data() << "mySignal()" // slots << "mySlot()" << "myOtherSlot()"); + + QTest::newRow( "don't enumerate slots" ) + << int(QScriptEngine::ExcludeSlots) + << (QStringList() + // meta-object-defined properties: + // inherited + << "objectName" + // non-inherited + << "p1" << "p2" << "p4" << "p6" + // dynamic properties + << "dp1" << "dp2" << "dp3" + // inherited signals + << "destroyed(QObject*)" << "destroyed()" + // signals + << "mySignal()"); } void tst_QScriptExtQObject::enumerate() @@ -2850,6 +2866,28 @@ void tst_QScriptExtQObject::wrapOptions() QVERIFY(obj.property("intProperty").isValid()); QVERIFY(obj.propertyFlags("intProperty") & QScriptValue::QObjectMember); } + // exclude slots + { + QScriptValue obj = m_engine->newQObject(m_myObject, QScriptEngine::QtOwnership, + QScriptEngine::ExcludeSlots); + QVERIFY(!obj.property("deleteLater").isValid()); + QVERIFY(!(obj.propertyFlags("deleteLater") & QScriptValue::QObjectMember)); + QVERIFY(!obj.property("mySlot").isValid()); + QVERIFY(!(obj.propertyFlags("mySlot") & QScriptValue::QObjectMember)); + + QVERIFY(obj.property("myInvokable").isFunction()); + QVERIFY(obj.propertyFlags("myInvokable") & QScriptValue::QObjectMember); + + QVERIFY(obj.property("mySignal").isFunction()); + QVERIFY(obj.propertyFlags("mySignal") & QScriptValue::QObjectMember); + QVERIFY(obj.property("destroyed").isFunction()); + QVERIFY(obj.propertyFlags("destroyed") & QScriptValue::QObjectMember); + + QVERIFY(obj.property("objectName").isValid()); + QVERIFY(obj.propertyFlags("objectName") & QScriptValue::QObjectMember); + QVERIFY(obj.property("intProperty").isValid()); + QVERIFY(obj.propertyFlags("intProperty") & QScriptValue::QObjectMember); + } // exclude all that we can { QScriptValue obj = m_engine->newQObject(m_myObject, QScriptEngine::QtOwnership, @@ -2871,6 +2909,33 @@ void tst_QScriptExtQObject::wrapOptions() QCOMPARE(obj.property("child") .strictlyEquals(QScriptValue(m_engine, 123)), true); } + // exclude absolutely all that we can + { + QScriptValue obj = m_engine->newQObject(m_myObject, QScriptEngine::QtOwnership, + QScriptEngine::ExcludeSuperClassMethods + | QScriptEngine::ExcludeSuperClassProperties + | QScriptEngine::ExcludeChildObjects + | QScriptEngine::ExcludeSlots); + QVERIFY(!obj.property("deleteLater").isValid()); + QVERIFY(!(obj.propertyFlags("deleteLater") & QScriptValue::QObjectMember)); + + QVERIFY(!obj.property("mySlot").isValid()); + QVERIFY(!(obj.propertyFlags("mySlot") & QScriptValue::QObjectMember)); + + QVERIFY(obj.property("mySignal").isFunction()); + QVERIFY(obj.propertyFlags("mySignal") & QScriptValue::QObjectMember); + + QVERIFY(obj.property("myInvokable").isFunction()); + QVERIFY(obj.propertyFlags("myInvokable") & QScriptValue::QObjectMember); + + QVERIFY(!obj.property("objectName").isValid()); + QVERIFY(!(obj.propertyFlags("objectName") & QScriptValue::QObjectMember)); + + QVERIFY(obj.property("intProperty").isValid()); + QVERIFY(obj.propertyFlags("intProperty") & QScriptValue::QObjectMember); + + QVERIFY(!obj.property("child").isValid()); + } delete child; } @@ -3043,5 +3108,27 @@ void tst_QScriptExtQObject::emitAfterReceiverDeleted() } } +void tst_QScriptExtQObject::inheritedSlots() +{ + QScriptEngine eng; + + QPushButton prototypeButton; + QScriptValue scriptPrototypeButton = eng.newQObject(&prototypeButton); + + QPushButton button; + QScriptValue scriptButton = eng.newQObject(&button, QScriptEngine::QtOwnership, + QScriptEngine::ExcludeSlots); + scriptButton.setPrototype(scriptPrototypeButton); + + QVERIFY(scriptButton.property("click").isFunction()); + QVERIFY(scriptButton.property("click").strictlyEquals(scriptPrototypeButton.property("click"))); + + QSignalSpy prototypeButtonClickedSpy(&prototypeButton, SIGNAL(clicked())); + QSignalSpy buttonClickedSpy(&button, SIGNAL(clicked())); + scriptButton.property("click").call(scriptButton); + QCOMPARE(buttonClickedSpy.count(), 1); + QCOMPARE(prototypeButtonClickedSpy.count(), 0); +} + QTEST_MAIN(tst_QScriptExtQObject) #include "tst_qscriptextqobject.moc" diff --git a/tests/auto/qshortcut/tst_qshortcut.cpp b/tests/auto/qshortcut/tst_qshortcut.cpp index 39518c5..6df4cc4 100644 --- a/tests/auto/qshortcut/tst_qshortcut.cpp +++ b/tests/auto/qshortcut/tst_qshortcut.cpp @@ -224,10 +224,10 @@ void tst_QShortcut::initTestCase() mainW->setFixedSize( 100, 100 ); mainW->setCentralWidget( edit ); mainW->show(); - mainW->activateWindow(); #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(mainW); #endif + mainW->activateWindow(); QTest::qWait(100); connect( mainW->statusBar(), SIGNAL(messageChanged(const QString&)), this, SLOT(statusMessage(const QString&)) ); diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.cpp b/tools/designer/src/components/propertyeditor/propertyeditor.cpp index 512cc82..86d7bdf 100644 --- a/tools/designer/src/components/propertyeditor/propertyeditor.cpp +++ b/tools/designer/src/components/propertyeditor/propertyeditor.cpp @@ -79,6 +79,7 @@ #include <QtGui/QToolButton> #include <QtGui/QActionGroup> #include <QtGui/QLabel> +#include <QtGui/QPainter> #include <QtCore/QDebug> #include <QtCore/QTextStream> @@ -98,6 +99,53 @@ QT_BEGIN_NAMESPACE // --------------------------------------------------------------------------------- namespace qdesigner_internal { + +// ----------- ElidingLabel +// QLabel does not support text eliding so we need a helper class + +class ElidingLabel : public QWidget +{ +public: + ElidingLabel(const QString &text = QString(), QWidget *parent = 0) + : QWidget(parent), + m_text(text), + m_mode(Qt::ElideRight) { + setContentsMargins(3, 2, 3, 2); + } + QSize sizeHint() const; + void paintEvent(QPaintEvent *e); + void setText(const QString &text) { + m_text = text; + updateGeometry(); + } + void setElidemode(Qt::TextElideMode mode) { + m_mode = mode; + updateGeometry(); + } +private: + QString m_text; + Qt::TextElideMode m_mode; +}; + +QSize ElidingLabel::sizeHint() const +{ + QSize size = fontMetrics().boundingRect(m_text).size(); + size += QSize(contentsMargins().left() + contentsMargins().right(), + contentsMargins().top() + contentsMargins().bottom()); + return size; +} + +void ElidingLabel::paintEvent(QPaintEvent *e) { + QPainter painter(this); + painter.setPen(QColor(0, 0, 0, 60)); + painter.setBrush(QColor(255, 255, 255, 40)); + painter.drawRect(rect().adjusted(0, 0, -1, -1)); + painter.setPen(palette().windowText().color()); + painter.drawText(contentsRect(), Qt::AlignLeft, + fontMetrics().elidedText(m_text, Qt::ElideRight, width(), 0)); +} + + // ----------- PropertyEditor::Strings PropertyEditor::Strings::Strings() : @@ -186,7 +234,7 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare m_coloringAction(new QAction(createIconSet(QLatin1String("color.png")), tr("Color Groups"), this)), m_treeAction(new QAction(tr("Tree View"), this)), m_buttonAction(new QAction(tr("Drop Down Button View"), this)), - m_classLabel(new QLabel), + m_classLabel(new ElidingLabel), m_sorting(false), m_coloring(false), m_brightness(false) @@ -223,11 +271,6 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare actionGroup->addAction(m_buttonAction); connect(actionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotViewTriggered(QAction*))); - QWidget *classWidget = new QWidget; - QHBoxLayout *l = new QHBoxLayout(classWidget); - l->setContentsMargins(5, 0, 5, 0); - l->addWidget(m_classLabel); - // Add actions QActionGroup *addDynamicActionGroup = new QActionGroup(this); connect(addDynamicActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotAddDynamicProperty(QAction*))); @@ -269,7 +312,6 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare #endif // Assemble toolbar QToolBar *toolBar = new QToolBar; - toolBar->addWidget(classWidget); toolBar->addWidget(m_filterWidget); toolBar->addWidget(createDropDownButton(m_addDynamicAction)); toolBar->addAction(m_removeDynamicAction); @@ -292,6 +334,8 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(toolBar); + layout->addWidget(m_classLabel); + layout->addSpacerItem(new QSpacerItem(0,1)); layout->addWidget(m_stackedWidget); layout->setMargin(0); layout->setSpacing(0); @@ -778,9 +822,14 @@ void PropertyEditor::updateToolBarLabel() className = realClassName(m_object); } - QString classLabelText = objectName; - classLabelText += QLatin1Char('\n'); + m_classLabel->setVisible(!objectName.isEmpty() || !className.isEmpty()); + m_classLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + QString classLabelText; + if (!objectName.isEmpty()) + classLabelText += objectName + QLatin1String(" : "); classLabelText += className; + m_classLabel->setText(classLabelText); m_classLabel->setToolTip(tr("Object: %1\nClass: %2").arg(objectName).arg(className)); } diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.h b/tools/designer/src/components/propertyeditor/propertyeditor.h index 5869c94..f0ea94f 100644 --- a/tools/designer/src/components/propertyeditor/propertyeditor.h +++ b/tools/designer/src/components/propertyeditor/propertyeditor.h @@ -62,9 +62,7 @@ class QtTreePropertyBrowser; class QtProperty; class QtVariantProperty; class QtBrowserItem; - class QStackedWidget; -class QLabel; namespace qdesigner_internal { @@ -72,6 +70,7 @@ class StringProperty; class DesignerPropertyManager; class DesignerEditorFactory; class FilterWidget; +class ElidingLabel; class QT_PROPERTYEDITOR_EXPORT PropertyEditor: public QDesignerPropertyEditor { @@ -186,7 +185,7 @@ private: QAction *m_coloringAction; QAction *m_treeAction; QAction *m_buttonAction; - QLabel *m_classLabel; + ElidingLabel *m_classLabel; bool m_sorting; bool m_coloring; |