mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Deleted unused and unrelated files
Merged lots of changes from upstream that were missed or ignored
This commit is contained in:
parent
9cbdd58af5
commit
61c6962bf2
@ -244,12 +244,9 @@ qt4_wrap_cpp(keepassx_SOURCES ${keepassx_MOC})
|
||||
add_library(keepassx_core STATIC ${keepassx_SOURCES})
|
||||
set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
|
||||
|
||||
add_subdirectory(gui/qocoa)
|
||||
|
||||
add_executable(${PROGNAME} WIN32 MACOSX_BUNDLE ${keepassx_SOURCES_MAINEXE})
|
||||
target_link_libraries(${PROGNAME}
|
||||
keepassx_core
|
||||
Qocoa
|
||||
qjson
|
||||
${MHD_LIBRARIES}
|
||||
${QT_QTCORE_LIBRARY}
|
||||
@ -261,9 +258,6 @@ target_link_libraries(${PROGNAME}
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(${PROGNAME} ${QT_QTDBUS_LIBRARY})
|
||||
endif()
|
||||
if(APPLE)
|
||||
set_target_properties(${PROGNAME} PROPERTIES LINK_FLAGS "-framework Foundation -framework AppKit")
|
||||
endif()
|
||||
|
||||
set_target_properties(${PROGNAME} PROPERTIES ENABLE_EXPORTS ON)
|
||||
|
||||
|
@ -87,7 +87,7 @@ void AutoTypeExecutor::execDelay(AutoTypeDelay* action)
|
||||
Tools::wait(action->delayMs);
|
||||
}
|
||||
|
||||
void AutoTypeExecutor::execClearField(AutoTypeClearField*)
|
||||
void AutoTypeExecutor::execClearField(AutoTypeClearField* action)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
@ -9,10 +9,6 @@ if(Q_WS_X11)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Q_WS_MAC)
|
||||
add_subdirectory(mac)
|
||||
endif()
|
||||
|
||||
if(WITH_TESTS)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
@ -1,553 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Jeff Gibbons
|
||||
* Copyright (C) 2005-2008 by Tarek Saidi <tarek.saidi@arcor.de>
|
||||
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AutoTypeMac.h"
|
||||
#include <map>
|
||||
|
||||
static pid_t keepassxPID2;
|
||||
|
||||
#define UNICODE_BUFFER_SIZE 20
|
||||
static UniChar unicodeBuffer[UNICODE_BUFFER_SIZE];
|
||||
static UniCharCount unicodePtr = 0;
|
||||
// reusable events
|
||||
static CGEventRef unicodeEvent = CGEventCreateKeyboardEvent(NULL, 0, true);
|
||||
CGEventRef AutoTypePlatformMac::keyEvent =
|
||||
CGEventCreateKeyboardEvent(NULL, 0, true);
|
||||
|
||||
bool AutoTypePlatformMac::inHotKeyEvent = false;
|
||||
|
||||
static const KeycodeWithMods NoKeycodeWithMods =
|
||||
(KeycodeWithMods){ NoKeycode, 0 };
|
||||
|
||||
static uint orderedModifiers[] = {
|
||||
0,
|
||||
( shiftKey ) >> 8,
|
||||
(controlKey ) >> 8,
|
||||
( optionKey ) >> 8,
|
||||
( cmdKey ) >> 8,
|
||||
( shiftKey | controlKey ) >> 8,
|
||||
( shiftKey | optionKey ) >> 8,
|
||||
( shiftKey | cmdKey ) >> 8,
|
||||
(controlKey | optionKey ) >> 8,
|
||||
(controlKey | cmdKey ) >> 8,
|
||||
( optionKey | cmdKey ) >> 8,
|
||||
( shiftKey | controlKey | optionKey ) >> 8,
|
||||
( shiftKey | controlKey | cmdKey ) >> 8,
|
||||
( shiftKey | optionKey | cmdKey ) >> 8,
|
||||
(controlKey | optionKey | cmdKey ) >> 8,
|
||||
( shiftKey | controlKey | optionKey | cmdKey) >> 8
|
||||
};
|
||||
|
||||
static std::map<uint,KeycodeWithMods> unicodeToKeycodeWithModsMap;
|
||||
|
||||
|
||||
AutoTypePlatformMac::AutoTypePlatformMac() : first(true), keepassxPID(0)
|
||||
{
|
||||
globalKey = 0;
|
||||
globalMod = 0;
|
||||
inGlobalAutoType = false;
|
||||
|
||||
// initialize hot key handling
|
||||
hotKeyRef = NULL;
|
||||
hotKeyID.signature = 'kpsx';
|
||||
hotKeyID.id = 1;
|
||||
EventTypeSpec eventType;
|
||||
eventType.eventClass = kEventClassKeyboard;
|
||||
eventType.eventKind = kEventHotKeyPressed;
|
||||
InstallApplicationEventHandler(&hotKeyHandler, 1, &eventType, this, NULL);
|
||||
AutoTypePlatformMac::initUnicodeToKeycodeWithModsMap();
|
||||
}
|
||||
|
||||
|
||||
QStringList AutoTypePlatformMac::windowTitles()
|
||||
{
|
||||
pid_t pid;
|
||||
return getTargetWindowInfo(&pid, NULL);
|
||||
}
|
||||
|
||||
|
||||
WId AutoTypePlatformMac::activeWindow()
|
||||
{
|
||||
WId mid;
|
||||
pid_t pid;
|
||||
getTargetWindowInfo(&pid, &mid);
|
||||
AutoTypePlatformMac::processToFront(pid);
|
||||
if (first)
|
||||
first = false;
|
||||
|
||||
return mid;
|
||||
}
|
||||
|
||||
|
||||
QString AutoTypePlatformMac::activeWindowTitle()
|
||||
{
|
||||
QStringList sl = getTargetWindowInfo(NULL, NULL);
|
||||
return sl[0];
|
||||
}
|
||||
|
||||
|
||||
bool AutoTypePlatformMac::registerGlobalShortcut(Qt::Key key,
|
||||
Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
if (key == 0)
|
||||
return false;
|
||||
|
||||
//KeycodeWithMods kc = keyToKeycodeWithMods(key);
|
||||
KeycodeWithMods kc = AutoTypePlatformMac::keysymToKeycodeWithMods2(static_cast<KeySym>(key));
|
||||
int code = kc.keycode;
|
||||
uint mod = qtToNativeModifiers(modifiers);
|
||||
|
||||
if (code==globalKey && mod==globalMod)
|
||||
return true;
|
||||
|
||||
// need to unregister old before registering new
|
||||
unregisterGlobalShortcut(key, modifiers);
|
||||
OSStatus status = RegisterEventHotKey(code, mod, hotKeyID,
|
||||
GetApplicationEventTarget(), 0, &hotKeyRef);
|
||||
|
||||
if (noErr == status) {
|
||||
globalKey = code;
|
||||
globalMod = mod;
|
||||
return true;
|
||||
} else {
|
||||
qWarning("Error registering global shortcut: %d", status);
|
||||
RegisterEventHotKey(globalKey, globalMod, hotKeyID,
|
||||
GetApplicationEventTarget(), 0, &hotKeyRef);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AutoTypePlatformMac::unregisterGlobalShortcut(Qt::Key,
|
||||
Qt::KeyboardModifiers)
|
||||
{
|
||||
globalKey = 0;
|
||||
globalMod = 0;
|
||||
UnregisterEventHotKey(hotKeyRef);
|
||||
}
|
||||
|
||||
|
||||
int AutoTypePlatformMac::platformEventFilter(void* event)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int AutoTypePlatformMac::initialTimeout()
|
||||
{
|
||||
first = true;
|
||||
return 500;
|
||||
}
|
||||
|
||||
|
||||
AutoTypeExecutor* AutoTypePlatformMac::createExecutor()
|
||||
{
|
||||
return new AutoTypeExecturorMac(this);
|
||||
}
|
||||
|
||||
|
||||
void AutoTypePlatformMac::sendUnicode(KeySym keysym)
|
||||
{
|
||||
if (onlySendKeycodes) {
|
||||
KeycodeWithMods keycodeWithMods =
|
||||
AutoTypePlatformMac::keysymToKeycodeWithMods2(keysym);
|
||||
if (NoKeycode == keycodeWithMods.keycode) return;
|
||||
sendKeycode(keycodeWithMods);
|
||||
return;
|
||||
}
|
||||
unicodeBuffer[unicodePtr++] = keysym;
|
||||
if (UNICODE_BUFFER_SIZE == unicodePtr) flushUnicode();
|
||||
}
|
||||
|
||||
|
||||
void AutoTypePlatformMac::sendKeycode(KeycodeWithMods keycodeWithMods)
|
||||
{
|
||||
flushUnicode();
|
||||
uint keycode = keycodeWithMods.keycode;
|
||||
uint mods = keycodeWithMods.mods << 8;
|
||||
uint flags = 0;
|
||||
if (0 != ( shiftKey & mods)) flags |= kCGEventFlagMaskShift;
|
||||
if (0 != (controlKey & mods)) flags |= kCGEventFlagMaskControl;
|
||||
if (0 != ( optionKey & mods)) flags |= kCGEventFlagMaskAlternate;
|
||||
if (0 != ( cmdKey & mods)) flags |= kCGEventFlagMaskCommand;
|
||||
CGEventSetIntegerValueField(keyEvent, kCGKeyboardEventKeycode, keycode);
|
||||
CGEventSetFlags(AutoTypePlatformMac::keyEvent, flags);
|
||||
keyDownUp(AutoTypePlatformMac::keyEvent);
|
||||
sleepKeyStrokeDelay();
|
||||
}
|
||||
|
||||
|
||||
KeycodeWithMods AutoTypePlatformMac::keyToKeycodeWithMods(Qt::Key key)
|
||||
{
|
||||
KeycodeWithMods kc;
|
||||
kc.mods = 0;
|
||||
|
||||
switch (key) {
|
||||
case Qt::Key_Tab:
|
||||
kc.keycode = kVK_Tab;
|
||||
break;
|
||||
case Qt::Key_Enter:
|
||||
kc.keycode = kVK_Return;
|
||||
break;
|
||||
case Qt::Key_Up:
|
||||
kc.keycode = kVK_UpArrow;
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
kc.keycode = kVK_DownArrow;
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
kc.keycode = kVK_LeftArrow;
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
kc.keycode = kVK_RightArrow;
|
||||
break;
|
||||
case Qt::Key_Insert:
|
||||
kc.keycode = kVK_Help;
|
||||
break;
|
||||
case Qt::Key_Delete:
|
||||
kc.keycode = kVK_ForwardDelete;
|
||||
break;
|
||||
case Qt::Key_Home:
|
||||
kc.keycode = kVK_Home;
|
||||
break;
|
||||
case Qt::Key_End:
|
||||
kc.keycode = kVK_End;
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
kc.keycode = kVK_PageUp;
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
kc.keycode = kVK_PageDown;
|
||||
break;
|
||||
case Qt::Key_Backspace:
|
||||
kc.keycode = kVK_Delete;
|
||||
break;
|
||||
//case Qt::Key_Pause:
|
||||
// return XK_Break;
|
||||
case Qt::Key_CapsLock:
|
||||
kc.keycode = kVK_CapsLock;
|
||||
break;
|
||||
case Qt::Key_Escape:
|
||||
kc.keycode = kVK_Escape;
|
||||
break;
|
||||
case Qt::Key_Help:
|
||||
kc.keycode = kVK_Help;
|
||||
break;
|
||||
case Qt::Key_NumLock:
|
||||
kc.keycode = kVK_ANSI_KeypadClear;
|
||||
break;
|
||||
case Qt::Key_Print:
|
||||
kc.keycode = kVK_F13;
|
||||
break;
|
||||
//case Qt::Key_ScrollLock:
|
||||
// return XK_Scroll_Lock;
|
||||
default:
|
||||
if (key >= Qt::Key_F1 && key <= Qt::Key_F16)
|
||||
kc.keycode = kVK_F1 + key - Qt::Key_F1;
|
||||
else
|
||||
kc.keycode = NoSymbol;
|
||||
}
|
||||
|
||||
return kc;
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
QStringList AutoTypePlatformMac::getTargetWindowInfo(pid_t *pidPtr,
|
||||
WId *windowNumberPtr)
|
||||
{
|
||||
QStringList titles;
|
||||
|
||||
const int maxWindowNameSize = 512;
|
||||
char windowName[maxWindowNameSize];
|
||||
|
||||
onlySendKeycodes = false;
|
||||
|
||||
CFArrayRef windowInfo = CGWindowListCopyWindowInfo(
|
||||
kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements,
|
||||
0);
|
||||
CFIndex windowCount = CFArrayGetCount(windowInfo);
|
||||
|
||||
for (CFIndex i = 0; i < windowCount; i++) {
|
||||
CFDictionaryRef window = static_cast<CFDictionaryRef>
|
||||
(CFArrayGetValueAtIndex(windowInfo, i));
|
||||
|
||||
// only want windows in layer 0
|
||||
CFNumberRef windowLayerRef = static_cast<CFNumberRef>
|
||||
(CFDictionaryGetValue(window, kCGWindowLayer));
|
||||
|
||||
int windowLayer = -1;
|
||||
CFNumberGetValue(windowLayerRef, kCFNumberIntType, &windowLayer);
|
||||
if (0 != windowLayer) continue;
|
||||
|
||||
// get the pid owning this window
|
||||
CFNumberRef pidRef = static_cast<CFNumberRef>
|
||||
(CFDictionaryGetValue(window, kCGWindowOwnerPID));
|
||||
pid_t pid = -1;
|
||||
CFNumberGetValue(pidRef, kCFNumberIntType, &pid);
|
||||
|
||||
// skip KeePassX windows
|
||||
if (getKeepassxPID() == pid) continue;
|
||||
|
||||
// get window name; continue if no name
|
||||
CFStringRef windowNameRef = static_cast<CFStringRef>
|
||||
(CFDictionaryGetValue(window, kCGWindowName));
|
||||
if (!windowNameRef) continue;
|
||||
|
||||
windowName[0] = 0;
|
||||
if (!CFStringGetCString(windowNameRef, windowName,
|
||||
maxWindowNameSize, kCFStringEncodingUTF8) ||
|
||||
(0 == windowName[0])) continue;
|
||||
|
||||
if (NULL != pidPtr)
|
||||
*pidPtr = pid;
|
||||
|
||||
if (NULL != windowNumberPtr) {
|
||||
CGWindowID wid;
|
||||
CFNumberRef windowNumberRef = static_cast<CFNumberRef>
|
||||
(CFDictionaryGetValue(window, kCGWindowNumber));
|
||||
CFNumberGetValue(windowNumberRef, kCGWindowIDCFNumberType, &wid);
|
||||
*windowNumberPtr = wid;
|
||||
return titles;
|
||||
}
|
||||
titles.append(QString(windowName));
|
||||
}
|
||||
|
||||
return titles;
|
||||
}
|
||||
|
||||
|
||||
uint AutoTypePlatformMac::qtToNativeModifiers(Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
uint nativeModifiers = 0;
|
||||
|
||||
if (modifiers & Qt::ShiftModifier) {
|
||||
nativeModifiers |= shiftKey;
|
||||
}
|
||||
if (modifiers & Qt::ControlModifier) {
|
||||
nativeModifiers |= controlKey;
|
||||
}
|
||||
if (modifiers & Qt::AltModifier) {
|
||||
nativeModifiers |= optionKey;
|
||||
}
|
||||
if (modifiers & Qt::MetaModifier) {
|
||||
nativeModifiers |= cmdKey;
|
||||
}
|
||||
|
||||
return nativeModifiers;
|
||||
}
|
||||
|
||||
|
||||
void AutoTypePlatformMac::flushUnicode()
|
||||
{
|
||||
if (0 == unicodePtr) return;
|
||||
CGEventKeyboardSetUnicodeString(unicodeEvent, unicodePtr, unicodeBuffer);
|
||||
keyDownUp(unicodeEvent);
|
||||
unicodePtr = 0;
|
||||
sleepKeyStrokeDelay();
|
||||
}
|
||||
|
||||
|
||||
void AutoTypePlatformMac::keyDownUp(CGEventRef theEvent)
|
||||
{
|
||||
// posting Key Down/Up events also annoyingly sets mouse location so mus
|
||||
// current mouse location and set it in the event
|
||||
CGEventRef eventLocation = CGEventCreate(NULL);
|
||||
CGEventSetLocation(theEvent, CGEventGetLocation(eventLocation));
|
||||
CFRelease(eventLocation);
|
||||
|
||||
CGEventSetType(theEvent, kCGEventKeyDown);
|
||||
CGEventPost(kCGHIDEventTap, theEvent);
|
||||
CGEventSetType(theEvent, kCGEventKeyUp);
|
||||
CGEventPost(kCGHIDEventTap, theEvent);
|
||||
}
|
||||
|
||||
|
||||
void AutoTypePlatformMac::sleepTime(int msec)
|
||||
{
|
||||
if (msec == 0) return;
|
||||
|
||||
timespec timeOut, remains;
|
||||
timeOut.tv_sec = msec/1000;
|
||||
timeOut.tv_nsec = (msec%1000)*1000000;
|
||||
nanosleep(&timeOut, &remains);
|
||||
}
|
||||
|
||||
|
||||
OSStatus AutoTypePlatformMac::hotKeyHandler(EventHandlerCallRef, EventRef,
|
||||
void *userData)
|
||||
{
|
||||
// ignore nextHandler - should not be called
|
||||
if ((inHotKeyEvent) ||
|
||||
AutoTypePlatformMac::isFrontProcess(AutoTypePlatformMac::getKeepassxPID2())) return noErr;
|
||||
|
||||
AutoTypePlatformMac::inHotKeyEvent = true;
|
||||
Q_EMIT static_cast<AutoTypePlatformMac*>(userData)->globalShortcutTriggered();
|
||||
AutoTypePlatformMac::inHotKeyEvent = false;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
pid_t AutoTypePlatformMac::getKeepassxPID() {
|
||||
|
||||
if (0 == keepassxPID) {
|
||||
ProcessSerialNumber processSerialNumber;
|
||||
GetCurrentProcess(&processSerialNumber);
|
||||
GetProcessPID(&processSerialNumber, &keepassxPID);
|
||||
}
|
||||
|
||||
return keepassxPID;
|
||||
}
|
||||
|
||||
|
||||
Boolean AutoTypePlatformMac::isFrontProcess(pid_t pid)
|
||||
{
|
||||
Boolean result;
|
||||
ProcessSerialNumber pidPSN;
|
||||
ProcessSerialNumber frontPSN;
|
||||
OSStatus status = GetProcessForPID(pid, &pidPSN);
|
||||
if (noErr != status) {
|
||||
qWarning("AutoTypePlatformMac::isFrontProcess: GetProcessForPID "
|
||||
"error for pid %d: %d", pid, status);
|
||||
return false;
|
||||
}
|
||||
GetFrontProcess(&frontPSN);
|
||||
SameProcess(&pidPSN, &frontPSN, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void AutoTypePlatformMac::initUnicodeToKeycodeWithModsMap()
|
||||
{
|
||||
unicodeToKeycodeWithModsMap.clear();
|
||||
TISInputSourceRef inputSourceRef = TISCopyCurrentKeyboardInputSource();
|
||||
|
||||
if (NULL == inputSourceRef) {
|
||||
qWarning("AutoTypePlatformMac::initUnicodeToKeycodeWithModsMap: "
|
||||
"inputSourceRef is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
CFDataRef unicodeKeyLayoutDataRef = static_cast<CFDataRef>
|
||||
(TISGetInputSourceProperty(inputSourceRef,
|
||||
kTISPropertyUnicodeKeyLayoutData));
|
||||
|
||||
if (NULL == unicodeKeyLayoutDataRef) {
|
||||
qWarning("AutoTypePlatformMac::initUnicodeToKeycodeWithModsMap: "
|
||||
"unicodeKeyLayoutDataRef is NULL");
|
||||
return;
|
||||
}
|
||||
const UCKeyboardLayout *unicodeKeyLayoutDataPtr =
|
||||
reinterpret_cast<const UCKeyboardLayout*>
|
||||
(CFDataGetBytePtr(unicodeKeyLayoutDataRef));
|
||||
|
||||
UInt32 deadKeyState;
|
||||
UniChar unicodeString[8];
|
||||
UniCharCount len;
|
||||
for (int m = 0; m < 16; m++) {
|
||||
uint mods = orderedModifiers[m];
|
||||
for (uint keycode = 0; keycode < 0x80; keycode++) {
|
||||
deadKeyState = 0;
|
||||
len = 0;
|
||||
OSStatus status = UCKeyTranslate(unicodeKeyLayoutDataPtr, keycode,
|
||||
kUCKeyActionDown, mods, LMGetKbdType(),
|
||||
kUCKeyTranslateNoDeadKeysMask, &deadKeyState,
|
||||
sizeof(unicodeString), &len, unicodeString);
|
||||
|
||||
if (noErr != status) {
|
||||
qWarning("AutoTypePlatformMac::initUnicodeToKeycodeWithModsMap: "
|
||||
"UCKeyTranslate error: %d keycode 0x%02X modifiers 0x%02X",
|
||||
status, keycode, mods);
|
||||
continue;
|
||||
}
|
||||
|
||||
// store if only one char and not already in store
|
||||
if ((1 != len) ||
|
||||
(0 < unicodeToKeycodeWithModsMap.count(unicodeString[0])))
|
||||
continue;
|
||||
|
||||
KeycodeWithMods kc;
|
||||
kc.keycode = keycode;
|
||||
kc.mods = mods;
|
||||
unicodeToKeycodeWithModsMap[unicodeString[0]] = kc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AutoTypePlatformMac::processToFront(pid_t pid)
|
||||
{
|
||||
OSStatus status;
|
||||
ProcessSerialNumber processSerialNumber;
|
||||
status = GetProcessForPID(pid, &processSerialNumber);
|
||||
|
||||
if (noErr != status) {
|
||||
qWarning("AutoTypePlatformMac::processToFront: GetProcessForPID "
|
||||
"error for pid %d: %d", pid, status);
|
||||
return;
|
||||
}
|
||||
|
||||
status = SetFrontProcessWithOptions(&processSerialNumber,
|
||||
kSetFrontProcessFrontWindowOnly);
|
||||
|
||||
if (noErr != status) {
|
||||
qWarning("AutoTypePlatformMac::processToFront: "
|
||||
"SetFrontProcessWithOptions for pid %d: %d", pid, status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KeycodeWithMods AutoTypePlatformMac::keysymToKeycodeWithMods2(KeySym keysym)
|
||||
{
|
||||
return 0 == unicodeToKeycodeWithModsMap.count(keysym)
|
||||
? NoKeycodeWithMods : unicodeToKeycodeWithModsMap[keysym];
|
||||
}
|
||||
|
||||
|
||||
pid_t AutoTypePlatformMac::getKeepassxPID2()
|
||||
{
|
||||
if (0 == keepassxPID2) {
|
||||
ProcessSerialNumber processSerialNumber;
|
||||
GetCurrentProcess(&processSerialNumber);
|
||||
GetProcessPID(&processSerialNumber, &keepassxPID2);
|
||||
}
|
||||
return keepassxPID2;
|
||||
}
|
||||
|
||||
|
||||
AutoTypeExecturorMac::AutoTypeExecturorMac(AutoTypePlatformMac* platform)
|
||||
: m_platform(platform)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void AutoTypeExecturorMac::execChar(AutoTypeChar* action)
|
||||
{
|
||||
m_platform->sendUnicode(action->character.unicode());
|
||||
}
|
||||
|
||||
|
||||
void AutoTypeExecturorMac::execKey(AutoTypeKey* action)
|
||||
{
|
||||
m_platform->sendKeycode(m_platform->keyToKeycodeWithMods(action->key));
|
||||
}
|
||||
|
||||
|
||||
Q_EXPORT_PLUGIN2(keepassx-autotype-mac, AutoTypePlatformMac)
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Jeff Gibbons
|
||||
* Copyright (C) 2005-2008 Tarek Saidi <tarek.saidi@arcor.de>
|
||||
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_AUTOTYPEMAC_H
|
||||
#define KEEPASSX_AUTOTYPEMAC_H
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#include "autotype/AutoTypePlatformPlugin.h"
|
||||
#include "autotype/AutoTypeAction.h"
|
||||
#include "core/Global.h"
|
||||
|
||||
typedef quint32 KeySym;
|
||||
#define NoSymbol static_cast<KeySym>(0)
|
||||
#define NoKeycode static_cast<uint16>(-1)
|
||||
|
||||
struct KeycodeWithMods {
|
||||
uint16 keycode;
|
||||
uint16 mods;
|
||||
};
|
||||
|
||||
class AutoTypePlatformMac : public QObject, public AutoTypePlatformInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(AutoTypePlatformInterface)
|
||||
|
||||
public:
|
||||
AutoTypePlatformMac();
|
||||
|
||||
QStringList windowTitles();
|
||||
WId activeWindow();
|
||||
QString activeWindowTitle();
|
||||
bool registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
|
||||
void unregisterGlobalShortcut(Qt::Key key, Qt::KeyboardModifiers modifiers);
|
||||
int platformEventFilter(void* event);
|
||||
int initialTimeout();
|
||||
AutoTypeExecutor* createExecutor();
|
||||
|
||||
void sendUnicode(KeySym keysym);
|
||||
void sendKeycode(KeycodeWithMods keycodeWithMods);
|
||||
KeycodeWithMods keyToKeycodeWithMods(Qt::Key key);
|
||||
|
||||
Q_SIGNALS:
|
||||
void globalShortcutTriggered();
|
||||
|
||||
private:
|
||||
QStringList getTargetWindowInfo(pid_t *pidPtr, WId *windowNumberPtr);
|
||||
uint qtToNativeModifiers(Qt::KeyboardModifiers modifiers);
|
||||
void flushUnicode();
|
||||
void keyDownUp(CGEventRef theEvent);
|
||||
void sleepTime(int msec);
|
||||
inline void sleepKeyStrokeDelay(){ sleepTime(5); };
|
||||
static OSStatus hotKeyHandler(EventHandlerCallRef,
|
||||
EventRef, void *userData);
|
||||
pid_t getKeepassxPID();
|
||||
|
||||
bool first;
|
||||
bool onlySendKeycodes;
|
||||
bool inGlobalAutoType;
|
||||
int globalKey;
|
||||
uint globalMod;
|
||||
pid_t keepassxPID;
|
||||
EventHotKeyRef hotKeyRef;
|
||||
EventHotKeyID hotKeyID;
|
||||
|
||||
static bool inHotKeyEvent;
|
||||
static CGEventRef keyEvent;
|
||||
|
||||
private:
|
||||
static void initUnicodeToKeycodeWithModsMap();
|
||||
static void processToFront(pid_t pid);
|
||||
static KeycodeWithMods keysymToKeycodeWithMods2(KeySym keysym);
|
||||
static Boolean isFrontProcess(pid_t pid);
|
||||
static pid_t getKeepassxPID2();
|
||||
};
|
||||
|
||||
|
||||
class AutoTypeExecturorMac : public AutoTypeExecutor
|
||||
{
|
||||
public:
|
||||
explicit AutoTypeExecturorMac(AutoTypePlatformMac* platform);
|
||||
|
||||
void execChar(AutoTypeChar* action);
|
||||
void execKey(AutoTypeKey* action);
|
||||
|
||||
private:
|
||||
AutoTypePlatformMac* const m_platform;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_AUTOTYPEMAC_H
|
@ -1,18 +0,0 @@
|
||||
set(autotype_mac_SOURCES
|
||||
AutoTypeMac.cpp
|
||||
)
|
||||
|
||||
set(autotype_mac_MOC
|
||||
AutoTypeMac.h
|
||||
)
|
||||
|
||||
qt4_wrap_cpp(autotype_mac_SOURCES ${autotype_mac_MOC})
|
||||
|
||||
add_library(keepassx-autotype-mac MODULE ${autotype_mac_SOURCES})
|
||||
if(APPLE)
|
||||
set_target_properties(keepassx-autotype-mac PROPERTIES LINK_FLAGS "-framework Foundation -framework AppKit -framework Carbon")
|
||||
endif()
|
||||
target_link_libraries(keepassx-autotype-mac testautotype ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
|
||||
install(TARGETS keepassx-autotype-mac
|
||||
BUNDLE DESTINATION . COMPONENT Runtime
|
||||
LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} COMPONENT Runtime)
|
@ -228,11 +228,6 @@ bool Database::verifyKey(const CompositeKey& key) const
|
||||
return (m_data.key.rawKey() == key.rawKey());
|
||||
}
|
||||
|
||||
CompositeKey Database::key() const
|
||||
{
|
||||
return m_data.key;
|
||||
}
|
||||
|
||||
void Database::createRecycleBin()
|
||||
{
|
||||
Group* recycleBin = Group::createRecycleBin();
|
||||
|
@ -99,7 +99,6 @@ public:
|
||||
void setKey(const CompositeKey& key);
|
||||
bool hasKey() const;
|
||||
bool verifyKey(const CompositeKey& key) const;
|
||||
CompositeKey key() const;
|
||||
void recycleEntry(Entry* entry);
|
||||
void recycleGroup(Group* group);
|
||||
void setEmitModified(bool value);
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include "core/Global.h"
|
||||
#include "crypto/SymmetricCipher.h"
|
||||
#include "crypto/SymmetricCipherBackend.h"
|
||||
|
||||
class SymmetricCipher
|
||||
@ -48,42 +47,31 @@ public:
|
||||
Encrypt
|
||||
};
|
||||
|
||||
SymmetricCipher();
|
||||
SymmetricCipher(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,
|
||||
SymmetricCipher::Direction direction, const QByteArray& key, const QByteArray& iv = QByteArray());
|
||||
SymmetricCipher::Direction direction, const QByteArray& key, const QByteArray& iv);
|
||||
~SymmetricCipher();
|
||||
|
||||
void init(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode, SymmetricCipher::Direction direction,
|
||||
const QByteArray &key, const QByteArray &iv = QByteArray());
|
||||
bool isValid() const {
|
||||
return m_backend != 0;
|
||||
}
|
||||
|
||||
inline QByteArray process(const QByteArray& data) {
|
||||
Q_ASSERT(m_backend);
|
||||
return m_backend->process(data);
|
||||
}
|
||||
|
||||
inline void processInPlace(QByteArray& data) {
|
||||
Q_ASSERT(m_backend);
|
||||
m_backend->processInPlace(data);
|
||||
}
|
||||
|
||||
inline void processInPlace(QByteArray& data, quint64 rounds) {
|
||||
Q_ASSERT(rounds > 0);
|
||||
Q_ASSERT(m_backend);
|
||||
m_backend->processInPlace(data, rounds);
|
||||
}
|
||||
|
||||
void reset();
|
||||
void setIv(const QByteArray& iv);
|
||||
int blockSize() const;
|
||||
|
||||
private:
|
||||
static SymmetricCipherBackend* createBackend(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,
|
||||
SymmetricCipher::Direction direction);
|
||||
|
||||
QScopedPointer<SymmetricCipherBackend> m_backend;
|
||||
const QScopedPointer<SymmetricCipherBackend> m_backend;
|
||||
|
||||
Q_DISABLE_COPY(SymmetricCipher)
|
||||
};
|
||||
|
@ -93,26 +93,14 @@ void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile)
|
||||
openDatabase();
|
||||
}
|
||||
|
||||
void DatabaseOpenWidget::enterKey(const CompositeKey& masterKey)
|
||||
{
|
||||
if (masterKey.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
openDatabase(masterKey);
|
||||
}
|
||||
|
||||
void DatabaseOpenWidget::openDatabase()
|
||||
{
|
||||
KeePass2Reader reader;
|
||||
CompositeKey masterKey = databaseKey();
|
||||
if (masterKey.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
openDatabase(masterKey);
|
||||
}
|
||||
|
||||
void DatabaseOpenWidget::openDatabase(const CompositeKey& masterKey)
|
||||
{
|
||||
KeePass2Reader reader;
|
||||
QFile file(m_filename);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
// TODO: error message
|
||||
|
@ -39,7 +39,6 @@ public:
|
||||
~DatabaseOpenWidget();
|
||||
void load(const QString& filename);
|
||||
void enterKey(const QString& pw, const QString& keyFile);
|
||||
void enterKey(const CompositeKey& masterKey);
|
||||
Database* database();
|
||||
|
||||
Q_SIGNALS:
|
||||
@ -50,7 +49,6 @@ protected:
|
||||
|
||||
protected Q_SLOTS:
|
||||
virtual void openDatabase();
|
||||
void openDatabase(const CompositeKey& masterKey);
|
||||
void reject();
|
||||
|
||||
private Q_SLOTS:
|
||||
|
@ -514,9 +514,7 @@ bool DatabaseTabWidget::hasLockableDatabases() const
|
||||
i.next();
|
||||
DatabaseWidget::Mode mode = i.value().dbWidget->currentMode();
|
||||
|
||||
if ((mode == DatabaseWidget::ViewMode ||
|
||||
mode == DatabaseWidget::EditMode ||
|
||||
mode == DatabaseWidget::OpenMode)
|
||||
if ((mode == DatabaseWidget::ViewMode || mode == DatabaseWidget::EditMode)
|
||||
&& i.value().dbWidget->dbHasKey()) {
|
||||
return true;
|
||||
}
|
||||
@ -532,9 +530,7 @@ void DatabaseTabWidget::lockDatabases()
|
||||
i.next();
|
||||
DatabaseWidget::Mode mode = i.value().dbWidget->currentMode();
|
||||
|
||||
if ((mode == DatabaseWidget::ViewMode ||
|
||||
mode == DatabaseWidget::EditMode ||
|
||||
mode == DatabaseWidget::OpenMode)
|
||||
if ((mode == DatabaseWidget::ViewMode || mode == DatabaseWidget::EditMode)
|
||||
&& i.value().dbWidget->dbHasKey()) {
|
||||
i.value().dbWidget->lock();
|
||||
updateTabName(i.key());
|
||||
|
@ -181,9 +181,6 @@ DatabaseWidget::Mode DatabaseWidget::currentMode() const
|
||||
else if (currentWidget() == m_unlockDatabaseWidget) {
|
||||
return DatabaseWidget::LockedMode;
|
||||
}
|
||||
else if (currentWidget() == m_databaseOpenWidget) {
|
||||
return DatabaseWidget::OpenMode;
|
||||
}
|
||||
else {
|
||||
return DatabaseWidget::EditMode;
|
||||
}
|
||||
|
@ -55,7 +55,6 @@ public:
|
||||
None,
|
||||
ViewMode,
|
||||
EditMode,
|
||||
OpenMode,
|
||||
LockedMode
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,6 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
|
||||
, m_database(Q_NULLPTR)
|
||||
, m_defaultIconModel(new DefaultIconModel(this))
|
||||
, m_customIconModel(new CustomIconModel(this))
|
||||
, m_networkAccessMngr(new QNetworkAccessManager(this))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
@ -55,11 +54,6 @@ EditWidgetIcons::EditWidgetIcons(QWidget* parent)
|
||||
this, SLOT(updateWidgetsCustomIcons(bool)));
|
||||
connect(m_ui->addButton, SIGNAL(clicked()), SLOT(addCustomIcon()));
|
||||
connect(m_ui->deleteButton, SIGNAL(clicked()), SLOT(removeCustomIcon()));
|
||||
connect(m_ui->faviconButton, SIGNAL(clicked()), SLOT(downloadFavicon()));
|
||||
connect(m_networkAccessMngr, SIGNAL(finished(QNetworkReply*)),
|
||||
this, SLOT(onRequestFinished(QNetworkReply*)) );
|
||||
|
||||
m_ui->faviconButton->setVisible(false);
|
||||
}
|
||||
|
||||
EditWidgetIcons::~EditWidgetIcons()
|
||||
|
@ -19,11 +19,6 @@
|
||||
#define KEEPASSX_EDITWIDGETICONS_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QSet>
|
||||
|
||||
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
#include "core/Global.h"
|
||||
#include "core/Uuid.h"
|
||||
@ -53,15 +48,9 @@ public:
|
||||
~EditWidgetIcons();
|
||||
|
||||
IconStruct save();
|
||||
void load(Uuid currentUuid, Database* database, IconStruct iconStruct, const QString &url = QString());
|
||||
|
||||
public Q_SLOTS:
|
||||
void setUrl(const QString &url);
|
||||
void load(Uuid currentUuid, Database* database, IconStruct iconStruct);
|
||||
|
||||
private Q_SLOTS:
|
||||
void downloadFavicon();
|
||||
void abortFaviconDownload();
|
||||
void onRequestFinished(QNetworkReply *reply);
|
||||
void addCustomIcon();
|
||||
void removeCustomIcon();
|
||||
void updateWidgetsDefaultIcons(bool checked);
|
||||
@ -73,11 +62,8 @@ private:
|
||||
const QScopedPointer<Ui::EditWidgetIcons> m_ui;
|
||||
Database* m_database;
|
||||
Uuid m_currentUuid;
|
||||
QString m_url;
|
||||
DefaultIconModel* const m_defaultIconModel;
|
||||
CustomIconModel* const m_customIconModel;
|
||||
QNetworkAccessManager* const m_networkAccessMngr;
|
||||
QSet<QNetworkReply *> m_networkOperations;
|
||||
|
||||
Q_DISABLE_COPY(EditWidgetIcons)
|
||||
};
|
||||
|
@ -91,13 +91,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="faviconButton">
|
||||
<property name="text">
|
||||
<string>Download favicon</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -342,7 +342,6 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
||||
}
|
||||
case DatabaseWidget::EditMode:
|
||||
case DatabaseWidget::LockedMode:
|
||||
case DatabaseWidget::OpenMode:
|
||||
Q_FOREACH (QAction* action, m_ui->menuEntries->actions()) {
|
||||
action->setEnabled(false);
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ private:
|
||||
Qt::KeyboardModifiers m_globalAutoTypeModifiers;
|
||||
class ExtraPage;
|
||||
QList<ExtraPage> m_extraPages;
|
||||
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_SETTINGSWIDGET_H
|
||||
|
@ -340,8 +340,7 @@ void EditEntryWidget::setForms(const Entry* entry, bool restore)
|
||||
IconStruct iconStruct;
|
||||
iconStruct.uuid = entry->iconUuid();
|
||||
iconStruct.number = entry->iconNumber();
|
||||
m_iconsWidget->load(entry->uuid(), m_database, iconStruct, entry->url());
|
||||
connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), m_iconsWidget, SLOT(setUrl(QString)));
|
||||
m_iconsWidget->load(entry->uuid(), m_database, iconStruct);
|
||||
|
||||
m_autoTypeUi->enableButton->setChecked(entry->autoTypeEnabled());
|
||||
if (entry->defaultAutoTypeSequence().isEmpty()) {
|
||||
|
@ -18,31 +18,13 @@
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="AttributesListView" name="attributesView"/>
|
||||
<widget class="QPlainTextEdit" name="attributesEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="AttributesListView" name="attributesView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="attributesEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -41,7 +41,7 @@ Entry* EntryModel::entryFromIndex(const QModelIndex& index) const
|
||||
QModelIndex EntryModel::indexFromEntry(Entry* entry) const
|
||||
{
|
||||
int row = m_entries.indexOf(entry);
|
||||
//Q_ASSERT(row != -1);
|
||||
Q_ASSERT(row != -1);
|
||||
return index(row, 1);
|
||||
}
|
||||
|
||||
|
2
src/gui/qocoa/.gitignore
vendored
2
src/gui/qocoa/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
cmake/
|
||||
qmake/
|
@ -1,50 +0,0 @@
|
||||
project(Qocoa)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
#find_package(Qt4 COMPONENTS QtMain QtCore QtGui REQUIRED)
|
||||
#include(UseQt4)
|
||||
|
||||
set(SOURCES
|
||||
#main.cpp
|
||||
#gallery.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
#gallery.h
|
||||
qsearchfield.h
|
||||
qbutton.h
|
||||
qprogressindicatorspinning.h
|
||||
)
|
||||
|
||||
qt4_wrap_cpp(MOC_SOURCES ${HEADERS})
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND SOURCES
|
||||
qsearchfield_mac.mm
|
||||
qbutton_mac.mm
|
||||
qprogressindicatorspinning_mac.mm
|
||||
)
|
||||
else()
|
||||
list(APPEND SOURCES
|
||||
qsearchfield_nonmac.cpp
|
||||
qbutton_nonmac.cpp
|
||||
qprogressindicatorspinning_nonmac.cpp
|
||||
)
|
||||
set(RESOURCES
|
||||
qsearchfield_nonmac.qrc
|
||||
qprogressindicatorspinning_nonmac.qrc
|
||||
)
|
||||
qt4_add_resources(RESOURCES_SOURCES ${RESOURCES})
|
||||
endif()
|
||||
|
||||
#add_executable(Qocoa
|
||||
# WIN32 MACOSX_BUNDLE
|
||||
# ${SOURCES} ${MOC_SOURCES} ${RESOURCES_SOURCES}
|
||||
#)
|
||||
#target_link_libraries(Qocoa ${QT_LIBRARIES})
|
||||
|
||||
add_library (Qocoa STATIC ${SOURCES} ${MOC_SOURCES} ${HEADERS} ${RESOURCES_SOURCES})
|
||||
|
||||
#if(APPLE)
|
||||
# set_target_properties(Qocoa PROPERTIES LINK_FLAGS "-framework Foundation -framework AppKit")
|
||||
#endif()
|
@ -1,19 +0,0 @@
|
||||
Copyright (C) 2011 by Mike McQuaid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
@ -1,17 +0,0 @@
|
||||
SOURCES += main.cpp\
|
||||
gallery.cpp \
|
||||
|
||||
HEADERS += gallery.h \
|
||||
qocoa_mac.h \
|
||||
qsearchfield.h \
|
||||
qbutton.h \
|
||||
qprogressindicatorspinning.h \
|
||||
|
||||
mac {
|
||||
OBJECTIVE_SOURCES += qsearchfield_mac.mm qbutton_mac.mm qprogressindicatorspinning_mac.mm
|
||||
LIBS += -framework Foundation -framework Appkit
|
||||
QMAKE_CFLAGS += -mmacosx-version-min=10.6
|
||||
} else {
|
||||
SOURCES += qsearchfield_nonmac.cpp qbutton_nonmac.cpp qprogressindicatorspinning_nonmac.cpp
|
||||
RESOURCES += qsearchfield_nonmac.qrc qprogressindicatorspinning_nonmac.qrc
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
# Qocoa
|
||||
Qocoa is a collection of Qt wrappers for OSX's Cocoa widgets.
|
||||
|
||||
## Features
|
||||
- basic fallback to sensible Qt types on non-OSX platforms
|
||||
- shared class headers which expose no implementation details
|
||||
- typical Qt signal/slot-based API
|
||||
- trivial to import into projects (class header/implementation, [single shared global header](https://github.com/mikemcquaid/Qocoa/blob/master/qocoa_mac.h))
|
||||
|
||||
## Building
|
||||
```
|
||||
git clone git://github.com/mikemcquaid/Qocoa.git
|
||||
cd Qocoa
|
||||
qmake # or cmake .
|
||||
make
|
||||
```
|
||||
|
||||
## Status
|
||||
Qocoa classes are currently provided for NSButton, a spinning NSProgressIndicator and NSSearchField. There is a [TODO list](https://github.com/mikemcquaid/Qocoa/blob/master/TODO.md) for classes I hope to implement.
|
||||
|
||||
## Usage
|
||||
For each class you want to use copy the [`qocoa_mac.h`](https://github.com/mikemcquaid/Qocoa/blob/master/qocoa_mac.h), `$CLASS.h`, `$CLASS_mac.*` and `$CLASS_nonmac.*` files into your source tree and add them to your buildsystem. Examples are provided for [CMake](https://github.com/mikemcquaid/Qocoa/blob/master/CMakeLists.txt) and [QMake](https://github.com/mikemcquaid/Qocoa/blob/master/Qocoa.pro).
|
||||
|
||||
## Contact
|
||||
[Mike McQuaid](mailto:mike@mikemcquaid.com)
|
||||
|
||||
## License
|
||||
Qocoa is licensed under the [MIT License](http://en.wikipedia.org/wiki/MIT_License).
|
||||
The full license text is available in [LICENSE.txt](https://github.com/mikemcquaid/Qocoa/blob/master/LICENSE.txt).
|
||||
|
||||
Magnifier and EditClear icons taken from [QtCreator](http://qt-project.org/) and are licensed under the [LGPL](http://www.gnu.org/copyleft/lesser.html).
|
||||
|
||||
Other icons are taken from the [Oxygen Project](http://www.oxygen-icons.org/) and are licensed under the [Creative Commons Attribution-ShareAlike 3.0 License](http://creativecommons.org/licenses/by-sa/3.0/).
|
||||
|
||||
## Gallery
|
||||
![Qocoa Gallery](https://github.com/mikemcquaid/Qocoa/raw/master/gallery.png)
|
@ -1,13 +0,0 @@
|
||||
Widgets I hope to implement (or at least investigate):
|
||||
|
||||
- NSTokenField
|
||||
- NSSegmentedControl
|
||||
- NSLevelIndicator
|
||||
- NSPathControl
|
||||
- NSSlider (Circular)
|
||||
- NSSplitView
|
||||
- NSTextFinder
|
||||
- NSOutlineView in an NSScrollView (Source List)
|
||||
- NSDrawer
|
||||
- PDFView
|
||||
- WebView
|
@ -1,75 +0,0 @@
|
||||
#include "gallery.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "qsearchfield.h"
|
||||
#include "qbutton.h"
|
||||
#include "qprogressindicatorspinning.h"
|
||||
|
||||
Gallery::Gallery(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
setWindowTitle("Qocoa Gallery");
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
QSearchField *searchField = new QSearchField(this);
|
||||
layout->addWidget(searchField);
|
||||
|
||||
QSearchField *searchFieldPlaceholder = new QSearchField(this);
|
||||
searchFieldPlaceholder->setPlaceholderText("Placeholder text");
|
||||
layout->addWidget(searchFieldPlaceholder);
|
||||
|
||||
QButton *roundedButton = new QButton(this, QButton::Rounded);
|
||||
roundedButton->setText("Button");
|
||||
layout->addWidget(roundedButton);
|
||||
|
||||
QButton *regularSquareButton = new QButton(this, QButton::RegularSquare);
|
||||
regularSquareButton->setText("Button");
|
||||
layout->addWidget(regularSquareButton);
|
||||
|
||||
QButton *disclosureButton = new QButton(this, QButton::Disclosure);
|
||||
layout->addWidget(disclosureButton);
|
||||
|
||||
QButton *shadowlessSquareButton = new QButton(this, QButton::ShadowlessSquare);
|
||||
shadowlessSquareButton->setText("Button");
|
||||
layout->addWidget(shadowlessSquareButton);
|
||||
|
||||
QButton *circularButton = new QButton(this, QButton::Circular);
|
||||
layout->addWidget(circularButton);
|
||||
|
||||
QButton *textureSquareButton = new QButton(this, QButton::TexturedSquare);
|
||||
textureSquareButton->setText("Textured Button");
|
||||
layout->addWidget(textureSquareButton);
|
||||
|
||||
QButton *helpButton = new QButton(this, QButton::HelpButton);
|
||||
layout->addWidget(helpButton);
|
||||
|
||||
QButton *smallSquareButton = new QButton(this, QButton::SmallSquare);
|
||||
smallSquareButton->setText("Gradient Button");
|
||||
layout->addWidget(smallSquareButton);
|
||||
|
||||
QButton *texturedRoundedButton = new QButton(this, QButton::TexturedRounded);
|
||||
texturedRoundedButton->setText("Round Textured");
|
||||
layout->addWidget(texturedRoundedButton);
|
||||
|
||||
QButton *roundedRectangleButton = new QButton(this, QButton::RoundRect);
|
||||
roundedRectangleButton->setText("Rounded Rect Button");
|
||||
layout->addWidget(roundedRectangleButton);
|
||||
|
||||
QButton *recessedButton = new QButton(this, QButton::Recessed);
|
||||
recessedButton->setText("Recessed Button");
|
||||
layout->addWidget(recessedButton);
|
||||
|
||||
QButton *roundedDisclosureButton = new QButton(this, QButton::RoundedDisclosure);
|
||||
layout->addWidget(roundedDisclosureButton);
|
||||
|
||||
#ifdef __MAC_10_7
|
||||
QButton *inlineButton = new QButton(this, QButton::Inline);
|
||||
inlineButton->setText("Inline Button");
|
||||
layout->addWidget(inlineButton);
|
||||
#endif
|
||||
|
||||
|
||||
QProgressIndicatorSpinning *progressIndicatorSpinning = new QProgressIndicatorSpinning(this);
|
||||
progressIndicatorSpinning->animate();
|
||||
layout->addWidget(progressIndicatorSpinning);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#ifndef GALLERY_H
|
||||
#define GALLERY_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class Gallery : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Gallery(QWidget *parent = 0);
|
||||
};
|
||||
|
||||
#endif // WIDGET_H
|
Binary file not shown.
Before Width: | Height: | Size: 41 KiB |
@ -1,13 +0,0 @@
|
||||
#include <QApplication>
|
||||
|
||||
#include "gallery.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication application(argc, argv);
|
||||
|
||||
Gallery gallery;
|
||||
gallery.show();
|
||||
|
||||
return application.exec();
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
#ifndef QBUTTON_H
|
||||
#define QBUTTON_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
|
||||
class QButtonPrivate;
|
||||
class QButton : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Matches NSBezelStyle
|
||||
enum BezelStyle {
|
||||
Rounded = 1,
|
||||
RegularSquare = 2,
|
||||
Disclosure = 5,
|
||||
ShadowlessSquare = 6,
|
||||
Circular = 7,
|
||||
TexturedSquare = 8,
|
||||
HelpButton = 9,
|
||||
SmallSquare = 10,
|
||||
TexturedRounded = 11,
|
||||
RoundRect = 12,
|
||||
Recessed = 13,
|
||||
RoundedDisclosure = 14,
|
||||
#ifdef __MAC_10_7
|
||||
Inline = 15
|
||||
#endif
|
||||
};
|
||||
|
||||
explicit QButton(QWidget *parent, BezelStyle bezelStyle = Rounded);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setText(const QString &text);
|
||||
void setImage(const QPixmap &image);
|
||||
void setChecked(bool checked);
|
||||
|
||||
public:
|
||||
void setCheckable(bool checkable);
|
||||
bool isChecked();
|
||||
|
||||
Q_SIGNALS:
|
||||
void clicked(bool checked = false);
|
||||
|
||||
private:
|
||||
friend class QButtonPrivate;
|
||||
QPointer<QButtonPrivate> pimpl;
|
||||
};
|
||||
#endif // QBUTTON_H
|
@ -1,229 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 by Mike McQuaid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qbutton.h"
|
||||
|
||||
#include "qocoa_mac.h"
|
||||
|
||||
#import "Foundation/NSAutoreleasePool.h"
|
||||
#import "AppKit/NSButton.h"
|
||||
#import "AppKit/NSFont.h"
|
||||
|
||||
class QButtonPrivate : public QObject
|
||||
{
|
||||
public:
|
||||
QButtonPrivate(QButton *qButton, NSButton *nsButton, QButton::BezelStyle bezelStyle)
|
||||
: QObject(qButton), qButton(qButton), nsButton(nsButton)
|
||||
{
|
||||
switch(bezelStyle) {
|
||||
case QButton::Disclosure:
|
||||
case QButton::Circular:
|
||||
#ifdef __MAC_10_7
|
||||
case QButton::Inline:
|
||||
#endif
|
||||
case QButton::RoundedDisclosure:
|
||||
case QButton::HelpButton:
|
||||
[nsButton setTitle:@""];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NSFont* font = 0;
|
||||
switch(bezelStyle) {
|
||||
case QButton::RoundRect:
|
||||
font = [NSFont fontWithName:@"Lucida Grande" size:12];
|
||||
break;
|
||||
|
||||
case QButton::Recessed:
|
||||
font = [NSFont fontWithName:@"Lucida Grande Bold" size:12];
|
||||
break;
|
||||
|
||||
#ifdef __MAC_10_7
|
||||
case QButton::Inline:
|
||||
font = [NSFont boldSystemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]];
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
|
||||
break;
|
||||
}
|
||||
[nsButton setFont:font];
|
||||
|
||||
switch(bezelStyle) {
|
||||
case QButton::Rounded:
|
||||
qButton->setMinimumWidth(40);
|
||||
qButton->setFixedHeight(24);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
break;
|
||||
case QButton::RegularSquare:
|
||||
case QButton::TexturedSquare:
|
||||
qButton->setMinimumSize(14, 23);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
break;
|
||||
case QButton::ShadowlessSquare:
|
||||
qButton->setMinimumSize(5, 25);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
break;
|
||||
case QButton::SmallSquare:
|
||||
qButton->setMinimumSize(4, 21);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
break;
|
||||
case QButton::TexturedRounded:
|
||||
qButton->setMinimumSize(10, 22);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
break;
|
||||
case QButton::RoundRect:
|
||||
case QButton::Recessed:
|
||||
qButton->setMinimumWidth(16);
|
||||
qButton->setFixedHeight(18);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
break;
|
||||
case QButton::Disclosure:
|
||||
qButton->setMinimumWidth(13);
|
||||
qButton->setFixedHeight(13);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
break;
|
||||
case QButton::Circular:
|
||||
qButton->setMinimumSize(16, 16);
|
||||
qButton->setMaximumHeight(40);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
break;
|
||||
case QButton::HelpButton:
|
||||
case QButton::RoundedDisclosure:
|
||||
qButton->setMinimumWidth(22);
|
||||
qButton->setFixedHeight(22);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
break;
|
||||
#ifdef __MAC_10_7
|
||||
case QButton::Inline:
|
||||
qButton->setMinimumWidth(10);
|
||||
qButton->setFixedHeight(16);
|
||||
qButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
switch(bezelStyle) {
|
||||
case QButton::Recessed:
|
||||
[nsButton setButtonType:NSPushOnPushOffButton];
|
||||
case QButton::Disclosure:
|
||||
[nsButton setButtonType:NSOnOffButton];
|
||||
default:
|
||||
[nsButton setButtonType:NSMomentaryPushInButton];
|
||||
}
|
||||
|
||||
[nsButton setBezelStyle:bezelStyle];
|
||||
}
|
||||
|
||||
void clicked()
|
||||
{
|
||||
Q_EMIT qButton->clicked(qButton->isChecked());
|
||||
}
|
||||
|
||||
~QButtonPrivate() {
|
||||
[[nsButton target] release];
|
||||
[nsButton setTarget:nil];
|
||||
}
|
||||
|
||||
QButton *qButton;
|
||||
NSButton *nsButton;
|
||||
};
|
||||
|
||||
@interface QButtonTarget : NSObject
|
||||
{
|
||||
@public
|
||||
QPointer<QButtonPrivate> pimpl;
|
||||
}
|
||||
-(void)clicked;
|
||||
@end
|
||||
|
||||
@implementation QButtonTarget
|
||||
-(void)clicked {
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
pimpl->clicked();
|
||||
}
|
||||
@end
|
||||
|
||||
QButton::QButton(QWidget *parent, BezelStyle bezelStyle) : QWidget(parent)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSButton *button = [[NSButton alloc] init];
|
||||
pimpl = new QButtonPrivate(this, button, bezelStyle);
|
||||
|
||||
QButtonTarget *target = [[QButtonTarget alloc] init];
|
||||
target->pimpl = pimpl;
|
||||
[button setTarget:target];
|
||||
|
||||
[button setAction:@selector(clicked)];
|
||||
|
||||
setupLayout(button, this);
|
||||
|
||||
[button release];
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
void QButton::setText(const QString &text)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[pimpl->nsButton setTitle:fromQString(text)];
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
void QButton::setImage(const QPixmap &image)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
[pimpl->nsButton setImage:fromQPixmap(image)];
|
||||
}
|
||||
|
||||
void QButton::setChecked(bool checked)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
[pimpl->nsButton setState:checked];
|
||||
}
|
||||
|
||||
void QButton::setCheckable(bool checkable)
|
||||
{
|
||||
const NSInteger cellMask = checkable ? NSChangeBackgroundCellMask : NSNoCellMask;
|
||||
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
[[pimpl->nsButton cell] setShowsStateBy:cellMask];
|
||||
}
|
||||
|
||||
bool QButton::isChecked()
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return false;
|
||||
|
||||
return [pimpl->nsButton state];
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 by Mike McQuaid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qbutton.h"
|
||||
|
||||
#include <QToolBar>
|
||||
#include <QToolButton>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class QButtonPrivate : public QObject
|
||||
{
|
||||
public:
|
||||
QButtonPrivate(QButton *button, QAbstractButton *abstractButton)
|
||||
: QObject(button), abstractButton(abstractButton) {}
|
||||
QPointer<QAbstractButton> abstractButton;
|
||||
};
|
||||
|
||||
QButton::QButton(QWidget *parent, BezelStyle) : QWidget(parent)
|
||||
{
|
||||
QAbstractButton *button = 0;
|
||||
if (qobject_cast<QToolBar*>(parent))
|
||||
button = new QToolButton(this);
|
||||
else
|
||||
button = new QPushButton(this);
|
||||
connect(button, SIGNAL(clicked()),
|
||||
this, SIGNAL(clicked()));
|
||||
pimpl = new QButtonPrivate(this, button);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
layout->addWidget(button);
|
||||
}
|
||||
|
||||
void QButton::setText(const QString &text)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
pimpl->abstractButton->setText(text);
|
||||
}
|
||||
|
||||
void QButton::setImage(const QPixmap &image)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
pimpl->abstractButton->setIcon(image);
|
||||
}
|
||||
|
||||
void QButton::setChecked(bool checked)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
pimpl->abstractButton->setChecked(checked);
|
||||
}
|
||||
|
||||
void QButton::setCheckable(bool checkable)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
pimpl->abstractButton->setCheckable(checkable);
|
||||
}
|
||||
|
||||
bool QButton::isChecked()
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return false;
|
||||
|
||||
return pimpl->abstractButton->isChecked();
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 by Mike McQuaid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <AppKit/NSImage.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <QString>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMacCocoaViewContainer>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <qmacfunctions.h>
|
||||
#endif
|
||||
|
||||
static inline NSString* fromQString(const QString &string)
|
||||
{
|
||||
const QByteArray utf8 = string.toUtf8();
|
||||
const char* cString = utf8.constData();
|
||||
return [[NSString alloc] initWithUTF8String:cString];
|
||||
}
|
||||
|
||||
static inline QString toQString(NSString *string)
|
||||
{
|
||||
if (!string)
|
||||
return QString();
|
||||
return QString::fromUtf8([string UTF8String]);
|
||||
}
|
||||
|
||||
static inline NSImage* fromQPixmap(const QPixmap &pixmap)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
CGImageRef cgImage = pixmap.toMacCGImageRef();
|
||||
#else
|
||||
CGImageRef cgImage = QtMac::toCGImageRef(pixmap);
|
||||
#endif
|
||||
return [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize];
|
||||
}
|
||||
|
||||
static inline void setupLayout(NSView *cocoaView, QWidget *parent)
|
||||
{
|
||||
parent->setAttribute(Qt::WA_NativeWindow);
|
||||
QVBoxLayout *layout = new QVBoxLayout(parent);
|
||||
layout->setMargin(0);
|
||||
layout->addWidget(new QMacCocoaViewContainer(cocoaView, parent));
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#ifndef QPROGRESSINDICATORSPINNING_H
|
||||
#define QPROGRESSINDICATORSPINNING_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
|
||||
class QProgressIndicatorSpinningPrivate;
|
||||
class QProgressIndicatorSpinning : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Matches NSProgressIndicatorThickness
|
||||
enum Thickness {
|
||||
Default = 14,
|
||||
Small = 10,
|
||||
Large = 18,
|
||||
Aqua = 12
|
||||
};
|
||||
|
||||
explicit QProgressIndicatorSpinning(QWidget *parent,
|
||||
Thickness thickness = Default);
|
||||
public Q_SLOTS:
|
||||
void animate(bool animate = true);
|
||||
private:
|
||||
friend class QProgressIndicatorSpinningPrivate;
|
||||
QPointer<QProgressIndicatorSpinningPrivate> pimpl;
|
||||
};
|
||||
|
||||
#endif // QPROGRESSINDICATORSPINNING_H
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 by Mike McQuaid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qprogressindicatorspinning.h"
|
||||
|
||||
#include "qocoa_mac.h"
|
||||
|
||||
#import "Foundation/NSAutoreleasePool.h"
|
||||
#import "AppKit/NSProgressIndicator.h"
|
||||
|
||||
class QProgressIndicatorSpinningPrivate : public QObject
|
||||
{
|
||||
public:
|
||||
QProgressIndicatorSpinningPrivate(QProgressIndicatorSpinning *qProgressIndicatorSpinning,
|
||||
NSProgressIndicator *nsProgressIndicator)
|
||||
: QObject(qProgressIndicatorSpinning), nsProgressIndicator(nsProgressIndicator) {}
|
||||
|
||||
NSProgressIndicator *nsProgressIndicator;
|
||||
};
|
||||
|
||||
QProgressIndicatorSpinning::QProgressIndicatorSpinning(QWidget *parent,
|
||||
Thickness thickness)
|
||||
: QWidget(parent)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSProgressIndicator *progress = [[NSProgressIndicator alloc] init];
|
||||
[progress setStyle:NSProgressIndicatorSpinningStyle];
|
||||
|
||||
pimpl = new QProgressIndicatorSpinningPrivate(this, progress);
|
||||
|
||||
setupLayout(progress, this);
|
||||
|
||||
setFixedSize(thickness, thickness);
|
||||
|
||||
[progress release];
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
void QProgressIndicatorSpinning::animate(bool animate)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
if (animate)
|
||||
[pimpl->nsProgressIndicator startAnimation:nil];
|
||||
else
|
||||
[pimpl->nsProgressIndicator stopAnimation:nil];
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 by Mike McQuaid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qprogressindicatorspinning.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QMovie>
|
||||
#include <QLabel>
|
||||
|
||||
class QProgressIndicatorSpinningPrivate : public QObject
|
||||
{
|
||||
public:
|
||||
QProgressIndicatorSpinningPrivate(QProgressIndicatorSpinning *qProgressIndicatorSpinning,
|
||||
QMovie *movie)
|
||||
: QObject(qProgressIndicatorSpinning), movie(movie) {}
|
||||
|
||||
QPointer<QMovie> movie;
|
||||
};
|
||||
|
||||
QProgressIndicatorSpinning::QProgressIndicatorSpinning(QWidget *parent,
|
||||
Thickness thickness)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
|
||||
QSize size(thickness, thickness);
|
||||
QMovie *movie = new QMovie(this);
|
||||
movie->setFileName(":/Qocoa/qprogressindicatorspinning_nonmac.gif");
|
||||
movie->setScaledSize(size);
|
||||
// Roughly match OSX speed.
|
||||
movie->setSpeed(200);
|
||||
pimpl = new QProgressIndicatorSpinningPrivate(this, movie);
|
||||
|
||||
QLabel *label = new QLabel(this);
|
||||
label->setMovie(movie);
|
||||
|
||||
layout->addWidget(label);
|
||||
setFixedSize(size);
|
||||
}
|
||||
|
||||
|
||||
void QProgressIndicatorSpinning::animate(bool animate)
|
||||
{
|
||||
Q_ASSERT(pimpl && pimpl->movie);
|
||||
if (!(pimpl && pimpl->movie))
|
||||
return;
|
||||
|
||||
if (animate)
|
||||
pimpl->movie->start();
|
||||
else
|
||||
pimpl->movie->stop();
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.1 KiB |
@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/Qocoa">
|
||||
<file>qprogressindicatorspinning_nonmac.gif</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -1,48 +0,0 @@
|
||||
#ifndef QSEARCHFIELD_H
|
||||
#define QSEARCHFIELD_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
#include <QMenu>
|
||||
|
||||
class QSearchFieldPrivate;
|
||||
class QSearchField : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true);
|
||||
Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText);
|
||||
|
||||
public:
|
||||
explicit QSearchField(QWidget *parent);
|
||||
|
||||
QString text() const;
|
||||
QString placeholderText() const;
|
||||
void setFocus(Qt::FocusReason);
|
||||
void setMenu(QMenu *menu);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setText(const QString &text);
|
||||
void setPlaceholderText(const QString &text);
|
||||
void clear();
|
||||
void selectAll();
|
||||
void setFocus();
|
||||
|
||||
Q_SIGNALS:
|
||||
void textChanged(const QString &text);
|
||||
void editingFinished();
|
||||
void returnPressed();
|
||||
|
||||
private Q_SLOTS:
|
||||
void popupMenu();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent*);
|
||||
void resizeEvent(QResizeEvent*);
|
||||
|
||||
private:
|
||||
friend class QSearchFieldPrivate;
|
||||
QPointer <QSearchFieldPrivate> pimpl;
|
||||
};
|
||||
|
||||
#endif // QSEARCHFIELD_H
|
@ -1,262 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 by Mike McQuaid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qsearchfield.h"
|
||||
|
||||
#include "qocoa_mac.h"
|
||||
|
||||
#import "Foundation/NSAutoreleasePool.h"
|
||||
#import "Foundation/NSNotification.h"
|
||||
#import "AppKit/NSSearchField.h"
|
||||
|
||||
#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)
|
||||
: QObject(qSearchField), qSearchField(qSearchField), nsSearchField(nsSearchField) {}
|
||||
|
||||
void textDidChange(const QString &text)
|
||||
{
|
||||
if (qSearchField)
|
||||
Q_EMIT qSearchField->textChanged(text);
|
||||
}
|
||||
|
||||
void textDidEndEditing()
|
||||
{
|
||||
if (qSearchField)
|
||||
Q_EMIT qSearchField->editingFinished();
|
||||
}
|
||||
|
||||
void returnPressed()
|
||||
{
|
||||
if (qSearchField)
|
||||
Q_EMIT qSearchField->returnPressed();
|
||||
}
|
||||
|
||||
QPointer<QSearchField> qSearchField;
|
||||
NSSearchField *nsSearchField;
|
||||
};
|
||||
|
||||
@interface QSearchFieldDelegate : NSObject<NSTextFieldDelegate>
|
||||
{
|
||||
@public
|
||||
QPointer<QSearchFieldPrivate> pimpl;
|
||||
}
|
||||
-(void)controlTextDidChange:(NSNotification*)notification;
|
||||
-(void)controlTextDidEndEditing:(NSNotification*)notification;
|
||||
@end
|
||||
|
||||
@implementation QSearchFieldDelegate
|
||||
-(void)controlTextDidChange:(NSNotification*)notification {
|
||||
Q_ASSERT(pimpl);
|
||||
if (pimpl)
|
||||
pimpl->textDidChange(toQString([[notification object] stringValue]));
|
||||
}
|
||||
|
||||
-(void)controlTextDidEndEditing:(NSNotification*)notification {
|
||||
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 NO;
|
||||
}
|
||||
else if (keyCode == KEYCODE_C)
|
||||
{
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
clipboard->setText(toQString([self stringValue]));
|
||||
return NO;
|
||||
}
|
||||
else if (keyCode == KEYCODE_V)
|
||||
{
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
[self setStringValue:fromQString(clipboard->text())];
|
||||
return NO;
|
||||
}
|
||||
else if (keyCode == KEYCODE_X)
|
||||
{
|
||||
QClipboard* clipboard = QApplication::clipboard();
|
||||
clipboard->setText(toQString([self stringValue]));
|
||||
[self setStringValue:@""];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
@end
|
||||
|
||||
QSearchField::QSearchField(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSSearchField *search = [[QocoaSearchField alloc] init];
|
||||
|
||||
QSearchFieldDelegate *delegate = [[QSearchFieldDelegate alloc] init];
|
||||
pimpl = delegate->pimpl = new QSearchFieldPrivate(this, search);
|
||||
[search setDelegate:delegate];
|
||||
|
||||
setupLayout(search, this);
|
||||
|
||||
setFixedHeight(24);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
||||
[search release];
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
void QSearchField::setMenu(QMenu *menu)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
NSMenu *nsMenu = menu->macMenu();
|
||||
#else
|
||||
NSMenu *nsMenu = menu->toNSMenu();
|
||||
#endif
|
||||
|
||||
[[pimpl->nsSearchField cell] setSearchMenuTemplate:nsMenu];
|
||||
}
|
||||
|
||||
void QSearchField::popupMenu()
|
||||
{
|
||||
}
|
||||
|
||||
void QSearchField::setText(const QString &text)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[pimpl->nsSearchField setStringValue:fromQString(text)];
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
void QSearchField::clear()
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
[pimpl->nsSearchField setStringValue:@""];
|
||||
Q_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)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
if ([pimpl->nsSearchField acceptsFirstResponder])
|
||||
[[pimpl->nsSearchField window] makeFirstResponder: pimpl->nsSearchField];
|
||||
}
|
||||
|
||||
void QSearchField::setFocus()
|
||||
{
|
||||
setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
|
||||
void QSearchField::changeEvent(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::EnabledChange) {
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
const bool enabled = isEnabled();
|
||||
[pimpl->nsSearchField setEnabled: enabled];
|
||||
}
|
||||
QWidget::changeEvent(event);
|
||||
}
|
||||
|
||||
void QSearchField::resizeEvent(QResizeEvent *resizeEvent)
|
||||
{
|
||||
QWidget::resizeEvent(resizeEvent);
|
||||
}
|
@ -1,256 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 by Mike McQuaid
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qsearchfield.h"
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QVBoxLayout>
|
||||
#include <QToolButton>
|
||||
#include <QStyle>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
|
||||
class QSearchFieldPrivate : public QObject
|
||||
{
|
||||
public:
|
||||
QSearchFieldPrivate(QSearchField *searchField, QLineEdit *lineEdit, QToolButton *clearButton, QToolButton *searchButton)
|
||||
: QObject(searchField), lineEdit(lineEdit), clearButton(clearButton), searchButton(searchButton) {}
|
||||
|
||||
int lineEditFrameWidth() const {
|
||||
return lineEdit->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||
}
|
||||
|
||||
int clearButtonPaddedWidth() const {
|
||||
return clearButton->width() + lineEditFrameWidth() * 2;
|
||||
}
|
||||
|
||||
int clearButtonPaddedHeight() const {
|
||||
return clearButton->height() + lineEditFrameWidth() * 2;
|
||||
}
|
||||
|
||||
int searchButtonPaddedWidth() const {
|
||||
return searchButton->width() + lineEditFrameWidth() * 2;
|
||||
}
|
||||
|
||||
int searchButtonPaddedHeight() const {
|
||||
return searchButton->height() + lineEditFrameWidth() * 2;
|
||||
}
|
||||
|
||||
QPointer<QLineEdit> lineEdit;
|
||||
QPointer<QToolButton> clearButton;
|
||||
QPointer<QToolButton> searchButton;
|
||||
QPointer<QMenu> searchMenu;
|
||||
};
|
||||
|
||||
QSearchField::QSearchField(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
QLineEdit *lineEdit = new QLineEdit(this);
|
||||
connect(lineEdit, SIGNAL(textChanged(QString)),
|
||||
this, SIGNAL(textChanged(QString)));
|
||||
connect(lineEdit, SIGNAL(editingFinished()),
|
||||
this, SIGNAL(editingFinished()));
|
||||
connect(lineEdit, SIGNAL(returnPressed()),
|
||||
this, SIGNAL(returnPressed()));
|
||||
connect(lineEdit, SIGNAL(textChanged(QString)),
|
||||
this, SLOT(setText(QString)));
|
||||
|
||||
int iconsize = style()->pixelMetric(QStyle::PM_SmallIconSize);
|
||||
QToolButton *clearButton = new QToolButton(this);
|
||||
QIcon clearIcon = QIcon::fromTheme(QLatin1String("edit-clear"),
|
||||
QIcon(QLatin1String(":/Qocoa/qsearchfield_nonmac_clear.png")));
|
||||
clearButton->setIcon(clearIcon);
|
||||
clearButton->setIconSize(QSize(iconsize, iconsize));
|
||||
clearButton->setFixedSize(QSize(iconsize, iconsize));
|
||||
clearButton->setStyleSheet("border: none;");
|
||||
clearButton->hide();
|
||||
connect(clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||
|
||||
QToolButton *searchButton = new QToolButton(this);
|
||||
QIcon searchIcon = QIcon(QLatin1String(":/Qocoa/qsearchfield_nonmac_magnifier.png"));
|
||||
searchButton->setIcon(searchIcon);
|
||||
searchButton->setIconSize(QSize(iconsize, iconsize));
|
||||
searchButton->setFixedSize(QSize(iconsize, iconsize));
|
||||
searchButton->setStyleSheet("border: none;");
|
||||
searchButton->setPopupMode(QToolButton::InstantPopup);
|
||||
searchButton->setEnabled(false);
|
||||
connect(searchButton, SIGNAL(clicked()), this, SLOT(popupMenu()));
|
||||
|
||||
pimpl = new QSearchFieldPrivate(this, lineEdit, clearButton, searchButton);
|
||||
|
||||
lineEdit->setStyleSheet(QString("QLineEdit { padding-left: %1px; padding-right: %2px; } ")
|
||||
.arg(pimpl->searchButtonPaddedWidth())
|
||||
.arg(pimpl->clearButtonPaddedWidth()));
|
||||
const int width = qMax(lineEdit->minimumSizeHint().width(), pimpl->clearButtonPaddedWidth() + pimpl->searchButtonPaddedWidth());
|
||||
const int height = qMax(lineEdit->minimumSizeHint().height(),
|
||||
qMax(pimpl->clearButtonPaddedHeight(),
|
||||
pimpl->searchButtonPaddedHeight()));
|
||||
lineEdit->setMinimumSize(width, height);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
layout->addWidget(lineEdit);
|
||||
}
|
||||
|
||||
void QSearchField::setMenu(QMenu *menu)
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
pimpl->searchMenu = menu;
|
||||
|
||||
QIcon searchIcon = menu ? QIcon(QLatin1String(":/Qocoa/qsearchfield_nonmac_magnifier_menu.png"))
|
||||
: QIcon(QLatin1String(":/Qocoa/qsearchfield_nonmac_magnifier.png"));
|
||||
pimpl->searchButton->setIcon(searchIcon);
|
||||
pimpl->searchButton->setEnabled(isEnabled() && menu);
|
||||
}
|
||||
|
||||
void QSearchField::popupMenu()
|
||||
{
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
if (pimpl->searchMenu) {
|
||||
const QRect screenRect = qApp->desktop()->availableGeometry(pimpl->searchButton);
|
||||
const QSize sizeHint = pimpl->searchMenu->sizeHint();
|
||||
const QRect rect = pimpl->searchButton->rect();
|
||||
const int x = pimpl->searchButton->isRightToLeft()
|
||||
? rect.right() - sizeHint.width()
|
||||
: rect.left();
|
||||
const int y = pimpl->searchButton->mapToGlobal(QPoint(0, rect.bottom())).y() + sizeHint.height() <= screenRect.height()
|
||||
? rect.bottom()
|
||||
: rect.top() - sizeHint.height();
|
||||
QPoint point = pimpl->searchButton->mapToGlobal(QPoint(x, y));
|
||||
point.rx() = qMax(screenRect.left(), qMin(point.x(), screenRect.right() - sizeHint.width()));
|
||||
point.ry() += 1;
|
||||
|
||||
pimpl->searchMenu->popup(point);
|
||||
}
|
||||
}
|
||||
|
||||
void QSearchField::changeEvent(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::EnabledChange) {
|
||||
Q_ASSERT(pimpl);
|
||||
if (!pimpl)
|
||||
return;
|
||||
|
||||
const bool enabled = isEnabled();
|
||||
pimpl->searchButton->setEnabled(enabled && pimpl->searchMenu);
|
||||
pimpl->lineEdit->setEnabled(enabled);
|
||||
pimpl->clearButton->setEnabled(enabled);
|
||||
}
|
||||
QWidget::changeEvent(event);
|
||||
}
|
||||
|
||||
void QSearchField::setText(const QString &text)
|
||||
{
|
||||
Q_ASSERT(pimpl && pimpl->clearButton && pimpl->lineEdit);
|
||||
if (!(pimpl && pimpl->clearButton && pimpl->lineEdit))
|
||||
return;
|
||||
|
||||
pimpl->clearButton->setVisible(!text.isEmpty());
|
||||
|
||||
if (text != this->text())
|
||||
pimpl->lineEdit->setText(text);
|
||||
}
|
||||
|
||||
void QSearchField::setPlaceholderText(const QString &text)
|
||||
{
|
||||
Q_ASSERT(pimpl && pimpl->lineEdit);
|
||||
if (!(pimpl && pimpl->lineEdit))
|
||||
return;
|
||||
|
||||
#if QT_VERSION >= 0x040700
|
||||
pimpl->lineEdit->setPlaceholderText(text);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QSearchField::clear()
|
||||
{
|
||||
Q_ASSERT(pimpl && pimpl->lineEdit);
|
||||
if (!(pimpl && pimpl->lineEdit))
|
||||
return;
|
||||
|
||||
pimpl->lineEdit->clear();
|
||||
}
|
||||
|
||||
void QSearchField::selectAll()
|
||||
{
|
||||
Q_ASSERT(pimpl && pimpl->lineEdit);
|
||||
if (!(pimpl && pimpl->lineEdit))
|
||||
return;
|
||||
|
||||
pimpl->lineEdit->selectAll();
|
||||
}
|
||||
|
||||
QString QSearchField::text() const
|
||||
{
|
||||
Q_ASSERT(pimpl && pimpl->lineEdit);
|
||||
if (!(pimpl && pimpl->lineEdit))
|
||||
return QString();
|
||||
|
||||
return pimpl->lineEdit->text();
|
||||
}
|
||||
|
||||
QString QSearchField::placeholderText() const {
|
||||
Q_ASSERT(pimpl && pimpl->lineEdit);
|
||||
if (!(pimpl && pimpl->lineEdit))
|
||||
return QString();
|
||||
|
||||
#if QT_VERSION >= 0x040700
|
||||
return pimpl->lineEdit->placeholderText();
|
||||
#else
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
void QSearchField::setFocus(Qt::FocusReason reason)
|
||||
{
|
||||
Q_ASSERT(pimpl && pimpl->lineEdit);
|
||||
if (pimpl && pimpl->lineEdit)
|
||||
pimpl->lineEdit->setFocus(reason);
|
||||
}
|
||||
|
||||
void QSearchField::setFocus()
|
||||
{
|
||||
setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
|
||||
void QSearchField::resizeEvent(QResizeEvent *resizeEvent)
|
||||
{
|
||||
Q_ASSERT(pimpl && pimpl->clearButton && pimpl->lineEdit);
|
||||
if (!(pimpl && pimpl->clearButton && pimpl->lineEdit))
|
||||
return;
|
||||
|
||||
QWidget::resizeEvent(resizeEvent);
|
||||
const int x = width() - pimpl->clearButtonPaddedWidth();
|
||||
const int y = (height() - pimpl->clearButton->height())/2;
|
||||
pimpl->clearButton->move(x, y);
|
||||
|
||||
pimpl->searchButton->move(pimpl->lineEditFrameWidth() * 2,
|
||||
(height() - pimpl->searchButton->height())/2);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/Qocoa">
|
||||
<file>qsearchfield_nonmac_clear.png</file>
|
||||
<file>qsearchfield_nonmac_magnifier_menu.png</file>
|
||||
<file>qsearchfield_nonmac_magnifier.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
Binary file not shown.
Before Width: | Height: | Size: 736 B |
Binary file not shown.
Before Width: | Height: | Size: 300 B |
Binary file not shown.
Before Width: | Height: | Size: 439 B |
Loading…
Reference in New Issue
Block a user