diff --git a/go/ui/messagemodel.go b/go/ui/messagemodel.go new file mode 100644 index 00000000..5d0735d1 --- /dev/null +++ b/go/ui/messagemodel.go @@ -0,0 +1,214 @@ +package ui + +import ( + "cwtch.im/cwtch/model" + "cwtch.im/ui/go/the" + "git.openprivacy.ca/openprivacy/log" + "github.com/therecipe/qt/core" + "reflect" + "strings" +) + +type MessageModel struct { + core.QAbstractTableModel + + handle string + //_ string `property:"handle,auto"` + _ func(string) `signal:"setHandle,auto"` + + _ map[int]*core.QByteArray `property:"roles"` + _ func() `constructor:"init"` + + _ func(int) `signal:"addMessage,auto"` + _ func(string) `signal:"createLocalFormEntry,auto"` + _ func() `signal:"requestEIR,auto"` // request this.EndInsertRecord() on gui thread + + _ func(string) string `slot:"getNick,auto"` + _ func(string) string `slot:"getImage,auto"` +} + +type MessageWrapper struct { + model.Message + core.QObject + + Timestamp int64 + PeerID string + Acknowledged bool + RawMessage string + Error string + _ bool `property:"ackd"` +} + +func (this *MessageModel) Handle() string{ + return this.handle +} + +func (this *MessageModel) setHandle(handle string) { + this.handle = handle +} + + +func (this *MessageModel) init() { + //mdt := reflect.TypeOf([]model.Message{}).Elem() + mdt := reflect.TypeOf([]MessageWrapper{}).Elem() + roles := make(map[int]*core.QByteArray) + for i := 0; i < mdt.NumField(); i++ { + roles[int(core.Qt__UserRole) + 1 + i] = core.NewQByteArray2(mdt.Field(i).Name, -1) + } + roles[int(core.Qt__DisplayRole)] = core.NewQByteArray2("display", -1) + this.SetRoles(roles) + + this.ConnectData(this.data) + this.ConnectRowCount(this.rowCount) + this.ConnectColumnCount(this.columnCount) + this.ConnectHeaderData(this.headerData) + this.ConnectRoleNames(this.roleNames) +} + +func (this *MessageModel) roleNames() map[int]*core.QByteArray { + return this.Roles() +} + +func (this *MessageModel) isGroup() bool { + return len(this.Handle()) == 32 +} + +func (this *MessageModel) getNick(handle string) string { + return GetNick(handle) +} + +func (this *MessageModel) getImage(handle string) string { + return GetProfilePic(handle) +} + +func (this *MessageModel) num() int { + if this.Handle() == "" || the.Peer == nil { + log.Debugf("num: early returning 0") + return 0 + } + + if this.isGroup() { + group := the.Peer.GetGroup(this.Handle()) + if group != nil { + return len(group.Timeline.Messages) + len(group.UnacknowledgedMessages) + } + } else { + contact := the.Peer.GetContact(this.Handle()) + if contact != nil { + log.Debugf("num: returning %v", len(contact.Timeline.Messages)) + return len(contact.Timeline.Messages) + } + } + + log.Warnf("group/contact was nil, returning 0") + return 0 +} + +func (this *MessageModel) getMessage(idx int) *MessageWrapper { + log.Infof("MessageModel.getMessage(%v)", idx) + + var modelmsg model.Message + + if this.isGroup() { + group := the.Peer.GetGroup(this.Handle()) + if idx >= len(group.Timeline.Messages) { + modelmsg = group.UnacknowledgedMessages[idx - len(group.Timeline.Messages)] + } else { + modelmsg = group.Timeline.Messages[idx] + } + } else { + contact := the.Peer.GetContact(this.Handle()) + if this.Handle() == "" || the.Peer == nil || contact == nil { + modelmsg = model.Message{Message:"oops test hi uhhhhh :/"} + } else if idx >= len(contact.Timeline.Messages) { + log.Errorf("this shouldnt happen") + //modelmsg = contact.UnacknowledgedMessages[idx-len(contact.Timeline.Messages)] + } else { + modelmsg = contact.Timeline.Messages[idx] + } + } + + return &MessageWrapper { + Message: modelmsg, + Timestamp: modelmsg.Timestamp.Unix(), + RawMessage: modelmsg.Message, + PeerID: modelmsg.PeerID, + Error: modelmsg.Error, + Acknowledged: modelmsg.Acknowledged, + } +} + +func (this *MessageModel) data(index *core.QModelIndex, role int) *core.QVariant { + log.Infof("MessageModel.data(%v, %v)", index.Row(), role) + + if !index.IsValid() { + return core.NewQVariant() + } + if index.Row() >= this.num() { + return core.NewQVariant() + } + + if role == int(core.Qt__DisplayRole) { + role = index.Column() + int(core.Qt__UserRole) + 1 + } + + // modelData-element [role]-field value (aka the data ~_~) + mderfv := reflect.ValueOf(*this.getMessage(index.Row())).Field(role - int(core.Qt__UserRole) - 1) + typeStr := reflect.TypeOf([]MessageWrapper{}).Elem().Field(role - int(core.Qt__UserRole) - 1).Type.String() + if typeStr == "string" { + return core.NewQVariant1(mderfv.String()) + } else if strings.HasPrefix(typeStr, "int") { + return core.NewQVariant1(mderfv.Int()) + } else if strings.HasPrefix(typeStr, "float") { + return core.NewQVariant1(mderfv.Float()) + } else if typeStr == "bool" { + return core.NewQVariant1(mderfv.Bool()) + } + + return core.NewQVariant1("unknown type " + typeStr) +} + +func (this *MessageModel) headerData(section int, orientation core.Qt__Orientation, role int) *core.QVariant { + if role != int(core.Qt__DisplayRole) || orientation == core.Qt__Vertical { + return this.HeaderDataDefault(section, orientation, role) + } + + mdt := reflect.TypeOf([]model.Message{}).Elem() + return core.NewQVariant12(mdt.Field(section).Name) +} + +func (this *MessageModel) rowCount(parent *core.QModelIndex) int { + return this.num() +} + +func (this *MessageModel) columnCount(parent *core.QModelIndex) int { + return reflect.TypeOf(MessageWrapper{}).NumField() +} + +func (this *MessageModel) addMessage(idx int) { + log.Debugf("MessageModel.addMessage() ZOOP ZOOP %v", this.handle) + this.BeginInsertRows(core.NewQModelIndex(), idx, idx)//this.num(), this.num()) + //this.modelData = append(this.modelData, *fe) + //this.RequestEIR() +} + +// perform this.EndInsertRows() on the gui thread +func (this *MessageModel) requestEIR() { + log.Debugf("MessageModel.requestEIR() ZEEP ZEEP %v", this.handle) + this.EndInsertRows() +} + + +func (this *MessageModel) createLocalFormEntry(name string) { + go this.createLocalFormEntry_thread(name) +} + +func (this *MessageModel) createLocalFormEntry_thread(name string) { + log.Debugf("nyi #9779729343959699492726648294050382") + /* + fe := &model.Message{ + Message: "hi!", + } + this.addMessage(fe) + */ +} \ No newline at end of file