mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 12:46:46 +00:00
Import/Export GUI
This commit is contained in:
committed by
Michal Horejsek
parent
1c10cc5065
commit
7e5e3d3dd4
@ -65,11 +65,11 @@ type FrontendQt struct {
|
||||
programVersion string // Program version
|
||||
buildVersion string // Program build version
|
||||
|
||||
PMStructure *FolderStructure // Providing data for account labels and folders for ProtonMail account
|
||||
ExternalStructure *FolderStructure // Providing data for account labels and folders for MBOX, EML or external IMAP account
|
||||
ErrorList *ErrorListModel // Providing data for error reporting
|
||||
TransferRules *TransferRules
|
||||
ErrorList *ErrorListModel // Providing data for error reporting
|
||||
|
||||
transfer *transfer.Transfer
|
||||
progress *transfer.Progress
|
||||
|
||||
notifyHasNoKeychain bool
|
||||
}
|
||||
@ -103,102 +103,99 @@ func New(
|
||||
}
|
||||
|
||||
// IsAppRestarting for Import-Export is always false i.e never restarts
|
||||
func (s *FrontendQt) IsAppRestarting() bool {
|
||||
func (f *FrontendQt) IsAppRestarting() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Loop function for Import-Export interface. It runs QtExecute in main thread
|
||||
// with no additional function.
|
||||
func (s *FrontendQt) Loop(setupError error) (err error) {
|
||||
func (f *FrontendQt) Loop(setupError error) (err error) {
|
||||
if setupError != nil {
|
||||
s.notifyHasNoKeychain = true
|
||||
f.notifyHasNoKeychain = true
|
||||
}
|
||||
go func() {
|
||||
defer s.panicHandler.HandlePanic()
|
||||
s.watchEvents()
|
||||
defer f.panicHandler.HandlePanic()
|
||||
f.watchEvents()
|
||||
}()
|
||||
err = s.QtExecute(func(s *FrontendQt) error { return nil })
|
||||
err = f.QtExecute(func(f *FrontendQt) error { return nil })
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *FrontendQt) watchEvents() {
|
||||
internetOffCh := qtcommon.MakeAndRegisterEvent(s.eventListener, events.InternetOffEvent)
|
||||
internetOnCh := qtcommon.MakeAndRegisterEvent(s.eventListener, events.InternetOnEvent)
|
||||
restartBridgeCh := qtcommon.MakeAndRegisterEvent(s.eventListener, events.RestartBridgeEvent)
|
||||
addressChangedCh := qtcommon.MakeAndRegisterEvent(s.eventListener, events.AddressChangedEvent)
|
||||
addressChangedLogoutCh := qtcommon.MakeAndRegisterEvent(s.eventListener, events.AddressChangedLogoutEvent)
|
||||
logoutCh := qtcommon.MakeAndRegisterEvent(s.eventListener, events.LogoutEvent)
|
||||
updateApplicationCh := qtcommon.MakeAndRegisterEvent(s.eventListener, events.UpgradeApplicationEvent)
|
||||
newUserCh := qtcommon.MakeAndRegisterEvent(s.eventListener, events.UserRefreshEvent)
|
||||
func (f *FrontendQt) watchEvents() {
|
||||
internetOffCh := qtcommon.MakeAndRegisterEvent(f.eventListener, events.InternetOffEvent)
|
||||
internetOnCh := qtcommon.MakeAndRegisterEvent(f.eventListener, events.InternetOnEvent)
|
||||
restartBridgeCh := qtcommon.MakeAndRegisterEvent(f.eventListener, events.RestartBridgeEvent)
|
||||
addressChangedCh := qtcommon.MakeAndRegisterEvent(f.eventListener, events.AddressChangedEvent)
|
||||
addressChangedLogoutCh := qtcommon.MakeAndRegisterEvent(f.eventListener, events.AddressChangedLogoutEvent)
|
||||
logoutCh := qtcommon.MakeAndRegisterEvent(f.eventListener, events.LogoutEvent)
|
||||
updateApplicationCh := qtcommon.MakeAndRegisterEvent(f.eventListener, events.UpgradeApplicationEvent)
|
||||
newUserCh := qtcommon.MakeAndRegisterEvent(f.eventListener, events.UserRefreshEvent)
|
||||
for {
|
||||
select {
|
||||
case <-internetOffCh:
|
||||
s.Qml.SetConnectionStatus(false)
|
||||
f.Qml.SetConnectionStatus(false)
|
||||
case <-internetOnCh:
|
||||
s.Qml.SetConnectionStatus(true)
|
||||
f.Qml.SetConnectionStatus(true)
|
||||
case <-restartBridgeCh:
|
||||
s.Qml.SetIsRestarting(true)
|
||||
s.App.Quit()
|
||||
f.Qml.SetIsRestarting(true)
|
||||
f.App.Quit()
|
||||
case address := <-addressChangedCh:
|
||||
s.Qml.NotifyAddressChanged(address)
|
||||
f.Qml.NotifyAddressChanged(address)
|
||||
case address := <-addressChangedLogoutCh:
|
||||
s.Qml.NotifyAddressChangedLogout(address)
|
||||
f.Qml.NotifyAddressChangedLogout(address)
|
||||
case userID := <-logoutCh:
|
||||
user, err := s.ie.GetUser(userID)
|
||||
user, err := f.ie.GetUser(userID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s.Qml.NotifyLogout(user.Username())
|
||||
f.Qml.NotifyLogout(user.Username())
|
||||
case <-updateApplicationCh:
|
||||
s.Qml.ProcessFinished()
|
||||
s.Qml.NotifyUpdate()
|
||||
f.Qml.ProcessFinished()
|
||||
f.Qml.NotifyUpdate()
|
||||
case <-newUserCh:
|
||||
s.Qml.LoadAccounts()
|
||||
f.Qml.LoadAccounts()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FrontendQt) qtSetupQmlAndStructures() {
|
||||
s.App = widgets.NewQApplication(len(os.Args), os.Args)
|
||||
func (f *FrontendQt) qtSetupQmlAndStructures() {
|
||||
f.App = widgets.NewQApplication(len(os.Args), os.Args)
|
||||
// view
|
||||
s.View = qml.NewQQmlApplicationEngine(s.App)
|
||||
f.View = qml.NewQQmlApplicationEngine(f.App)
|
||||
// Add Go-QML Import-Export
|
||||
s.Qml = NewGoQMLInterface(nil)
|
||||
s.Qml.SetFrontend(s) // provides access
|
||||
s.View.RootContext().SetContextProperty("go", s.Qml)
|
||||
f.Qml = NewGoQMLInterface(nil)
|
||||
f.Qml.SetFrontend(f) // provides access
|
||||
f.View.RootContext().SetContextProperty("go", f.Qml)
|
||||
|
||||
// Add AccountsModel
|
||||
s.Accounts.SetupAccounts(s.Qml, s.ie)
|
||||
s.View.RootContext().SetContextProperty("accountsModel", s.Accounts.Model)
|
||||
f.Accounts.SetupAccounts(f.Qml, f.ie)
|
||||
f.View.RootContext().SetContextProperty("accountsModel", f.Accounts.Model)
|
||||
|
||||
// Add ProtonMail FolderStructure
|
||||
s.PMStructure = NewFolderStructure(nil)
|
||||
s.View.RootContext().SetContextProperty("structurePM", s.PMStructure)
|
||||
|
||||
// Add external FolderStructure
|
||||
s.ExternalStructure = NewFolderStructure(nil)
|
||||
s.View.RootContext().SetContextProperty("structureExternal", s.ExternalStructure)
|
||||
// Add TransferRules structure
|
||||
f.TransferRules = NewTransferRules(nil)
|
||||
f.View.RootContext().SetContextProperty("transferRules", f.TransferRules)
|
||||
|
||||
// Add error list modal
|
||||
s.ErrorList = NewErrorListModel(nil)
|
||||
s.View.RootContext().SetContextProperty("errorList", s.ErrorList)
|
||||
s.Qml.ConnectLoadImportReports(s.ErrorList.load)
|
||||
f.ErrorList = NewErrorListModel(nil)
|
||||
f.View.RootContext().SetContextProperty("errorList", f.ErrorList)
|
||||
f.Qml.ConnectLoadImportReports(f.ErrorList.load)
|
||||
|
||||
// Import path and load QML files
|
||||
s.View.AddImportPath("qrc:///")
|
||||
s.View.Load(core.NewQUrl3("qrc:/uiie.qml", 0))
|
||||
f.View.AddImportPath("qrc:///")
|
||||
f.View.Load(core.NewQUrl3("qrc:/uiie.qml", 0))
|
||||
|
||||
// TODO set the first start flag
|
||||
log.Error("Get FirstStart: Not implemented")
|
||||
//if prefs.Get(prefs.FirstStart) == "true" {
|
||||
if false {
|
||||
s.Qml.SetIsFirstStart(true)
|
||||
f.Qml.SetIsFirstStart(true)
|
||||
} else {
|
||||
s.Qml.SetIsFirstStart(false)
|
||||
f.Qml.SetIsFirstStart(false)
|
||||
}
|
||||
|
||||
// Notify user about error during initialization.
|
||||
if s.notifyHasNoKeychain {
|
||||
s.Qml.NotifyHasNoKeychain()
|
||||
if f.notifyHasNoKeychain {
|
||||
f.Qml.NotifyHasNoKeychain()
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,18 +204,18 @@ func (s *FrontendQt) qtSetupQmlAndStructures() {
|
||||
// It is needed to have just one Qt application per program (at least per same
|
||||
// thread). This functions reads the main user interface defined in QML files.
|
||||
// The files are appended to library by Qt-QRC.
|
||||
func (s *FrontendQt) QtExecute(Procedure func(*FrontendQt) error) error {
|
||||
qtcommon.QtSetupCoreAndControls(s.programName, s.programVersion)
|
||||
s.qtSetupQmlAndStructures()
|
||||
func (f *FrontendQt) QtExecute(Procedure func(*FrontendQt) error) error {
|
||||
qtcommon.QtSetupCoreAndControls(f.programName, f.programVersion)
|
||||
f.qtSetupQmlAndStructures()
|
||||
// Check QML is loaded properly
|
||||
if len(s.View.RootObjects()) == 0 {
|
||||
if len(f.View.RootObjects()) == 0 {
|
||||
//return errors.New(errors.ErrQApplication, "QML not loaded properly")
|
||||
return errors.New("QML not loaded properly")
|
||||
}
|
||||
// Obtain main window (need for invoke method)
|
||||
s.MainWin = s.View.RootObjects()[0]
|
||||
f.MainWin = f.View.RootObjects()[0]
|
||||
// Injected procedure for out-of-main-thread applications
|
||||
if err := Procedure(s); err != nil {
|
||||
if err := Procedure(f); err != nil {
|
||||
return err
|
||||
}
|
||||
// Loop
|
||||
@ -234,63 +231,55 @@ func (s *FrontendQt) QtExecute(Procedure func(*FrontendQt) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FrontendQt) openLogs() {
|
||||
go open.Run(s.config.GetLogDir())
|
||||
func (f *FrontendQt) openLogs() {
|
||||
go open.Run(f.config.GetLogDir())
|
||||
}
|
||||
|
||||
func (s *FrontendQt) openReport() {
|
||||
go open.Run(s.Qml.ImportLogFileName())
|
||||
func (f *FrontendQt) openReport() {
|
||||
go open.Run(f.Qml.ImportLogFileName())
|
||||
}
|
||||
|
||||
func (s *FrontendQt) openDownloadLink() {
|
||||
go open.Run(s.updates.GetDownloadLink())
|
||||
func (f *FrontendQt) openDownloadLink() {
|
||||
go open.Run(f.updates.GetDownloadLink())
|
||||
}
|
||||
|
||||
func (s *FrontendQt) sendImportReport(address, reportFile string) (isOK bool) {
|
||||
/*
|
||||
accname := "[No account logged in]"
|
||||
if s.Accounts.Count() > 0 {
|
||||
accname = s.Accounts.get(0).Account()
|
||||
}
|
||||
|
||||
basename := filepath.Base(reportFile)
|
||||
req := pmapi.ReportReq{
|
||||
OS: core.QSysInfo_ProductType(),
|
||||
OSVersion: core.QSysInfo_PrettyProductName(),
|
||||
Title: "[Import Export] Import report: " + basename,
|
||||
Description: "Sending import report file in attachment.",
|
||||
Username: accname,
|
||||
Email: address,
|
||||
}
|
||||
|
||||
report, err := os.Open(reportFile)
|
||||
if err != nil {
|
||||
log.Errorln("report file open:", err)
|
||||
isOK = false
|
||||
}
|
||||
req.AddAttachment("log", basename, report)
|
||||
|
||||
c := pmapi.NewClient(backend.APIConfig, "import_reporter")
|
||||
err = c.Report(req)
|
||||
if err != nil {
|
||||
log.Errorln("while sendReport:", err)
|
||||
isOK = false
|
||||
return
|
||||
}
|
||||
log.Infof("Report %q send successfully", basename)
|
||||
isOK = true
|
||||
*/
|
||||
return false
|
||||
}
|
||||
|
||||
// sendBug is almost idetical to bridge
|
||||
func (s *FrontendQt) sendBug(description, emailClient, address string) (isOK bool) {
|
||||
isOK = true
|
||||
// sendImportReport sends an anonymized import or export report file to our customer support
|
||||
func (f *FrontendQt) sendImportReport(address string) bool { // Todo_: Rename to sendReport?
|
||||
var accname = "No account logged in"
|
||||
if s.Accounts.Model.Count() > 0 {
|
||||
accname = s.Accounts.Model.Get(0).Account()
|
||||
if f.Accounts.Model.Count() > 0 {
|
||||
accname = f.Accounts.Model.Get(0).Account()
|
||||
}
|
||||
if err := s.ie.ReportBug(
|
||||
|
||||
if f.progress == nil {
|
||||
log.Errorln("Failed to send process report: Missing progress")
|
||||
return false
|
||||
}
|
||||
|
||||
report := f.progress.GenerateBugReport()
|
||||
|
||||
if err := f.ie.ReportFile(
|
||||
core.QSysInfo_ProductType(),
|
||||
core.QSysInfo_PrettyProductName(),
|
||||
accname,
|
||||
address,
|
||||
report,
|
||||
); err != nil {
|
||||
log.Errorln("Failed to send process report:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
log.Info("Report send successfully")
|
||||
return true
|
||||
}
|
||||
|
||||
// sendBug sends a bug report described by user to our customer support
|
||||
func (f *FrontendQt) sendBug(description, emailClient, address string) bool {
|
||||
var accname = "No account logged in"
|
||||
if f.Accounts.Model.Count() > 0 {
|
||||
accname = f.Accounts.Model.Get(0).Account()
|
||||
}
|
||||
|
||||
if err := f.ie.ReportBug(
|
||||
core.QSysInfo_ProductType(),
|
||||
core.QSysInfo_PrettyProductName(),
|
||||
description,
|
||||
@ -299,41 +288,43 @@ func (s *FrontendQt) sendBug(description, emailClient, address string) (isOK boo
|
||||
emailClient,
|
||||
); err != nil {
|
||||
log.Errorln("while sendBug:", err)
|
||||
isOK = false
|
||||
return false
|
||||
}
|
||||
return
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// checkInternet is almost idetical to bridge
|
||||
func (s *FrontendQt) checkInternet() {
|
||||
s.Qml.SetConnectionStatus(s.ie.CheckConnection() == nil)
|
||||
func (f *FrontendQt) checkInternet() {
|
||||
f.Qml.SetConnectionStatus(f.ie.CheckConnection() == nil)
|
||||
}
|
||||
|
||||
func (s *FrontendQt) showError(err error) {
|
||||
code := 0 // TODO err.Code()
|
||||
s.Qml.SetErrorDescription(err.Error())
|
||||
func (f *FrontendQt) showError(code int, err error) {
|
||||
f.Qml.SetErrorDescription(err.Error())
|
||||
log.WithField("code", code).Errorln(err.Error())
|
||||
s.Qml.NotifyError(code)
|
||||
f.Qml.NotifyError(code)
|
||||
}
|
||||
|
||||
func (s *FrontendQt) emitEvent(evType, msg string) {
|
||||
s.eventListener.Emit(evType, msg)
|
||||
func (f *FrontendQt) emitEvent(evType, msg string) {
|
||||
f.eventListener.Emit(evType, msg)
|
||||
}
|
||||
|
||||
func (s *FrontendQt) setProgressManager(progress *transfer.Progress) {
|
||||
s.Qml.ConnectPauseProcess(func() { progress.Pause("user") })
|
||||
s.Qml.ConnectResumeProcess(progress.Resume)
|
||||
s.Qml.ConnectCancelProcess(func(clearUnfinished bool) {
|
||||
// TODO clear unfinished
|
||||
func (f *FrontendQt) setProgressManager(progress *transfer.Progress) {
|
||||
f.progress = progress
|
||||
f.ErrorList.Progress = progress
|
||||
|
||||
f.Qml.ConnectPauseProcess(func() { progress.Pause("paused") })
|
||||
f.Qml.ConnectResumeProcess(progress.Resume)
|
||||
f.Qml.ConnectCancelProcess(func() {
|
||||
progress.Stop()
|
||||
})
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
s.Qml.DisconnectPauseProcess()
|
||||
s.Qml.DisconnectResumeProcess()
|
||||
s.Qml.DisconnectCancelProcess()
|
||||
s.Qml.SetProgress(1)
|
||||
f.Qml.DisconnectPauseProcess()
|
||||
f.Qml.DisconnectResumeProcess()
|
||||
f.Qml.DisconnectCancelProcess()
|
||||
f.Qml.SetProgress(1)
|
||||
}()
|
||||
|
||||
//TODO get log file (in old code it was here, but this is ugly place probably somewhere else)
|
||||
@ -344,119 +335,123 @@ func (s *FrontendQt) setProgressManager(progress *transfer.Progress) {
|
||||
}
|
||||
failed, imported, _, _, total := progress.GetCounts()
|
||||
if total != 0 { // udate total
|
||||
s.Qml.SetTotal(int(total))
|
||||
f.Qml.SetTotal(int(total))
|
||||
}
|
||||
s.Qml.SetProgressFails(int(failed))
|
||||
s.Qml.SetProgressDescription(progress.PauseReason()) // TODO add description when changing folders?
|
||||
f.Qml.SetProgressFails(int(failed))
|
||||
f.Qml.SetProgressDescription(progress.PauseReason()) // TODO add description when changing folders?
|
||||
if total > 0 {
|
||||
newProgress := float32(imported+failed) / float32(total)
|
||||
if newProgress >= 0 && newProgress != s.Qml.Progress() {
|
||||
s.Qml.SetProgress(newProgress)
|
||||
s.Qml.ProgressChanged(newProgress)
|
||||
if newProgress >= 0 && newProgress != f.Qml.Progress() {
|
||||
f.Qml.SetProgress(newProgress)
|
||||
f.Qml.ProgressChanged(newProgress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO fatal error?
|
||||
if err := progress.GetFatalError(); err != nil {
|
||||
f.Qml.SetProgressDescription(err.Error())
|
||||
} else {
|
||||
f.Qml.SetProgressDescription("")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// StartUpdate is identical to bridge
|
||||
func (s *FrontendQt) StartUpdate() {
|
||||
func (f *FrontendQt) StartUpdate() {
|
||||
progress := make(chan updates.Progress)
|
||||
go func() { // Update progress in QML.
|
||||
defer s.panicHandler.HandlePanic()
|
||||
defer f.panicHandler.HandlePanic()
|
||||
for current := range progress {
|
||||
s.Qml.SetProgress(current.Processed)
|
||||
s.Qml.SetProgressDescription(strconv.Itoa(current.Description))
|
||||
f.Qml.SetProgress(current.Processed)
|
||||
f.Qml.SetProgressDescription(strconv.Itoa(current.Description))
|
||||
// Error happend
|
||||
if current.Err != nil {
|
||||
log.Error("update progress: ", current.Err)
|
||||
s.Qml.UpdateFinished(true)
|
||||
f.Qml.UpdateFinished(true)
|
||||
return
|
||||
}
|
||||
// Finished everything OK.
|
||||
if current.Description >= updates.InfoQuitApp {
|
||||
s.Qml.UpdateFinished(false)
|
||||
f.Qml.UpdateFinished(false)
|
||||
time.Sleep(3 * time.Second) // Just notify.
|
||||
s.Qml.SetIsRestarting(current.Description == updates.InfoRestartApp)
|
||||
s.App.Quit()
|
||||
f.Qml.SetIsRestarting(current.Description == updates.InfoRestartApp)
|
||||
f.App.Quit()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer s.panicHandler.HandlePanic()
|
||||
s.updates.StartUpgrade(progress)
|
||||
defer f.panicHandler.HandlePanic()
|
||||
f.updates.StartUpgrade(progress)
|
||||
}()
|
||||
}
|
||||
|
||||
// isNewVersionAvailable is identical to bridge
|
||||
// return 0 when local version is fine
|
||||
// return 1 when new version is available
|
||||
func (s *FrontendQt) isNewVersionAvailable(showMessage bool) {
|
||||
func (f *FrontendQt) isNewVersionAvailable(showMessage bool) {
|
||||
go func() {
|
||||
defer s.Qml.ProcessFinished()
|
||||
isUpToDate, latestVersionInfo, err := s.updates.CheckIsUpToDate()
|
||||
defer f.Qml.ProcessFinished()
|
||||
isUpToDate, latestVersionInfo, err := f.updates.CheckIsUpToDate()
|
||||
if err != nil {
|
||||
log.Warnln("Cannot retrieve version info: ", err)
|
||||
s.checkInternet()
|
||||
f.checkInternet()
|
||||
return
|
||||
}
|
||||
s.Qml.SetConnectionStatus(true) // if we are here connection is ok
|
||||
f.Qml.SetConnectionStatus(true) // if we are here connection is ok
|
||||
if isUpToDate {
|
||||
s.Qml.SetUpdateState(StatusUpToDate)
|
||||
f.Qml.SetUpdateState(StatusUpToDate)
|
||||
if showMessage {
|
||||
s.Qml.NotifyVersionIsTheLatest()
|
||||
f.Qml.NotifyVersionIsTheLatest()
|
||||
}
|
||||
return
|
||||
}
|
||||
s.Qml.SetNewversion(latestVersionInfo.Version)
|
||||
s.Qml.SetChangelog(latestVersionInfo.ReleaseNotes)
|
||||
s.Qml.SetBugfixes(latestVersionInfo.ReleaseFixedBugs)
|
||||
s.Qml.SetLandingPage(latestVersionInfo.LandingPage)
|
||||
s.Qml.SetDownloadLink(latestVersionInfo.GetDownloadLink())
|
||||
s.Qml.SetUpdateState(StatusNewVersionAvailable)
|
||||
f.Qml.SetNewversion(latestVersionInfo.Version)
|
||||
f.Qml.SetChangelog(latestVersionInfo.ReleaseNotes)
|
||||
f.Qml.SetBugfixes(latestVersionInfo.ReleaseFixedBugs)
|
||||
f.Qml.SetLandingPage(latestVersionInfo.LandingPage)
|
||||
f.Qml.SetDownloadLink(latestVersionInfo.GetDownloadLink())
|
||||
f.Qml.SetUpdateState(StatusNewVersionAvailable)
|
||||
}()
|
||||
}
|
||||
|
||||
func (s *FrontendQt) resetSource() {
|
||||
if s.transfer != nil {
|
||||
s.transfer.ResetRules()
|
||||
if err := s.loadStructuresForImport(); err != nil {
|
||||
func (f *FrontendQt) resetSource() {
|
||||
if f.transfer != nil {
|
||||
f.transfer.ResetRules()
|
||||
if err := f.loadStructuresForImport(); err != nil {
|
||||
log.WithError(err).Error("Cannot reload structures after reseting rules.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getLocalVersionInfo is identical to bridge.
|
||||
func (s *FrontendQt) getLocalVersionInfo() {
|
||||
defer s.Qml.ProcessFinished()
|
||||
localVersion := s.updates.GetLocalVersion()
|
||||
s.Qml.SetNewversion(localVersion.Version)
|
||||
s.Qml.SetChangelog(localVersion.ReleaseNotes)
|
||||
s.Qml.SetBugfixes(localVersion.ReleaseFixedBugs)
|
||||
func (f *FrontendQt) getLocalVersionInfo() {
|
||||
defer f.Qml.ProcessFinished()
|
||||
localVersion := f.updates.GetLocalVersion()
|
||||
f.Qml.SetNewversion(localVersion.Version)
|
||||
f.Qml.SetChangelog(localVersion.ReleaseNotes)
|
||||
f.Qml.SetBugfixes(localVersion.ReleaseFixedBugs)
|
||||
}
|
||||
|
||||
// LeastUsedColor is intended to return color for creating a new inbox or label.
|
||||
func (s *FrontendQt) leastUsedColor() string {
|
||||
if s.transfer == nil {
|
||||
func (f *FrontendQt) leastUsedColor() string {
|
||||
if f.transfer == nil {
|
||||
log.Errorln("Getting least used color before transfer exist.")
|
||||
return "#7272a7"
|
||||
}
|
||||
|
||||
m, err := s.transfer.TargetMailboxes()
|
||||
m, err := f.transfer.TargetMailboxes()
|
||||
|
||||
if err != nil {
|
||||
log.Errorln("Getting least used color:", err)
|
||||
s.showError(err)
|
||||
f.showError(errUnknownError, err)
|
||||
}
|
||||
|
||||
return transfer.LeastUsedColor(m)
|
||||
}
|
||||
|
||||
// createLabelOrFolder performs an IE target mailbox creation.
|
||||
func (s *FrontendQt) createLabelOrFolder(email, name, color string, isLabel bool, sourceID string) bool {
|
||||
func (f *FrontendQt) createLabelOrFolder(email, name, color string, isLabel bool, sourceID string) bool {
|
||||
// Prepare new mailbox.
|
||||
m := transfer.Mailbox{
|
||||
Name: name,
|
||||
@ -466,32 +461,28 @@ func (s *FrontendQt) createLabelOrFolder(email, name, color string, isLabel bool
|
||||
|
||||
// Select least used color if no color given.
|
||||
if m.Color == "" {
|
||||
m.Color = s.leastUsedColor()
|
||||
m.Color = f.leastUsedColor()
|
||||
}
|
||||
|
||||
f.TransferRules.BeginResetModel()
|
||||
defer f.TransferRules.EndResetModel()
|
||||
|
||||
// Create mailbox.
|
||||
newLabel, err := s.transfer.CreateTargetMailbox(m)
|
||||
|
||||
m, err := f.transfer.CreateTargetMailbox(m)
|
||||
if err != nil {
|
||||
log.Errorln("Folder/Label creating:", err)
|
||||
s.showError(err)
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: notify UI of newly added folders/labels
|
||||
/*errc := s.PMStructure.Load(email, false)
|
||||
if errc != nil {
|
||||
s.showError(errc)
|
||||
return false
|
||||
}*/
|
||||
|
||||
if sourceID != "" {
|
||||
if isLabel {
|
||||
s.ExternalStructure.addTargetLabelID(sourceID, newLabel.ID)
|
||||
f.showError(errCreateLabelFailed, err)
|
||||
} else {
|
||||
s.ExternalStructure.setTargetFolderID(sourceID, newLabel.ID)
|
||||
f.showError(errCreateFolderFailed, err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if sourceID == "-1" {
|
||||
f.transfer.SetGlobalMailbox(&m)
|
||||
} else {
|
||||
f.TransferRules.addTargetID(sourceID, m.Hash())
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user