| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #include "core/file_utilities.h"
- #include "storage/localstorage.h"
- #include "storage/storage_account.h"
- #include "base/platform/base_platform_file_utilities.h"
- #include "platform/platform_file_utilities.h"
- #include "core/application.h"
- #include "base/unixtime.h"
- #include "ui/delayed_activation.h"
- #include "ui/chat/attach/attach_extensions.h"
- #include "main/main_session.h"
- #include "mainwindow.h"
- #include <QtWidgets/QFileDialog>
- #include <QtCore/QCoreApplication>
- #include <QtCore/QStandardPaths>
- #include <QtGui/QDesktopServices>
- bool filedialogGetSaveFile(
- QPointer<QWidget> parent,
- QString &file,
- const QString &caption,
- const QString &filter,
- const QString &initialPath) {
- QStringList files;
- QByteArray remoteContent;
- Ui::PreventDelayedActivation();
- bool result = Platform::FileDialog::Get(
- parent,
- files,
- remoteContent,
- caption,
- filter,
- FileDialog::internal::Type::WriteFile,
- initialPath);
- file = files.isEmpty() ? QString() : files.at(0);
- return result;
- }
- bool filedialogGetSaveFile(
- QString &file,
- const QString &caption,
- const QString &filter,
- const QString &initialPath) {
- return filedialogGetSaveFile(
- Core::App().getFileDialogParent(),
- file,
- caption,
- filter,
- initialPath);
- }
- QString filedialogDefaultName(
- const QString &prefix,
- const QString &extension,
- const QString &path,
- bool skipExistance,
- TimeId fileTime) {
- auto directoryPath = path;
- if (directoryPath.isEmpty()) {
- if (cDialogLastPath().isEmpty()) {
- Platform::FileDialog::InitLastPath();
- }
- directoryPath = cDialogLastPath();
- }
- QString base;
- if (fileTime) {
- const auto date = base::unixtime::parse(fileTime);
- base = prefix + date.toString("_yyyy-MM-dd_HH-mm-ss");
- } else {
- struct tm tm;
- time_t t = time(NULL);
- mylocaltime(&tm, &t);
- const auto zero = QChar('0');
- base = prefix + u"_%1-%2-%3_%4-%5-%6"_q.arg(tm.tm_year + 1900).arg(tm.tm_mon + 1, 2, 10, zero).arg(tm.tm_mday, 2, 10, zero).arg(tm.tm_hour, 2, 10, zero).arg(tm.tm_min, 2, 10, zero).arg(tm.tm_sec, 2, 10, zero);
- }
- QString name;
- if (skipExistance) {
- name = base + extension;
- } else {
- QDir directory(directoryPath);
- const auto dir = directory.absolutePath();
- const auto nameBase = (dir.endsWith('/') ? dir : (dir + '/'))
- + base;
- name = nameBase + extension;
- for (int i = 0; QFileInfo::exists(name); ++i) {
- name = nameBase + u" (%1)"_q.arg(i + 2) + extension;
- }
- }
- return name;
- }
- QString filedialogNextFilename(
- const QString &name,
- const QString &cur,
- const QString &path) {
- QDir directory(path.isEmpty() ? cDialogLastPath() : path);
- int32 extIndex = name.lastIndexOf('.');
- QString prefix = name, extension;
- if (extIndex >= 0) {
- extension = name.mid(extIndex);
- prefix = name.mid(0, extIndex);
- }
- const auto dir = directory.absolutePath();
- const auto nameBase = (dir.endsWith('/') ? dir : (dir + '/')) + prefix;
- auto result = nameBase + extension;
- for (int i = 0; result.toLower() != cur.toLower() && QFileInfo::exists(result); ++i) {
- result = nameBase + u" (%1)"_q.arg(i + 2) + extension;
- }
- return result;
- }
- namespace File {
- void OpenUrl(const QString &url) {
- crl::on_main([=] {
- Ui::PreventDelayedActivation();
- Platform::File::UnsafeOpenUrl(url);
- });
- }
- void OpenEmailLink(const QString &email) {
- crl::on_main([=] {
- Ui::PreventDelayedActivation();
- Platform::File::UnsafeOpenEmailLink(email);
- });
- }
- void OpenWith(const QString &filepath) {
- InvokeQueued(QCoreApplication::instance(), [=] {
- if (!Platform::File::UnsafeShowOpenWithDropdown(filepath)) {
- Ui::PreventDelayedActivation();
- if (!Platform::File::UnsafeShowOpenWith(filepath)) {
- Platform::File::UnsafeLaunch(filepath);
- }
- }
- });
- }
- void Launch(const QString &filepath) {
- crl::on_main([=] {
- Ui::PreventDelayedActivation();
- Platform::File::UnsafeLaunch(filepath);
- });
- }
- void ShowInFolder(const QString &filepath) {
- crl::on_main([=] {
- Ui::PreventDelayedActivation();
- base::Platform::ShowInFolder(filepath);
- });
- }
- QString DefaultDownloadPathFolder(not_null<Main::Session*> session) {
- #if OS_MAC_STORE
- return u"Telegram Lite"_q;
- #else // OS_MAC_STORE
- return session->supportMode() ? u"Tsupport Desktop"_q : AppName.utf16();
- #endif // OS_MAC_STORE
- }
- QString DefaultDownloadPath(not_null<Main::Session*> session) {
- if (!Core::App().canReadDefaultDownloadPath()) {
- return session->local().tempDirectory();
- }
- return QStandardPaths::writableLocation(
- QStandardPaths::DownloadLocation)
- + '/'
- + DefaultDownloadPathFolder(session)
- + '/';
- }
- namespace internal {
- void UnsafeOpenUrlDefault(const QString &url) {
- QDesktopServices::openUrl(url);
- }
- void UnsafeOpenEmailLinkDefault(const QString &email) {
- auto url = QUrl(u"mailto:"_q + email);
- QDesktopServices::openUrl(url);
- }
- void UnsafeLaunchDefault(const QString &filepath) {
- QDesktopServices::openUrl(QUrl::fromLocalFile(filepath));
- }
- } // namespace internal
- } // namespace File
- namespace FileDialog {
- void GetOpenPath(
- QPointer<QWidget> parent,
- const QString &caption,
- const QString &filter,
- Fn<void(OpenResult &&result)> callback,
- Fn<void()> failed) {
- InvokeQueued(QCoreApplication::instance(), [=] {
- auto files = QStringList();
- auto remoteContent = QByteArray();
- Ui::PreventDelayedActivation();
- const auto success = Platform::FileDialog::Get(
- parent,
- files,
- remoteContent,
- caption,
- filter,
- FileDialog::internal::Type::ReadFile);
- if (success
- && ((!files.isEmpty() && !files[0].isEmpty())
- || !remoteContent.isEmpty())) {
- if (callback) {
- auto result = OpenResult();
- if (!files.isEmpty() && !files[0].isEmpty()) {
- result.paths.push_back(files[0]);
- }
- result.remoteContent = remoteContent;
- callback(std::move(result));
- }
- } else if (failed) {
- failed();
- }
- });
- }
- void GetOpenPaths(
- QPointer<QWidget> parent,
- const QString &caption,
- const QString &filter,
- Fn<void(OpenResult &&result)> callback,
- Fn<void()> failed) {
- InvokeQueued(QCoreApplication::instance(), [=] {
- auto files = QStringList();
- auto remoteContent = QByteArray();
- Ui::PreventDelayedActivation();
- const auto success = Platform::FileDialog::Get(
- parent,
- files,
- remoteContent,
- caption,
- filter,
- FileDialog::internal::Type::ReadFiles);
- if (success && (!files.isEmpty() || !remoteContent.isEmpty())) {
- if (callback) {
- auto result = OpenResult();
- result.paths = files;
- result.remoteContent = remoteContent;
- callback(std::move(result));
- }
- } else if (failed) {
- failed();
- }
- });
- }
- void GetWritePath(
- QPointer<QWidget> parent,
- const QString &caption,
- const QString &filter,
- const QString &initialPath,
- Fn<void(QString &&result)> callback,
- Fn<void()> failed) {
- InvokeQueued(QCoreApplication::instance(), [=] {
- auto file = QString();
- if (filedialogGetSaveFile(parent, file, caption, filter, initialPath)) {
- if (callback) {
- callback(std::move(file));
- }
- } else if (failed) {
- failed();
- }
- });
- }
- void GetFolder(
- QPointer<QWidget> parent,
- const QString &caption,
- const QString &initialPath,
- Fn<void(QString &&result)> callback,
- Fn<void()> failed) {
- InvokeQueued(QCoreApplication::instance(), [=] {
- auto files = QStringList();
- auto remoteContent = QByteArray();
- Ui::PreventDelayedActivation();
- const auto success = Platform::FileDialog::Get(
- parent,
- files,
- remoteContent,
- caption,
- QString(),
- FileDialog::internal::Type::ReadFolder,
- initialPath);
- if (success && !files.isEmpty() && !files[0].isEmpty()) {
- if (callback) {
- callback(std::move(files[0]));
- }
- } else if (failed) {
- failed();
- }
- });
- }
- QString AllFilesFilter() {
- #ifdef Q_OS_WIN
- return u"All files (*.*)"_q;
- #else // Q_OS_WIN
- return u"All files (*)"_q;
- #endif // Q_OS_WIN
- }
- QString ImagesFilter() {
- return u"Image files (*"_q + Ui::ImageExtensions().join(u" *"_q) + u")"_q;
- }
- QString AllOrImagesFilter() {
- return AllFilesFilter() + u";;"_q + ImagesFilter();
- }
- QString ImagesOrAllFilter() {
- return ImagesFilter() + u";;"_q + AllFilesFilter();
- }
- QString PhotoVideoFilesFilter() {
- return u"Image and Video Files (*.png *.jpg *.jpeg *.mp4 *.mov *.m4v);;"_q
- + AllFilesFilter();
- }
- const QString &Tmp() {
- static const auto tmp = u"tmp"_q;
- return tmp;
- }
- namespace internal {
- void InitLastPathDefault() {
- cSetDialogLastPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
- }
- bool GetDefault(
- QPointer<QWidget> parent,
- QStringList &files,
- QByteArray &remoteContent,
- const QString &caption,
- const QString &filter,
- FileDialog::internal::Type type,
- QString startFile = QString()) {
- if (cDialogLastPath().isEmpty()) {
- Platform::FileDialog::InitLastPath();
- }
- remoteContent = QByteArray();
- if (startFile.isEmpty() || startFile.at(0) != '/') {
- startFile = cDialogLastPath() + '/' + startFile;
- }
- QString file;
- const auto resolvedParent = (parent && parent->window()->isVisible())
- ? parent->window()
- : Core::App().getFileDialogParent();
- Core::App().notifyFileDialogShown(true);
- const auto guard = gsl::finally([] {
- Core::App().notifyFileDialogShown(false);
- });
- if (type == Type::ReadFiles) {
- files = QFileDialog::getOpenFileNames(resolvedParent, caption, startFile, filter);
- QString path = files.isEmpty() ? QString() : QFileInfo(files.back()).absoluteDir().absolutePath();
- if (!path.isEmpty() && path != cDialogLastPath()) {
- cSetDialogLastPath(path);
- Local::writeSettings();
- }
- return !files.isEmpty();
- } else if (type == Type::ReadFolder) {
- file = QFileDialog::getExistingDirectory(resolvedParent, caption, startFile);
- } else if (type == Type::WriteFile) {
- file = QFileDialog::getSaveFileName(resolvedParent, caption, startFile, filter);
- } else {
- file = QFileDialog::getOpenFileName(resolvedParent, caption, startFile, filter);
- }
- if (file.isEmpty()) {
- files = QStringList();
- return false;
- }
- if (type != Type::ReadFolder) {
- // Save last used directory for all queries except directory choosing.
- auto path = QFileInfo(file).absoluteDir().absolutePath();
- if (!path.isEmpty() && path != cDialogLastPath()) {
- cSetDialogLastPath(path);
- Local::writeSettings();
- }
- }
- files = QStringList(file);
- return true;
- }
- } // namespace internal
- } // namespace FileDialog
|