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/pages/BufferView.qml \
qml/js/config.js \
qml/pages/BufferList.qml
qml/pages/BufferList.qml \
qml/js/weechatcolors.js
HEADERS += \
src/relayconnection.h \

View file

@ -16,19 +16,28 @@
.import "moment.js" as M
.import "debug.js" as D
var _textListComponent = Qt.createComponent('../pages/TextListComponent.qml');
function Buffer(pointer, number, name, title) {
this.pointer = pointer;
this.number = number;
this.name = name;
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
this.add = function(moment, str) {
this.textList.add(moment, str);
this.add = function(moment, prefix, 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
var _buffersList = [];
// Page that will own all of our textlistcomponents
// Page that will own all of our textlistmodels
var _parentPage = null;
@ -129,7 +138,7 @@ function lineAdded(data) {
var buffer = data.buffer;
var date = M.moment(data.date);
_buffers[buffer].add(date, data.message);
_buffers[buffer].add(date, data.prefix, data.message);
}
function _sortBuffersList() {

View file

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

View file

@ -17,8 +17,6 @@
var _pendingEvents = {};
function handleEvent(id, data) {
//D.d("Handling " + id);
//D.d(JSON.stringify(_pendingEvents));
if (id in _pendingEvents) {
var c = _pendingEvents[id];
c.callback(data);
@ -44,8 +42,6 @@ function command(command, callback) {
if (read_write) {
var id = UID.get();
command = "(" + id + ") " + command;
//D.d("Adding handler for " + id);
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
.pragma library
// Escape strings for Text.StyledText
function escapeStyled(string) {
string = string.replace('&', '&');
@ -11,3 +19,8 @@ function escapeStyled(string) {
function colored(color, string) {
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
DialogHeader {
title: "Save"
title: "Add connection"
acceptText: "Save"
cancelText: "Cancel"
}
TextField {

View file

@ -12,6 +12,8 @@ import "../js/buffers.js" as B
Page {
id: bufferListPage
property BufferView bufferViewPage : null;
onVisibleChanged: bufferList.updateList();
SilicaListView {
@ -20,10 +22,13 @@ Page {
anchors.fill: parent
function updateList() {
bufferListModel.clear();
var buffers = B.getBuffersByNumber();
for (var i = 0; i < buffers.length; ++i) {
bufferListModel.append({
pointer: buffers[i].pointer,
number: buffers[i].number,
name: buffers[i].name
});
@ -85,7 +90,9 @@ Page {
}
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/connection.js" as C
import "../js/moment.js" as M
import "../js/buffers.js" as B
Page {
id: bufferViewPage
@ -14,6 +12,7 @@ Page {
property string pointer: "";
property int number: 0;
property string name: "";
property var buffer: null;
function setTitle(str) {
topic.title = str;
@ -27,20 +26,12 @@ Page {
isConnected = false;
}
function changeBuffer(buffer) {
var textList = buffer.textList;
// Replace current list with new list
textListItem = textList;
textListItem.parent = mainFlickable;
// 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;
function changeBuffer(newBuffer) {
// Replace current list model with new list
D.c('Changing buffer to ' + newBuffer.name);
buffer = newBuffer;
topic.title = newBuffer.title;
textList.model = newBuffer.textList;
}
SilicaFlickable {
@ -53,8 +44,13 @@ Page {
anchors.top: parent.top
}
Item {
id: textListItem
TextListComponent {
id: textList
anchors.top: topic.bottom
anchors.bottom: inputRow.top
width: parent.width
clip: true
}
Row {
@ -71,11 +67,10 @@ Page {
placeholderText: "Type here"
EnterKey.enabled: text.length > 0
//EnterKey.iconSource: "image://theme/icon-m-send"
EnterKey.iconSource: "image://theme/icon-m-enter-accept"
EnterKey.onClicked: {
var buffer = B.getBuffer(inputField.text);
if (buffer !== null) {
changeBuffer(buffer);
buffer.input(inputField.text);
}
inputField.text = "";

View file

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

View file

@ -6,28 +6,11 @@ import "../js/utils.js" as U
SilicaListView {
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) {
return U.colored(Theme.secondaryHighlightColor,
time);
}
model: ListModel { id: textListModel }
verticalLayoutDirection: ListView.BottomToTop
delegate: ListItem {
@ -36,7 +19,7 @@ SilicaListView {
Label {
id: messageLabel
text: colorTime(time) + " " + U.escapeStyled(str)
text: colorTime(time) + " " + U.bold(U.escapeStyled(prefix)) + " " + U.escapeStyled(str)
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
color: Theme.highlightColor