forked from Silverfish/proton-bridge
186 lines
4.9 KiB
Go
186 lines
4.9 KiB
Go
// Copyright (c) 2021 Proton Technologies AG
|
|
|
|
//
|
|
// This file is part of ProtonMail Bridge.
|
|
//
|
|
// ProtonMail Bridge 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 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// ProtonMail Bridge 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 ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
// +build build_qt
|
|
|
|
package qtie
|
|
|
|
import (
|
|
qtcommon "github.com/ProtonMail/proton-bridge/internal/frontend/qt-common"
|
|
"github.com/ProtonMail/proton-bridge/internal/transfer"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/therecipe/qt/core"
|
|
)
|
|
|
|
// MboxList is an interface between QML and targets for given rule.
|
|
type MboxList struct {
|
|
core.QAbstractListModel
|
|
|
|
containsFolders bool // Provides only folders if true. On the other hand provides only labels if false
|
|
transfer *transfer.Transfer
|
|
rule *transfer.Rule
|
|
log *logrus.Entry
|
|
|
|
_ int `property:"selectedIndex"`
|
|
|
|
_ func() `constructor:"init"`
|
|
}
|
|
|
|
func init() {
|
|
// This is needed so the type exists in QML files.
|
|
MboxList_QRegisterMetaType()
|
|
}
|
|
|
|
func newMboxList(t *TransferRules, rule *transfer.Rule, containsFolders bool) *MboxList {
|
|
m := NewMboxList(t)
|
|
m.BeginResetModel()
|
|
m.transfer = t.transfer
|
|
m.rule = rule
|
|
m.containsFolders = containsFolders
|
|
m.log = log.
|
|
WithField("rule", m.rule.SourceMailbox.Hash()).
|
|
WithField("folders", m.containsFolders)
|
|
m.updateSelectedIndex()
|
|
m.EndResetModel()
|
|
return m
|
|
}
|
|
|
|
func (m *MboxList) init() {
|
|
m.ConnectRowCount(m.rowCount)
|
|
m.ConnectRoleNames(m.roleNames)
|
|
m.ConnectData(m.data)
|
|
}
|
|
|
|
func (m *MboxList) rowCount(index *core.QModelIndex) int {
|
|
return len(m.targetMailboxes())
|
|
}
|
|
|
|
func (m *MboxList) roleNames() map[int]*core.QByteArray {
|
|
return map[int]*core.QByteArray{
|
|
MboxIsActive: qtcommon.NewQByteArrayFromString("isActive"),
|
|
MboxID: qtcommon.NewQByteArrayFromString("mboxID"),
|
|
MboxName: qtcommon.NewQByteArrayFromString("name"),
|
|
MboxType: qtcommon.NewQByteArrayFromString("type"),
|
|
MboxColor: qtcommon.NewQByteArrayFromString("iconColor"),
|
|
}
|
|
}
|
|
|
|
func (m *MboxList) data(index *core.QModelIndex, role int) *core.QVariant {
|
|
allTargets := m.targetMailboxes()
|
|
|
|
i := index.Row()
|
|
log := m.log.WithField("row", i).WithField("role", role)
|
|
log.Trace("Mbox data")
|
|
|
|
if i >= len(allTargets) {
|
|
log.Warning("Invalid index")
|
|
return core.NewQVariant()
|
|
}
|
|
|
|
if m.transfer == nil {
|
|
log.Warning("Requested mbox list data before transfer is connected")
|
|
return qtcommon.NewQVariantString("")
|
|
}
|
|
|
|
mbox := allTargets[i]
|
|
|
|
switch role {
|
|
|
|
case MboxIsActive:
|
|
for _, selectedMailbox := range m.rule.TargetMailboxes {
|
|
if selectedMailbox.Hash() == mbox.Hash() {
|
|
return qtcommon.NewQVariantBool(true)
|
|
}
|
|
}
|
|
return qtcommon.NewQVariantBool(false)
|
|
|
|
case MboxID:
|
|
return qtcommon.NewQVariantString(mbox.Hash())
|
|
|
|
case MboxName, int(core.Qt__DisplayRole):
|
|
return qtcommon.NewQVariantString(mbox.Name)
|
|
|
|
case MboxType:
|
|
t := "label"
|
|
if mbox.IsExclusive {
|
|
t = "folder"
|
|
}
|
|
return qtcommon.NewQVariantString(t)
|
|
|
|
case MboxColor:
|
|
return qtcommon.NewQVariantString(mbox.Color)
|
|
|
|
default:
|
|
log.Error("Requested mbox list data with unknown role")
|
|
return qtcommon.NewQVariantString("")
|
|
}
|
|
}
|
|
|
|
func (m *MboxList) targetMailboxes() []transfer.Mailbox {
|
|
if m.transfer == nil {
|
|
m.log.Warning("Requested target mailboxes before transfer is connected")
|
|
}
|
|
|
|
mailboxes, err := m.transfer.TargetMailboxes()
|
|
if err != nil {
|
|
m.log.WithError(err).Error("Unable to get target mailboxes")
|
|
}
|
|
|
|
return m.filter(mailboxes)
|
|
}
|
|
|
|
func (m *MboxList) filter(mailboxes []transfer.Mailbox) (filtered []transfer.Mailbox) {
|
|
for _, mailbox := range mailboxes {
|
|
if mailbox.IsExclusive == m.containsFolders {
|
|
filtered = append(filtered, mailbox)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (m *MboxList) itemsChanged(rule *transfer.Rule) {
|
|
m.rule = rule
|
|
allTargets := m.targetMailboxes()
|
|
|
|
m.log.WithField("count", len(allTargets)).Trace("Mbox items changed")
|
|
|
|
m.updateSelectedIndex()
|
|
|
|
// NOTE: Be careful with indices: If they are invalid the DataChanged
|
|
// signal will not be sent to QML e.g. `end == rowCount - 1`
|
|
if len(allTargets) > 0 {
|
|
begin := m.Index(0, 0, core.NewQModelIndex())
|
|
end := m.Index(len(allTargets)-1, 0, core.NewQModelIndex())
|
|
changedRoles := []int{MboxIsActive}
|
|
m.DataChanged(begin, end, changedRoles)
|
|
}
|
|
}
|
|
|
|
func (m *MboxList) updateSelectedIndex() {
|
|
allTargets := m.targetMailboxes()
|
|
for index, targetMailbox := range allTargets {
|
|
for _, selectedTarget := range m.rule.TargetMailboxes {
|
|
if targetMailbox.Hash() == selectedTarget.Hash() {
|
|
m.SetSelectedIndex(index)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
m.SetSelectedIndex(-1)
|
|
}
|