1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-04-22 08:52:12 +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:
Leo Franchi 2012-07-20 17:31:31 -04:00
parent 85618cc62b
commit 05f58b2dfe
3 changed files with 157 additions and 21 deletions
src/libtomahawk/thirdparty/Qocoa

@ -30,7 +30,8 @@ THE SOFTWARE.
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];
}
@ -41,11 +42,17 @@ static inline QString toQString(NSString *string)
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);
layout->setMargin(0);
parent->setAttribute(Qt::WA_NativeWindow);
layout->addWidget(new QMacCocoaViewContainer(cocoaView, parent));
}

@ -2,6 +2,7 @@
#define QSEARCHFIELD_H
#include <QWidget>
#include <QPointer>
#include "DllMacro.h"
@ -9,23 +10,34 @@ class QSearchFieldPrivate;
class DLLEXPORT QSearchField : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText);
public:
explicit QSearchField(QWidget* parent);
explicit QSearchField(QWidget *parent);
QString text() const;
QString placeholderText() const;
void setFocus(Qt::FocusReason);
public slots:
void setText(const QString &text);
void setPlaceholderText(const QString& text);
void clear();
void selectAll();
void setFocus();
signals:
void textChanged(const QString &text);
void editingFinished();
void returnPressed();
protected:
void resizeEvent(QResizeEvent*);
private:
friend class QSearchFieldPrivate;
QSearchFieldPrivate *pimpl;
QPointer <QSearchFieldPrivate> pimpl;
};
#endif // QSEARCHFIELD_H

@ -30,42 +30,105 @@ THE SOFTWARE.
#import "Foundation/NSNotification.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:
QSearchFieldPrivate(QSearchField *qSearchField, NSSearchField *nsSearchField)
: qSearchField(qSearchField), nsSearchField(nsSearchField) {}
: QObject(qSearchField), qSearchField(qSearchField), nsSearchField(nsSearchField) {}
void textDidChange(const QString &text)
{
emit qSearchField->textChanged(text);
if (qSearchField)
emit qSearchField->textChanged(text);
}
void textDidEndEditing()
{
emit qSearchField->returnPressed();
if (qSearchField)
emit qSearchField->editingFinished();
}
QSearchField *qSearchField;
void returnPressed()
{
if (qSearchField)
emit qSearchField->returnPressed();
}
QPointer<QSearchField> qSearchField;
NSSearchField *nsSearchField;
};
@interface QSearchFieldDelegate : NSObject<NSTextFieldDelegate>
{
@public
QSearchFieldPrivate* pimpl;
QPointer<QSearchFieldPrivate> pimpl;
}
-(void)controlTextDidChange:(NSNotification*)notification;
-(void)controlTextDidEndEditing:(NSNotification*)aNotification;
-(void)controlTextDidEndEditing:(NSNotification*)notification;
@end
@implementation QSearchFieldDelegate
-(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 {
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
@ -73,27 +136,30 @@ QSearchField::QSearchField(QWidget *parent) : QWidget(parent)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSSearchField *search = [[NSSearchField alloc] init];
pimpl = new QSearchFieldPrivate(this, search);
NSSearchField *search = [[QocoaSearchField alloc] init];
QSearchFieldDelegate *delegate = [[QSearchFieldDelegate alloc] init];
delegate->pimpl = pimpl;
pimpl = delegate->pimpl = new QSearchFieldPrivate(this, search);
[search setDelegate:delegate];
zeroLayout(search, this);
setupLayout(search, this);
setFixedHeight(24);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
layout()->setContentsMargins(2, 0, 2, 0);
setStyleSheet( "* { background: #DDE4EB; }" );
setMinimumSize(layout()->sizeHint().width(), 20);
[search release];
[pool drain];
}
void QSearchField::setText(const QString &text)
{
Q_ASSERT(pimpl);
if (!pimpl)
return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pimpl->nsSearchField setStringValue:fromQString(text)];
[pool drain];
@ -101,6 +167,10 @@ void QSearchField::setText(const QString &text)
void QSearchField::setPlaceholderText(const QString& text)
{
Q_ASSERT(pimpl);
if (!pimpl)
return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[pimpl->nsSearchField cell] setPlaceholderString:fromQString(text)];
[pool drain];
@ -108,10 +178,57 @@ void QSearchField::setPlaceholderText(const QString& text)
void QSearchField::clear()
{
Q_ASSERT(pimpl);
if (!pimpl)
return;
[pimpl->nsSearchField setStringValue:@""];
emit textChanged(QString());
}
void QSearchField::selectAll()
{
Q_ASSERT(pimpl);
if (!pimpl)
return;
[pimpl->nsSearchField performSelector:@selector(selectText:)];
}
QString QSearchField::text() const
{
Q_ASSERT(pimpl);
if (!pimpl)
return QString();
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);
}