peony/libpeony-qt/mount-operation.cpp

212 lines
7.3 KiB
C++

/*
* Peony-Qt's Library
*
* Copyright (C) 2020, KylinSoft Co., Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library. If not, see <https://www.gnu.org/licenses/>.
*
* Authors: Yue Lan <lanyue@kylinos.cn>
*
*/
#include "mount-operation.h"
//#include "connect-server-dialog.h"
#include "connect-to-server-dialog.h"
#include "gerror-wrapper.h"
#include <QMessageBox>
#include <QPushButton>
#include <QUrl>
#include <QLineEdit>
#include <QDebug>
using namespace Peony;
MountOperation::MountOperation(QString uri, QObject *parent) : QObject(parent)
{
m_volume = g_file_new_for_uri(uri.toUtf8().constData());
m_op = g_mount_operation_new();
m_cancellable = g_cancellable_new();
}
MountOperation::~MountOperation()
{
disconnect();
//g_object_disconnect (G_OBJECT (m_op), "any_signal::signal_name", nullptr);
g_signal_handlers_disconnect_by_func(m_op, (void *)G_CALLBACK(ask_password_cb), nullptr);
g_signal_handlers_disconnect_by_func(m_op, (void *)G_CALLBACK(ask_question_cb), nullptr);
g_signal_handlers_disconnect_by_func(m_op, (void *)G_CALLBACK(aborted_cb), nullptr);
g_object_unref(m_volume);
g_object_unref(m_op);
g_object_unref(m_cancellable);
//g_list_free_full(m_errs, GDestroyNotify(g_error_free));
m_dlg->deleteLater();
}
void MountOperation::cancel()
{
g_cancellable_cancel(m_cancellable);
g_object_unref(m_cancellable);
m_cancellable = g_cancellable_new();
Q_EMIT cancelled();
if (m_auto_delete)
deleteLater();
}
void MountOperation::start()
{
gchar* urit = g_file_get_uri(m_volume);
QUrl uri = QUrl(urit);
if (uri.scheme() != "mtp") {
ConnectServerLogin* dlg = new ConnectServerLogin(urit);
m_dlg = dlg;
//block ui
auto code = dlg->exec();
if (code == QDialog::Accepted) {
g_mount_operation_set_username(m_op, dlg->user().toUtf8().constData());
g_mount_operation_set_password(m_op, dlg->password().toUtf8().constData());
g_mount_operation_set_domain(m_op, dlg->domain().toUtf8().constData());
g_mount_operation_set_anonymous(m_op, dlg->anonymous());
//TODO: when FileEnumerator::prepare(), trying mount volume without password dialog first.
g_mount_operation_set_password_save(m_op,/* dlg->savePassword()? G_PASSWORD_SAVE_FOR_SESSION:*/ G_PASSWORD_SAVE_NEVER);
}
if (code == QDialog::Rejected) {
cancel();
QMessageBox msg;
msg.setText(tr("Operation Cancelled"));
msg.exec();
return;
}
}
g_file_mount_enclosing_volume(m_volume, G_MOUNT_MOUNT_NONE, m_op, m_cancellable, GAsyncReadyCallback(mount_enclosing_volume_callback), this);
g_signal_connect (m_op, "ask-question", G_CALLBACK(ask_question_cb), this);
g_signal_connect (m_op, "ask-password", G_CALLBACK (ask_password_cb), this);
g_signal_connect (m_op, "aborted", G_CALLBACK (aborted_cb), this);
if (nullptr != urit) g_free(urit);
}
#include "global-settings.h"
GAsyncReadyCallback MountOperation::mount_enclosing_volume_callback(GFile *volume,
GAsyncResult *res,
MountOperation *p_this)
{
GError *err = nullptr;
g_file_mount_enclosing_volume_finish (volume, res, &err);
if (err) {
qDebug()<<err->code<<err->message<<err->domain;
auto errWarpper = GErrorWrapper::wrapFrom(err);
p_this->finished(errWarpper);
} else{
QUrl url = QUrl(g_file_get_uri(volume));
p_this->m_dlg->syncRemoteServer(url);
p_this->finished(nullptr);
}
if (p_this->m_auto_delete) {
p_this->disconnect();
p_this->deleteLater();
}
return nullptr;
}
void MountOperation::ask_question_cb(GMountOperation *op,
char *message, char **choices,
MountOperation *p_this)
{
qDebug()<<"ask question cb:"<<message;
Q_UNUSED(p_this);
QMessageBox *msg_box = new QMessageBox;
msg_box->setText(message);
char **choice = choices;
int i = 0;
while (*choice) {
qDebug()<<*choice;
QPushButton *button = msg_box->addButton(QString(*choice), QMessageBox::ActionRole);
connect(button, &QPushButton::clicked, [=]() {
g_mount_operation_set_choice(op, i);
});
*choice++;
i++;
}
//block ui
msg_box->exec();
msg_box->deleteLater();
qDebug()<<"msg_box done";
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
}
void MountOperation::ask_password_cb(GMountOperation *op,
const char *message,
const char *default_user,
const char *default_domain,
GAskPasswordFlags flags,
MountOperation *p_this)
{
Q_UNUSED(message);
Q_UNUSED(default_user);
Q_UNUSED(default_domain);
Q_UNUSED(flags);
Q_UNUSED(p_this);
//block ui
if (p_this->m_dlg->anonymous()) {
// try login anonymous once, if not successed, ask password.
p_this->m_dlg->m_usr_btn_usr->click();
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
return;
} else {
// try get password and login once, if not successed, show message and
// require input password again.
if (!p_this->m_dlg->password().isEmpty()) {
//p_this->m_dlg->m_reg_usr_passwd_editor->setText(nullptr);/* 去掉,因为记住密码时需要保存用户名密码 */
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
return;
} else {
QMessageBox::information(0, 0, message);
auto code = p_this->m_dlg->exec();
auto dlg = p_this->m_dlg;
if (code == QDialog::Accepted) {
g_mount_operation_set_username(op, dlg->user().toUtf8().constData());
g_mount_operation_set_password(op, dlg->password().toUtf8().constData());
g_mount_operation_set_domain(op, dlg->domain().toUtf8().constData());
g_mount_operation_set_anonymous(op, dlg->anonymous());
g_mount_operation_set_password_save(op, /*dlg->savePassword()? G_PASSWORD_SAVE_FOR_SESSION: */G_PASSWORD_SAVE_NEVER);
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
return;
}
if (code == QDialog::Rejected) {
g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
return;
}
}
}
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
}
void MountOperation::aborted_cb(GMountOperation *op,
MountOperation *p_this)
{
g_mount_operation_reply(op, G_MOUNT_OPERATION_ABORTED);
p_this->disconnect();
p_this->deleteLater();
}