mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-08 15:16:34 +02:00
Update Qocoa QSearchField to latest, with hatstand's fix.
Now shortcuts work in the QSearchField, like c&p and select all
This commit is contained in:
13
src/libtomahawk/thirdparty/Qocoa/qocoa_mac.h
vendored
13
src/libtomahawk/thirdparty/Qocoa/qocoa_mac.h
vendored
@@ -30,7 +30,8 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
static inline NSString* fromQString(const QString &string)
|
static inline NSString* fromQString(const QString &string)
|
||||||
{
|
{
|
||||||
char* cString = string.toUtf8().data();
|
const QByteArray utf8 = string.toUtf8();
|
||||||
|
const char* cString = utf8.constData();
|
||||||
return [[NSString alloc] initWithUTF8String:cString];
|
return [[NSString alloc] initWithUTF8String:cString];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,11 +42,17 @@ static inline QString toQString(NSString *string)
|
|||||||
return QString::fromUtf8([string UTF8String]);
|
return QString::fromUtf8([string UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void zeroLayout(void *cocoaView, QWidget *parent)
|
static inline NSImage* fromQPixmap(const QPixmap &pixmap)
|
||||||
{
|
{
|
||||||
|
CGImageRef cgImage = pixmap.toMacCGImageRef();
|
||||||
|
return [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void setupLayout(void *cocoaView, QWidget *parent)
|
||||||
|
{
|
||||||
|
parent->setAttribute(Qt::WA_NativeWindow);
|
||||||
QVBoxLayout *layout = new QVBoxLayout(parent);
|
QVBoxLayout *layout = new QVBoxLayout(parent);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
parent->setAttribute(Qt::WA_NativeWindow);
|
|
||||||
layout->addWidget(new QMacCocoaViewContainer(cocoaView, parent));
|
layout->addWidget(new QMacCocoaViewContainer(cocoaView, parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
src/libtomahawk/thirdparty/Qocoa/qsearchfield.h
vendored
18
src/libtomahawk/thirdparty/Qocoa/qsearchfield.h
vendored
@@ -2,6 +2,7 @@
|
|||||||
#define QSEARCHFIELD_H
|
#define QSEARCHFIELD_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
#include "DllMacro.h"
|
#include "DllMacro.h"
|
||||||
|
|
||||||
@@ -9,23 +10,34 @@ class QSearchFieldPrivate;
|
|||||||
class DLLEXPORT QSearchField : public QWidget
|
class DLLEXPORT QSearchField : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QSearchField(QWidget* parent);
|
explicit QSearchField(QWidget *parent);
|
||||||
|
|
||||||
QString text() const;
|
QString text() const;
|
||||||
|
QString placeholderText() const;
|
||||||
|
void setFocus(Qt::FocusReason);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setText(const QString &text);
|
void setText(const QString &text);
|
||||||
void setPlaceholderText(const QString& text);
|
void setPlaceholderText(const QString& text);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
void selectAll();
|
||||||
|
void setFocus();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void textChanged(const QString &text);
|
void textChanged(const QString &text);
|
||||||
|
void editingFinished();
|
||||||
void returnPressed();
|
void returnPressed();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class QSearchFieldPrivate;
|
friend class QSearchFieldPrivate;
|
||||||
QSearchFieldPrivate *pimpl;
|
QPointer <QSearchFieldPrivate> pimpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QSEARCHFIELD_H
|
#endif // QSEARCHFIELD_H
|
||||||
|
147
src/libtomahawk/thirdparty/Qocoa/qsearchfield_mac.mm
vendored
147
src/libtomahawk/thirdparty/Qocoa/qsearchfield_mac.mm
vendored
@@ -30,42 +30,105 @@ THE SOFTWARE.
|
|||||||
#import "Foundation/NSNotification.h"
|
#import "Foundation/NSNotification.h"
|
||||||
#import "AppKit/NSSearchField.h"
|
#import "AppKit/NSSearchField.h"
|
||||||
|
|
||||||
class QSearchFieldPrivate
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
|
||||||
|
#define KEYCODE_A 0
|
||||||
|
#define KEYCODE_X 7
|
||||||
|
#define KEYCODE_C 8
|
||||||
|
#define KEYCODE_V 9
|
||||||
|
|
||||||
|
class QSearchFieldPrivate : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QSearchFieldPrivate(QSearchField *qSearchField, NSSearchField *nsSearchField)
|
QSearchFieldPrivate(QSearchField *qSearchField, NSSearchField *nsSearchField)
|
||||||
: qSearchField(qSearchField), nsSearchField(nsSearchField) {}
|
: QObject(qSearchField), qSearchField(qSearchField), nsSearchField(nsSearchField) {}
|
||||||
|
|
||||||
void textDidChange(const QString &text)
|
void textDidChange(const QString &text)
|
||||||
{
|
{
|
||||||
emit qSearchField->textChanged(text);
|
if (qSearchField)
|
||||||
|
emit qSearchField->textChanged(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void textDidEndEditing()
|
void textDidEndEditing()
|
||||||
{
|
{
|
||||||
emit qSearchField->returnPressed();
|
if (qSearchField)
|
||||||
|
emit qSearchField->editingFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSearchField *qSearchField;
|
void returnPressed()
|
||||||
|
{
|
||||||
|
if (qSearchField)
|
||||||
|
emit qSearchField->returnPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointer<QSearchField> qSearchField;
|
||||||
NSSearchField *nsSearchField;
|
NSSearchField *nsSearchField;
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface QSearchFieldDelegate : NSObject<NSTextFieldDelegate>
|
@interface QSearchFieldDelegate : NSObject<NSTextFieldDelegate>
|
||||||
{
|
{
|
||||||
@public
|
@public
|
||||||
QSearchFieldPrivate* pimpl;
|
QPointer<QSearchFieldPrivate> pimpl;
|
||||||
}
|
}
|
||||||
-(void)controlTextDidChange:(NSNotification*)notification;
|
-(void)controlTextDidChange:(NSNotification*)notification;
|
||||||
-(void)controlTextDidEndEditing:(NSNotification*)aNotification;
|
-(void)controlTextDidEndEditing:(NSNotification*)notification;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation QSearchFieldDelegate
|
@implementation QSearchFieldDelegate
|
||||||
-(void)controlTextDidChange:(NSNotification*)notification {
|
-(void)controlTextDidChange:(NSNotification*)notification {
|
||||||
pimpl->textDidChange(toQString([[notification object] stringValue]));
|
Q_ASSERT(pimpl);
|
||||||
|
if (pimpl)
|
||||||
|
pimpl->textDidChange(toQString([[notification object] stringValue]));
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)controlTextDidEndEditing:(NSNotification*)notification {
|
-(void)controlTextDidEndEditing:(NSNotification*)notification {
|
||||||
pimpl->textDidEndEditing();
|
Q_UNUSED(notification);
|
||||||
|
// No Q_ASSERT here as it is called on destruction.
|
||||||
|
if (pimpl)
|
||||||
|
pimpl->textDidEndEditing();
|
||||||
|
|
||||||
|
if ([[[notification userInfo] objectForKey:@"NSTextMovement"] intValue] == NSReturnTextMovement)
|
||||||
|
pimpl->returnPressed();
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface QocoaSearchField : NSSearchField
|
||||||
|
-(BOOL)performKeyEquivalent:(NSEvent*)event;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation QocoaSearchField
|
||||||
|
-(BOOL)performKeyEquivalent:(NSEvent*)event {
|
||||||
|
if ([event type] == NSKeyDown && [event modifierFlags] & NSCommandKeyMask)
|
||||||
|
{
|
||||||
|
const unsigned short keyCode = [event keyCode];
|
||||||
|
if (keyCode == KEYCODE_A)
|
||||||
|
{
|
||||||
|
[self performSelector:@selector(selectText:)];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
else if (keyCode == KEYCODE_C)
|
||||||
|
{
|
||||||
|
QClipboard* clipboard = QApplication::clipboard();
|
||||||
|
clipboard->setText(toQString([self stringValue]));
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
else if (keyCode == KEYCODE_V)
|
||||||
|
{
|
||||||
|
QClipboard* clipboard = QApplication::clipboard();
|
||||||
|
[self setStringValue:fromQString(clipboard->text())];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
else if (keyCode == KEYCODE_X)
|
||||||
|
{
|
||||||
|
QClipboard* clipboard = QApplication::clipboard();
|
||||||
|
clipboard->setText(toQString([self stringValue]));
|
||||||
|
[self setStringValue:@""];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -73,27 +136,30 @@ QSearchField::QSearchField(QWidget *parent) : QWidget(parent)
|
|||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
NSSearchField *search = [[NSSearchField alloc] init];
|
NSSearchField *search = [[QocoaSearchField alloc] init];
|
||||||
pimpl = new QSearchFieldPrivate(this, search);
|
|
||||||
|
|
||||||
QSearchFieldDelegate *delegate = [[QSearchFieldDelegate alloc] init];
|
QSearchFieldDelegate *delegate = [[QSearchFieldDelegate alloc] init];
|
||||||
delegate->pimpl = pimpl;
|
pimpl = delegate->pimpl = new QSearchFieldPrivate(this, search);
|
||||||
[search setDelegate:delegate];
|
[search setDelegate:delegate];
|
||||||
|
|
||||||
zeroLayout(search, this);
|
setupLayout(search, this);
|
||||||
|
|
||||||
|
setFixedHeight(24);
|
||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||||
|
|
||||||
layout()->setContentsMargins(2, 0, 2, 0);
|
layout()->setContentsMargins(2, 0, 2, 0);
|
||||||
setStyleSheet( "* { background: #DDE4EB; }" );
|
setStyleSheet( "* { background: #DDE4EB; }" );
|
||||||
|
|
||||||
setMinimumSize(layout()->sizeHint().width(), 20);
|
|
||||||
|
|
||||||
[search release];
|
[search release];
|
||||||
[pool drain];
|
[pool drain];
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSearchField::setText(const QString &text)
|
void QSearchField::setText(const QString &text)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(pimpl);
|
||||||
|
if (!pimpl)
|
||||||
|
return;
|
||||||
|
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
[pimpl->nsSearchField setStringValue:fromQString(text)];
|
[pimpl->nsSearchField setStringValue:fromQString(text)];
|
||||||
[pool drain];
|
[pool drain];
|
||||||
@@ -101,6 +167,10 @@ void QSearchField::setText(const QString &text)
|
|||||||
|
|
||||||
void QSearchField::setPlaceholderText(const QString& text)
|
void QSearchField::setPlaceholderText(const QString& text)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(pimpl);
|
||||||
|
if (!pimpl)
|
||||||
|
return;
|
||||||
|
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
[[pimpl->nsSearchField cell] setPlaceholderString:fromQString(text)];
|
[[pimpl->nsSearchField cell] setPlaceholderString:fromQString(text)];
|
||||||
[pool drain];
|
[pool drain];
|
||||||
@@ -108,10 +178,57 @@ void QSearchField::setPlaceholderText(const QString& text)
|
|||||||
|
|
||||||
void QSearchField::clear()
|
void QSearchField::clear()
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(pimpl);
|
||||||
|
if (!pimpl)
|
||||||
|
return;
|
||||||
|
|
||||||
[pimpl->nsSearchField setStringValue:@""];
|
[pimpl->nsSearchField setStringValue:@""];
|
||||||
|
emit textChanged(QString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSearchField::selectAll()
|
||||||
|
{
|
||||||
|
Q_ASSERT(pimpl);
|
||||||
|
if (!pimpl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
[pimpl->nsSearchField performSelector:@selector(selectText:)];
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QSearchField::text() const
|
QString QSearchField::text() const
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(pimpl);
|
||||||
|
if (!pimpl)
|
||||||
|
return QString();
|
||||||
|
|
||||||
return toQString([pimpl->nsSearchField stringValue]);
|
return toQString([pimpl->nsSearchField stringValue]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QSearchField::placeholderText() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(pimpl);
|
||||||
|
if (!pimpl)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
return toQString([[pimpl->nsSearchField cell] placeholderString]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSearchField::setFocus(Qt::FocusReason reason)
|
||||||
|
{
|
||||||
|
Q_ASSERT(pimpl);
|
||||||
|
if (!pimpl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ([pimpl->nsSearchField acceptsFirstResponder])
|
||||||
|
[[pimpl->nsSearchField window] makeFirstResponder: pimpl->nsSearchField];
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSearchField::setFocus()
|
||||||
|
{
|
||||||
|
setFocus(Qt::OtherFocusReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSearchField::resizeEvent(QResizeEvent *resizeEvent)
|
||||||
|
{
|
||||||
|
QWidget::resizeEvent(resizeEvent);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user