Start color code parsing, hook up input to actually send it. ITS ALIVE

This commit is contained in:
Mikko Ahlroth 2014-09-28 22:01:29 +03:00
parent efbf4ba81d
commit 7561c4ccc9
12 changed files with 196 additions and 61 deletions

View file

@ -39,7 +39,8 @@ OTHER_FILES += qml/harbour-weechatrelay.qml \
qml/js/uniqid.js \ qml/js/uniqid.js \
qml/pages/BufferView.qml \ qml/pages/BufferView.qml \
qml/js/config.js \ qml/js/config.js \
qml/pages/BufferList.qml qml/pages/BufferList.qml \
qml/js/weechatcolors.js
HEADERS += \ HEADERS += \
src/relayconnection.h \ src/relayconnection.h \

View file

@ -16,19 +16,28 @@
.import "moment.js" as M .import "moment.js" as M
.import "debug.js" as D .import "debug.js" as D
var _textListComponent = Qt.createComponent('../pages/TextListComponent.qml');
function Buffer(pointer, number, name, title) { function Buffer(pointer, number, name, title) {
this.pointer = pointer; this.pointer = pointer;
this.number = number; this.number = number;
this.name = name; this.name = name;
this.title = title; this.title = title;
this.textList = _textListComponent.createObject(_parentPage); // A listmodel where we put the messages of this buffer
this.textList = Qt.createQmlObject('import QtQuick 2.0; ListModel {}',
_parentPage);
// Add line to this buffer // Add line to this buffer
this.add = function(moment, str) { this.add = function(moment, prefix, str) {
this.textList.add(moment, str); this.textList.insert(0, {
time: moment.format('HH:mm:ss'),
prefix: prefix,
str: str
});
};
// Send input into this buffer
this.input = function(str) {
EQ.command('input 0x' + this.pointer + ' ' + str);
}; };
} }
@ -39,7 +48,7 @@ var _buffers = {};
// according to buffer number whenever requested // according to buffer number whenever requested
var _buffersList = []; var _buffersList = [];
// Page that will own all of our textlistcomponents // Page that will own all of our textlistmodels
var _parentPage = null; var _parentPage = null;
@ -129,7 +138,7 @@ function lineAdded(data) {
var buffer = data.buffer; var buffer = data.buffer;
var date = M.moment(data.date); var date = M.moment(data.date);
_buffers[buffer].add(date, data.message); _buffers[buffer].add(date, data.prefix, data.message);
} }
function _sortBuffersList() { function _sortBuffersList() {

View file

@ -61,13 +61,13 @@ function init(connectionHandler, pageStack) {
// Signal handlers for incoming data from connection // Signal handlers for incoming data from connection
function newEvent(id, data) { function newEvent(id, data) {
D.d("Event received: " + id); D.c("Event received: " + id);
D.d(JSON.stringify(data)); D.c(JSON.stringify(data));
EQ.handleEvent(id, data); EQ.handleEvent(id, data);
} }
function onDisplayDebugData(str) { function onDisplayDebugData(str) {
D.d(str); D.c(str);
} }
function onConnected() { function onConnected() {
@ -89,7 +89,7 @@ function onSslError(errorStrings,
startDate, startDate,
expiryDate, expiryDate,
digest) { digest) {
D.d("SSL verification error when connecting"); D.d("SSL verification error when connecting!");
sslVerifyDialog = ps.push("../pages/SslVerifyDialog.qml", sslVerifyDialog = ps.push("../pages/SslVerifyDialog.qml",
{ {
@ -106,7 +106,9 @@ function onSslError(errorStrings,
function connect(connObj) { function connect(connObj) {
debugViewPage = ps.replace("../pages/BufferView.qml"); debugViewPage = ps.replace("../pages/BufferView.qml");
bufferListPage = ps.pushAttached("../pages/BufferList.qml"); bufferListPage = ps.pushAttached("../pages/BufferList.qml", {
bufferViewPage: debugViewPage
});
B.setDebugPage(debugViewPage); B.setDebugPage(debugViewPage);
D.d("Connecting..."); D.d("Connecting...");
@ -175,7 +177,7 @@ function clearConnection() {
// Send a command to the WeeChat server // Send a command to the WeeChat server
function send(str) { function send(str) {
D.d("Sending command: " + str); D.c("Sending command: " + str);
handler.send(str); handler.send(str);
} }

View file

@ -14,7 +14,7 @@ var _buffer = null;
// Write a line to the debug view (will go to console if debug view isn't open) // Write a line to the debug view (will go to console if debug view isn't open)
function debug(str) { function debug(str) {
if (_buffer !== undefined && _buffer !== null) { if (_buffer !== undefined && _buffer !== null) {
_buffer.add(M.moment(), str); _buffer.add(M.moment(), 'DEBUG', str);
} }
else { else {
console.log(str); console.log(str);

View file

@ -17,8 +17,6 @@
var _pendingEvents = {}; var _pendingEvents = {};
function handleEvent(id, data) { function handleEvent(id, data) {
//D.d("Handling " + id);
//D.d(JSON.stringify(_pendingEvents));
if (id in _pendingEvents) { if (id in _pendingEvents) {
var c = _pendingEvents[id]; var c = _pendingEvents[id];
c.callback(data); c.callback(data);
@ -44,8 +42,6 @@ function command(command, callback) {
if (read_write) { if (read_write) {
var id = UID.get(); var id = UID.get();
command = "(" + id + ") " + command; command = "(" + id + ") " + command;
//D.d("Adding handler for " + id);
addHandler(id, callback, true); addHandler(id, callback, true);
} }

View file

@ -1,5 +1,13 @@
/*
* © Mikko Ahlroth 2014
* WeeCRApp is open source software. For licensing information, please check
* the LICENCE file.
*/
// Miscellaneous functions for generic use // Miscellaneous functions for generic use
.pragma library
// Escape strings for Text.StyledText // Escape strings for Text.StyledText
function escapeStyled(string) { function escapeStyled(string) {
string = string.replace('&', '&'); string = string.replace('&', '&');
@ -11,3 +19,8 @@ function escapeStyled(string) {
function colored(color, string) { function colored(color, string) {
return '<font color="' + color + '">' + string + '</font>'; return '<font color="' + color + '">' + string + '</font>';
} }
// Return bold text
function bold(string) {
return '<b>' + string + '</b>';
}

126
qml/js/weechatcolors.js Normal file
View file

@ -0,0 +1,126 @@
/*
* © Mikko Ahlroth 2014
* WeeCRApp is open source software. For licensing information, please check
* the LICENCE file.
*/
// Utilities for parsing WeeChat color codes sent
// in the relay protocol
.pragma library
// Protocol specific constants
// Starting bytes
var COLOR_START = 0x19;
var SET_ATTR = 0x1A;
var REMOVE_ATTR = 0x1B;
var RESET = 0x1C;
var START_RE = /^(\u0019|\u001a|\u001b|\u001c)/;
// Attributes
var ATTR_BOLD = '*';
var ATTR_REVERSE = '!';
var ATTR_ITALIC = '/';
var ATTR_UNDERLINE = '_';
var ATTR_KEEP = '|';
// A section of text which has the given attributes:
// fgColor: Foreground color as weechat color number
// bgColor: Background color --//--
// attributes: List of attributes from the selection above,
// except ATTR_KEEP.
function CodedTextSection(str, fgColor, bgColor, attributes) {
this.str = str;
this.fgColor = fgColor;
this.bgColor = bgColor;
this.attributes = attributes;
}
// Parse coded text and return list of CodedTextSection
function parseString(str) {
var out = [];
var currentMode = null;
var currentFg = null;
var currentBg = null;
var currentAttr = [];
var currentStr = null;
var parts = str.split(START_RE);
for (var i = 0; i < parts.length; ++i) {
// Every even index is a content part
if ((i % 2) === 0) {
// The first part won't have any extra info
if (i !== 0) {
switch (currentMode) {
case COLOR_START:
currentStr = parseColorStart(parts[i], currentFg, currentBg, currentAttr);
break;
case SET_ATTR:
currentStr = parseSetAttr(parts[i], currentFg, currentBg, currentAttr);
break;
case REMOVE_ATTR:
currentStr = parseRemoveAttr(parts[i], currentFg, currentBg, currentAttr);
break;
case RESET:
currentFg = null;
currentBg = null;
currentAttr = null;
break;
}
}
out.push(new CodedTextSection(currentStr, currentFg, currentBg, currentAttr));
}
// The odd parts give the next mode
else {
currentMode = parts[i];
}
}
return out;
}
function parseColorStart(part, currentFg, currentBg, currentAttr) {
var data = null;
if (part[0] === 'F') {
data = parseASTD(part);
}
}
function parseSetAttr(part, currentFg, currentBg, currentAttr) {
}
function parseRemoveAttr(part, currentFg, currentBg, currentAttr) {
}
// Parse STD (standard color), removing it from the beginning of string
function parseSTD(str) {
}
// Parse EXT (extended color), --//--
function parseEXT(str) {
}
// Parse attributes + STD
function parseASTD(str) {
}
// Parse attributes + EXT
function parseAEXT(str) {
}
// Parse single attribute
function parseATTR(str) {
}

View file

@ -107,7 +107,9 @@ Dialog {
spacing: Theme.paddingLarge spacing: Theme.paddingLarge
DialogHeader { DialogHeader {
title: "Save" title: "Add connection"
acceptText: "Save"
cancelText: "Cancel"
} }
TextField { TextField {

View file

@ -12,6 +12,8 @@ import "../js/buffers.js" as B
Page { Page {
id: bufferListPage id: bufferListPage
property BufferView bufferViewPage : null;
onVisibleChanged: bufferList.updateList(); onVisibleChanged: bufferList.updateList();
SilicaListView { SilicaListView {
@ -20,10 +22,13 @@ Page {
anchors.fill: parent anchors.fill: parent
function updateList() { function updateList() {
bufferListModel.clear();
var buffers = B.getBuffersByNumber(); var buffers = B.getBuffersByNumber();
for (var i = 0; i < buffers.length; ++i) { for (var i = 0; i < buffers.length; ++i) {
bufferListModel.append({ bufferListModel.append({
pointer: buffers[i].pointer,
number: buffers[i].number, number: buffers[i].number,
name: buffers[i].name name: buffers[i].name
}); });
@ -85,7 +90,9 @@ Page {
} }
onClicked: { onClicked: {
console.log(name + " clicked!"); var buffer = B.getBuffer(pointer);
bufferViewPage.changeBuffer(buffer);
pageStack.navigateBack(PageStackAction.Animated);
} }
} }

View file

@ -4,8 +4,6 @@ import "."
import "../js/debug.js" as D import "../js/debug.js" as D
import "../js/connection.js" as C import "../js/connection.js" as C
import "../js/moment.js" as M
import "../js/buffers.js" as B
Page { Page {
id: bufferViewPage id: bufferViewPage
@ -14,6 +12,7 @@ Page {
property string pointer: ""; property string pointer: "";
property int number: 0; property int number: 0;
property string name: ""; property string name: "";
property var buffer: null;
function setTitle(str) { function setTitle(str) {
topic.title = str; topic.title = str;
@ -27,20 +26,12 @@ Page {
isConnected = false; isConnected = false;
} }
function changeBuffer(buffer) { function changeBuffer(newBuffer) {
var textList = buffer.textList; // Replace current list model with new list
D.c('Changing buffer to ' + newBuffer.name);
// Replace current list with new list buffer = newBuffer;
textListItem = textList; topic.title = newBuffer.title;
textListItem.parent = mainFlickable; textList.model = newBuffer.textList;
// HOW DO I SHOT WEB
//mainFlickable.children.push(textListItem);
//textListItem.anchors.top = topic.bottom;
//textListItem.anchors.bottom = inpuRow.top;
textListItem.width = textListItem.parent.width;
textListItem.clip = true;
topic.title = buffer.title;
} }
SilicaFlickable { SilicaFlickable {
@ -53,8 +44,13 @@ Page {
anchors.top: parent.top anchors.top: parent.top
} }
Item { TextListComponent {
id: textListItem id: textList
anchors.top: topic.bottom
anchors.bottom: inputRow.top
width: parent.width
clip: true
} }
Row { Row {
@ -71,11 +67,10 @@ Page {
placeholderText: "Type here" placeholderText: "Type here"
EnterKey.enabled: text.length > 0 EnterKey.enabled: text.length > 0
//EnterKey.iconSource: "image://theme/icon-m-send" EnterKey.iconSource: "image://theme/icon-m-enter-accept"
EnterKey.onClicked: { EnterKey.onClicked: {
var buffer = B.getBuffer(inputField.text);
if (buffer !== null) { if (buffer !== null) {
changeBuffer(buffer); buffer.input(inputField.text);
} }
inputField.text = ""; inputField.text = "";

View file

@ -49,7 +49,8 @@ Dialog {
DialogHeader { DialogHeader {
id: connectHeader id: connectHeader
title: "Connect" title: "SSL Verification"
acceptText: "Connect"
cancelText: "Disconnect" cancelText: "Disconnect"
width: sslVerifyFlickable.width width: sslVerifyFlickable.width
} }

View file

@ -6,28 +6,11 @@ import "../js/utils.js" as U
SilicaListView { SilicaListView {
id: textList id: textList
function add(datetime, str) {
var snap = false;
if (textList.atYBeginning) {
snap = true;
}
// The top is the latest message on the bottom
textListModel.insert(0, { "time": datetime.format('HH:mm:ss'), "str": str });
if (snap) {
textList.positionViewAtBeginning();
}
}
function colorTime(time) { function colorTime(time) {
return U.colored(Theme.secondaryHighlightColor, return U.colored(Theme.secondaryHighlightColor,
time); time);
} }
model: ListModel { id: textListModel }
verticalLayoutDirection: ListView.BottomToTop verticalLayoutDirection: ListView.BottomToTop
delegate: ListItem { delegate: ListItem {
@ -36,7 +19,7 @@ SilicaListView {
Label { Label {
id: messageLabel id: messageLabel
text: colorTime(time) + " " + U.escapeStyled(str) text: colorTime(time) + " " + U.bold(U.escapeStyled(prefix)) + " " + U.escapeStyled(str)
wrapMode: Text.WrapAtWordBoundaryOrAnywhere wrapMode: Text.WrapAtWordBoundaryOrAnywhere
color: Theme.highlightColor color: Theme.highlightColor