peony/ 0000775 0001750 0001750 00000000000 15167662230 010642 5 ustar feng feng peony/peony-qt.pro 0000664 0001750 0001750 00000000735 15154271070 013137 0 ustar feng feng TEMPLATE = subdirs
SUBDIRS = src libpeony-qt \ # plugin #libpeony-qt/test \ #plugin-iface
#libpeony-qt/model/model-test \
#libpeony-qt/file-operation/file-operation-test \
#peony-qt-plugin-test \
peony-qt-desktop \
stable
CONFIG += debug_and_release
CONFIG(release,debug|release){
DEFINES += QT_NO_DEBUG_OUTPUT
}
src.depends = libpeony-qt
peony-qt-plugin-test.depends = libpeony-qt
peony-qt-desktop.depends = libpeony-qt
stable.depends = libpeony-qt
peony/src/ 0000775 0001750 0001750 00000000000 15167662230 011431 5 ustar feng feng peony/src/peony-application.cpp 0000664 0001750 0001750 00000054514 15154271106 015573 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, KylinSoft Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#include "peony-application.h"
#include "menu-plugin-iface.h"
#include "main-window-factory-plugin-manager.h"
#include "file-info.h"
#include "file-info-job.h"
#include "file-utils.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "preview-page-factory-manager.h"
#include "preview-page-plugin-iface.h"
#include "directory-view-factory-manager.h"
#include "directory-view-plugin-iface.h"
#include "directory-view-container.h"
#include "path-edit.h"
#include "location-bar.h"
#include
#include
#include "tool-bar.h"
#include
#include "tab-page.h"
#include "side-bar.h"
#include "navigation-tool-bar.h"
#include "navigation-bar.h"
#include "fm-window.h"
//#include "main-window.h"
#include "global-settings.h"
#include
#include
#include "search-vfs-register.h"
#include
#include "menu-plugin-manager.h"
#include "directory-view-menu.h"
#include "icon-view.h"
#include "side-bar-factory-manager.h"
#include "intel/tablet-side-bar-factory.h"
#include "plugin-manager.h"
#include "list-view.h"
#include "basic-properties-page.h"
#include "file-count-operation.h"
#include
#include "properties-window-factory-plugin-manager.h"
#include "properties-window.h"
#include "complementary-style.h"
#include "volume-manager.h"
#include "file-enumerator.h"
#include "gerror-wrapper.h"
#include "image-mount-manager.h"
#include "main-window.h"
#include "thumbnail-manager.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define KYLIN_USER_GUIDE_PATH "/"
#define KYLIN_USER_GUIDE_SERVICE QString("com.kylinUserGuide.hotel_%1").arg(getuid())
#define KYLIN_USER_GUIDE_INTERFACE "com.guide.hotel"
//record of peony start time
qint64 PeonyApplication::peony_start_time = 0;
static bool m_resident = false;
PeonyApplication::PeonyApplication(int &argc, char *argv[], const char *applicationName) : SingleApplication (argc, argv, applicationName, true)
{
// fix #172774
QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths()<<"/usr/share/pixmaps");
bool isWayland = QString(qgetenv("XDG_SESSION_DESKTOP")).contains("ukui-wayland");
setProperty("isWayland", isWayland);
setApplicationVersion(QString("v%1").arg(VERSION));
//setApplicationDisplayName(tr("Peony-Qt"));
// QFile file(":/data/libpeony-qt-styled.qss");
// file.open(QFile::ReadOnly);
// setStyleSheet(QString::fromLatin1(file.readAll()));
// qDebug()<load("/usr/share/libpeony-qt/libpeony-qt_"+QLocale::system().name());
QApplication::installTranslator(t);
QTranslator *t2 = new QTranslator(this);
t2->load("/usr/share/peony-qt/peony-qt_"+QLocale::system().name());
QApplication::installTranslator(t2);
QTranslator *t3 = new QTranslator(this);
t3->load("/usr/share/qt6/translations/qt_"+QLocale::system().name());
QApplication::installTranslator(t3);
QTranslator *t4 = new QTranslator(this);
t4->load("/usr/share/qt6/translations/qtbase_"+QLocale::system().name());
QApplication::installTranslator(t4);
//setStyle(Peony::ComplementaryStyle::getStyle());
QTranslator *sdkTrans = new QTranslator(this);
if (sdkTrans->load(":/translations/gui_" + QLocale::system().name() + ".qm")) {
QApplication::installTranslator(sdkTrans);
}
#ifdef KY_UDF_BURN
QTranslator *tUdfBrun = new QTranslator(this);
auto udfBurnTranslationFilePath = QString("/usr/share/kyudfburn/translations/kyudfburn_%1.qm").arg(QLocale::system().name());
bool ok = tUdfBrun->load(udfBurnTranslationFilePath);
if (!ok) {
qWarning()<<"can not load kyudfburn translation files, path is"<isSecondary()) {
parser.addHelpOption();
parser.addVersionOption();
if (this->arguments().count() == 2 && arguments().last() == ".") {
QStringList args;
auto dir = g_get_current_dir();
args<<"peony"<isPrimary()) {
connect(this, &SingleApplication::receivedMessage, this, &PeonyApplication::parseCmd);
Peony::SideBarFactoryManager::getInstance()->registerFactory(new Peony::Intel::TabletSideBarFactory);
} else {
qCritical()<<"secondary process send message to old primary process failed, try changed this process to primary one";
this->startPrimary();
connect(this, &SingleApplication::receivedMessage, this, &PeonyApplication::parseCmd);
}
//parse cmd
parser.process(arguments());
QStringList allArgs = arguments();
auto message = getUriMessage(allArgs).toUtf8();
parseCmd(this->instanceId(), message);
auto testIcon = QIcon::fromTheme("folder");
if (testIcon.isNull()) {
QIcon::setThemeName("ukui-icon-theme-default");
if (QStyleFactory::keys().contains("gtk2")) {
setStyle("gtk2");
}
QMessageBox::warning(nullptr, tr("Warning"), tr("Peony-Qt can not get the system's icon theme. "
"There are 2 reasons might lead to this problem:\n\n"
"1. Peony-Qt might be running as root, "
"that means you have the higher permission "
"and can do some things which normally forbidden. "
"But, you should learn that if you were in a "
"root, the virtual file system will lose some "
"featrue such as you can not use \"My Computer\", "
"the theme and icons might also went wrong. So, run "
"peony-qt in a root is not recommended.\n\n"
"2. You are using a non-qt theme for your system but "
"you didn't install the platform theme plugin for qt's "
"applications. If you are using gtk-theme, try installing "
"the qt5-gtk2-platformtheme package to resolve this problem."));
}
//Peony::SearchVFSRegister::registSearchVFS();
//QIcon::setThemeName("ukui-icon-theme-one");
//setAttribute(Qt::AA_UseHighDpiPixmaps);
//setAttribute(Qt::AA_EnableHighDpiScaling);
setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
//setStyle(QStyleFactory::create("windows"));
//check if first run
//if not send message to server
//else
// load plgin
// read from command line
// do with args
setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
connect(IMAGE_MOUNT_MANAGER, &Peony::ImageMountManager::deviceMounted, this, [this](const QString &mountPoint) {
MainWindow* mainWindow = activedTopMainWindow();
if (mainWindow && QFileInfo(mountPoint).exists()) {
QString uri = "file://" + mountPoint;
mainWindow->goToUri(uri, true);
}
});
connect(IMAGE_MOUNT_MANAGER, &Peony::ImageMountManager::mountError, this, [this](const QString &errMsg) {
if (!errMsg.isEmpty()) {
qDebug() << "iso image unmount or mount error: " << errMsg;
}
});
}
static void unmount_finished(GFile* file, GAsyncResult* result, gpointer udata)
{
int flags = 0;
GError *err = nullptr;
if (g_file_unmount_mountable_with_operation_finish (file, result, &err) == TRUE){
flags = 1;
char *uri = g_file_get_uri(file);
Peony::VolumeManager::getInstance()->fileUnmounted(uri);
if (uri)
g_free(uri);
}
if (! m_resident)
{
qApp->setQuitOnLastWindowClosed(true);
}
if (err){
qCritical() << "main window unmount_finished error:"<message<topLevelWindows().count() <= 0 && ! m_resident){
qDebug() << "has no new window, exit";
qApp->exit();
}
}
void PeonyApplication::unmountAllFtpLinks()
{
qDebug() << "lastWindowClosed unmountAllFtpLinks";
auto allUris = Peony::FileUtils::getChildrenUris("computer:///");
for(auto uri : allUris)
{
auto targetUri = Peony::FileUtils::getTargetUri(uri);
qDebug() << "unmountAllFtpLinks targetUri:" <getValue(RESIDENT_IN_BACKEND).toBool();
qApp->setQuitOnLastWindowClosed(false);
GFile *file = g_file_new_for_uri(uri.toUtf8().constData());
g_file_unmount_mountable_with_operation(file,
G_MOUNT_UNMOUNT_NONE,
nullptr,
nullptr,
GAsyncReadyCallback(unmount_finished),
this);
g_object_unref(file);
}
}
QString PeonyApplication::getUriMessage(QStringList& strList)
{
QStringList args;
for (auto uri = strList.constBegin(); uri != strList.constEnd(); ++uri) {
if ("peony" == (*uri) || (*uri).startsWith("-") || (*uri).startsWith("--") || (*uri).startsWith("%")
|| (*uri).startsWith("/usr/") || (*uri).startsWith("/bin/") || (*uri).startsWith("/sbin/")) {
args << *uri;
} else if ((*uri).startsWith("/")) {
args << Peony::FileUtils::urlEncode("file://" + *uri);
} else if ((*uri).startsWith("mtp://") || (*uri).startsWith("gphoto2://")) {
args << *uri;
} else if ((*uri).contains("://")) {
args << Peony::FileUtils::urlEncode(*uri);
} else {
args << Peony::FileUtils::urlEncode(QString("file://%1/%2").arg(g_get_current_dir()).arg(*uri));
}
}
return args.join(' ');
}
void PeonyApplication::parseCmd(quint32 id, QByteArray msg)
{
//story 28077, control start of peony
if (! Peony::GlobalSettings::getInstance()->getValue(ENABLE_START_PEONY).toBool()){
qWarning() << "peony is diablsed to start";
Peony::GlobalSettings::getInstance()->sendNotifyMessage(tr("Peony is disabled to start !"));
return;
}
QCommandLineParser parser;
if (m_first_parse) {
parser.addHelpOption();
parser.addVersionOption();
m_first_parse = false;
}
parser.addOption(quitOption);
parser.addOption(showItemsOption);
parser.addOption(showFoldersOption);
parser.addOption(showPropertiesOption);
//qDebug()<<"parse cmd:"<<"id:"<quit();
});
return;
}
MainWindowFactoryPluginManager::getInstance()->setVersion();
//FIXME: should I load plugins async?
//Peony::PluginManager::init();
if (!parser.optionNames().isEmpty()) {
if (parser.isSet(showItemsOption)) {
//FIXME: show item parent folder and set selection for item.
QHash itemHash;
auto uris = Peony::FileUtils::toDisplayUris(parser.positionalArguments());
if (uris.isEmpty()) {
return;
}
for (auto uri : uris) {
auto parentUri = Peony::FileUtils::getParentUri(uri);
if (itemHash.value(parentUri).isEmpty()) {
QStringList l;
l<create(parentUri,itemHash.value(parentUri));
// Peony::MainWindowIface* mainWindowIface = dynamic_cast(window);
//auto window = new MainWindow(parentUri);
//Peony::FMWindow *window = new Peony::FMWindow(parentUri);
// connect(mainWindowIface, &Peony::MainWindowIface::locationChangeEnd, [=]() {
// QTimer::singleShot(500, [=] {
// Peony::FMWindowIface* iface = dynamic_cast(window);
// iface->getCurrentPage()->getView()->setSelections(itemHash.value(parentUri));
// iface->getCurrentPage()->getView()->scrollToSelection(itemHash.value(parentUri).first());
// });
// });
window->show();
window->raise();
window->activateWindow();
if (QWindow *w = window->windowHandle()) {
w->raise();
w->requestActivate();
}
// KWindowSystem::raiseWindow(window->winId());
// if (KWindowSystem::activeWindow() != window->winId()) {
// KWindowSystem::activateWindow(window->winId());
// }
}
}
if (parser.isSet(showFoldersOption)) {
QStringList uris = Peony::FileUtils::toDisplayUris(parser.positionalArguments());
if (uris.isEmpty()) {
return;
}
QWidget *window = MainWindowFactoryPluginManager::getInstance()->create(uris.first());
//auto window = new MainWindow(uris.first());
//Peony::FMWindow *window = new Peony::FMWindow(uris.first());
uris.removeAt(0);
if (!uris.isEmpty()) {
Peony::FMWindowIface* iface = dynamic_cast(window);
iface->addNewTabs(uris);
}
window->show();
if (QWindow *w = window->windowHandle()) {
w->raise();
w->requestActivate();
}
// KWindowSystem::raiseWindow(window->winId());
// if (KWindowSystem::activeWindow() != window->winId()) {
// KWindowSystem::activateWindow(window->winId());
// }
}
if (parser.isSet(showPropertiesOption)) {
QStringList uris = Peony::FileUtils::toDisplayUris(parser.positionalArguments());
if (uris.isEmpty()) {
return;
}
qApp->setProperty("showProperties", true);
Peony::ThumbnailManager::setPropertiesWindowVisible(true);
QMainWindow *window = Peony::PropertiesWindowFactoryPluginManager::getInstance()->create(uris);
//Peony::PropertiesWindow *window = new Peony::PropertiesWindow(uris);
Peony::PropertiesWindow *w = qobject_cast(window);
if (w) {
if (Peony::GlobalSettings::getInstance()->isExist(SHOW_SHARE_PROPERTIES) && Peony::GlobalSettings::getInstance()->getValue(SHOW_SHARE_PROPERTIES).toBool()) {
w->setOpenTabPage("SharePage");
Peony::GlobalSettings::getInstance()->setValue(SHOW_SHARE_PROPERTIES, false);
}
}
window->setAttribute(Qt::WA_DeleteOnClose);
Peony::PropertiesWindowFactoryPluginManager::getInstance()->show();
//window->show();
window->show();
window->activateWindow();
// KWindowSystem::raiseWindow(window->winId());
// if (KWindowSystem::activeWindow() != window->winId()) {
// KWindowSystem::activateWindow(window->winId());
// }
Peony::ThumbnailManager::setPropertiesWindowVisible(false);
}
} else {
if (!parser.positionalArguments().isEmpty()) {
auto arguments = parser.positionalArguments();
arguments.removeOne("%U");
arguments.removeOne("%U&");
QStringList uris = Peony::FileUtils::toDisplayUris(arguments);
if (!uris.isEmpty()) {
QWidget *window = MainWindowFactoryPluginManager::getInstance()->create(uris.first());
Peony::FMWindowIface* iface = dynamic_cast(window);
//auto window = new MainWindow(uris.first());
uris.removeAt(0);
if (!uris.isEmpty()) {
iface->addNewTabs(uris);
}
window->setAttribute(Qt::WA_DeleteOnClose);
window->show();
if (QWindow *w = window->windowHandle()) {
w->raise();
w->requestActivate();
}
// KWindowSystem::raiseWindow(window->winId());
// if (KWindowSystem::activeWindow() != window->winId()) {
// KWindowSystem::activateWindow(window->winId());
// }
} else {
QWidget *window = MainWindowFactoryPluginManager::getInstance()->create(QString());
// auto window = new MainWindow();
window->setAttribute(Qt::WA_DeleteOnClose);
window->show();
if (QWindow *w = window->windowHandle()) {
w->raise();
w->requestActivate();
}
// KWindowSystem::raiseWindow(window->winId());
// if (KWindowSystem::activeWindow() != window->winId()) {
// KWindowSystem::activateWindow(window->winId());
// }
}
} else {
QWidget *window = MainWindowFactoryPluginManager::getInstance()->create(QString());
//auto window = new MainWindow;
//auto window = new Peony::FMWindow;
window->setAttribute(Qt::WA_DeleteOnClose);
window->show();
if (QWindow *w = window->windowHandle()) {
w->raise();
w->requestActivate();
}
// KWindowSystem::raiseWindow(window->winId());
// if (KWindowSystem::activeWindow() != window->winId()) {
// KWindowSystem::activateWindow(window->winId());
// }
}
}
connect(this, &QApplication::paletteChanged, this, [=](const QPalette &pal) {
for (auto w : allWidgets()) {
w->setPalette(pal);
w->update();
}
});
}
void PeonyApplication::about()
{
QMessageBox *msgBox = new QMessageBox();
msgBox->setWindowTitle(tr("Peony Qt"));
msgBox->setText(tr("Copyright (C): 2020, KylinSoft Co., Ltd."));
msgBox->setModal(false);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->show();
}
void PeonyApplication::help()
{
showGuide();
}
bool PeonyApplication::userGuideDaemonRunning()
{
QDBusConnection conn = QDBusConnection::sessionBus();
if (!conn.isConnected())
return false;
QDBusReply reply = conn.interface()->call("GetNameOwner", KYLIN_USER_GUIDE_SERVICE);
return reply != "";
}
void PeonyApplication::showGuide(const QString &appName)
{
auto s = KYLIN_USER_GUIDE_SERVICE;
qDebug()<topLevelWidgets();
for (QWidget *widget : widgets) {
if (widget->objectName() == "_peony_mainwindow") {
MainWindow* mainWindow = static_cast(widget);
if (mainWindow) {
return mainWindow;
}
}
}
return nullptr;
}
peony/src/customIcons.qrc 0000664 0001750 0001750 00000000044 15154271070 014436 0 ustar feng feng
peony/src/windows/ 0000775 0001750 0001750 00000000000 15154271106 013115 5 ustar feng feng peony/src/windows/x11-window-manager.h 0000664 0001750 0001750 00000007401 15154271106 016616 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#ifndef X11WINDOWMANAGER_H
#define X11WINDOWMANAGER_H
#include
#include
#include
class X11WindowManager : public QObject
{
Q_OBJECT
public:
static X11WindowManager *getInstance();
bool eventFilter(QObject *watched, QEvent *event) override;
void registerWidget(QWidget *widget);
private:
explicit X11WindowManager(QObject *parent = nullptr);
bool m_is_draging = false;
ulong m_prepare_drag_time = 0;
QWidget *m_current_widget = nullptr;
QPoint m_press_pos;
QPoint m_toplevel_offset;
};
struct UnityCorners {
ulong topLeft = 0;
ulong topRight = 0;
ulong bottomLeft = 0;
ulong bottomRight = 0;
};
typedef struct {
ulong flags = 0;
ulong functions = 0;
ulong decorations = 0;
long input_mode = 0;
ulong status = 0;
} MotifWmHints, MwmHints;
#define MWM_HINTS_FUNCTIONS (1L << 0)
#define MWM_HINTS_DECORATIONS (1L << 1)
#define MWM_HINTS_INPUT_MODE (1L << 2)
#define MWM_HINTS_STATUS (1L << 3)
#define MWM_FUNC_ALL (1L << 0)
#define MWM_FUNC_RESIZE (1L << 1)
#define MWM_FUNC_MOVE (1L << 2)
#define MWM_FUNC_MINIMIZE (1L << 3)
#define MWM_FUNC_MAXIMIZE (1L << 4)
#define MWM_FUNC_CLOSE (1L << 5)
#define MWM_DECOR_ALL (1L << 0)
#define MWM_DECOR_BORDER (1L << 1)
#define MWM_DECOR_RESIZEH (1L << 2)
#define MWM_DECOR_TITLE (1L << 3)
#define MWM_DECOR_MENU (1L << 4)
#define MWM_DECOR_MINIMIZE (1L << 5)
#define MWM_DECOR_MAXIMIZE (1L << 6)
#define MWM_INPUT_MODELESS 0
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
#define MWM_INPUT_SYSTEM_MODAL 2
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
#define MWM_TEAROFF_WINDOW (1L<<0)
namespace UKUI {
class Decoration;
}
class XAtomHelper : public QObject
{
friend class UKUI::Decoration;
Q_OBJECT
public:
static XAtomHelper *getInstance();
static bool isFrameLessWindow(int winId);
bool isWindowDecorateBorderOnly(int winId);
bool isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint);
bool isUKUICsdSupported();
bool isUKUIDecorationWindow(int winId);
UnityCorners getWindowBorderRadius(int winId);
void setWindowBorderRadius(int winId, const UnityCorners &data);
void setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight);
void setUKUIDecoraiontHint(int winId, bool set = true);
void setWindowMotifHint(int winId, const MotifWmHints &hints);
MotifWmHints getWindowMotifHint(int winId);
static Display *getDisplay();
static bool isPlatformX11();
private:
explicit XAtomHelper(QObject *parent = nullptr);
unsigned long registerUKUICsdNetWmSupportAtom();
void unregisterUKUICsdNetWmSupportAtom();
unsigned long m_motifWMHintsAtom = 0l;
unsigned long m_unityBorderRadiusAtom = 0l;
unsigned long m_ukuiDecorationAtion = 0l;
};
#endif // X11WINDOWMANAGER_H
peony/src/windows/about-dialog.ui 0000664 0001750 0001750 00000025716 15154271070 016036 0 ustar feng feng
AboutDialog
0
0
420
492
0
0
420
324
420
560
Dialog
0
0
0
0
0
-
0
32
32
-
0
0
0
0
16777215
16777215
Qt::NoFocus
QFrame::NoFrame
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'Noto Sans CJK SC'; font-size:10pt; font-weight:400; font-style:normal;">
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p></body></html>
-
Qt::Vertical
QSizePolicy::Fixed
20
24
-
TextLabel
-
Qt::Vertical
QSizePolicy::Fixed
20
40
-
8
4
4
4
4
-
0
4
4
-
24
24
24
24
-
0
28
16777215
24
-
30
30
30
30
Qt::RightToLeft
-
0
-
Qt::Horizontal
118
20
-
38
-
96
96
96
96
Qt::AlignBottom|Qt::AlignHCenter
-
Qt::Horizontal
118
20
-
0
0
0
-
Qt::Horizontal
88
20
-
0
16
12
-
12
-
0
28
16777215
28
11
Qt::LeftToRight
Qt::AlignCenter
-
0
24
16777215
24
11
Qt::AlignCenter
-
Qt::Horizontal
88
20
peony/src/windows/trash-warn-dialog.h 0000664 0001750 0001750 00000002115 15154271070 016610 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2021, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Wenfei He
*
*/
#ifndef TRASHWARNDIALOG_H
#define TRASHWARNDIALOG_H
#include "QDialog"
namespace Peony {
class TrashWarnDialog : public QDialog
{
Q_OBJECT
public:
explicit TrashWarnDialog(QWidget *parent = nullptr);
protected:
void paintEvent(QPaintEvent *event) override;
};
}
#endif //TRASHWARNDIALOG_H
peony/src/windows/x11-window-manager.cpp 0000664 0001750 0001750 00000033153 15154271106 017154 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#include "x11-window-manager.h"
#include "navigation-tab-bar.h"
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#define START_DRAG_TIME 120
static X11WindowManager *global_instance = nullptr;
X11WindowManager *X11WindowManager::getInstance()
{
if (!global_instance) {
global_instance = new X11WindowManager;
}
return global_instance;
}
X11WindowManager::X11WindowManager(QObject *parent) : QObject(parent)
{
}
bool X11WindowManager::eventFilter(QObject *watched, QEvent *event)
{
//qDebug()<type();
switch (event->type()) {
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchCancel:
case QEvent::TouchEnd: {
qDebug()<type();
break;
}
case QEvent::MouseButtonPress: {
//Make tabbar blank area dragable and do not effect tablabel.
if (qobject_cast(watched)) {
QMouseEvent *e = static_cast(event);
QTabBar *tabBar = qobject_cast(watched);
if (tabBar->tabAt(e->pos()) != -1)
return false;
}
QMouseEvent *e = static_cast(event);
if (QObject::eventFilter(watched, event))
return true;
if (e->button() == Qt::LeftButton) {
m_prepare_drag_time = e->timestamp();
//修改页签可以拖拽,记录鼠标位置
//bug#94981 修改页签可以拖拽,记录鼠标位置
m_press_pos = QCursor::pos();
m_is_draging = true;
m_current_widget = static_cast(watched);
m_toplevel_offset = m_current_widget->topLevelWidget()->mapFromGlobal(m_press_pos);
}
//qDebug()<type();
break;
}
case QEvent::MouseMove: {
QMouseEvent *e = static_cast(event);
//qDebug()<type()<pos();
if (m_is_draging) {
bool isPlatformX11 = qGuiApp->nativeInterface();
if (isPlatformX11) {
bool isTouchMove = e->source() == Qt::MouseEventSynthesizedByQt;
QPoint currentPos = QCursor::pos();
QPoint offset = QCursor::pos() - m_press_pos;
bool smallOffset = qAbs(offset.x()) <= 2 && qAbs(offset.y() <= 2);
if (smallOffset)
break;
Display *display = XAtomHelper::getDisplay();
Atom netMoveResize = XInternAtom(XAtomHelper::getDisplay(), "_NET_WM_MOVERESIZE", False);
XEvent xEvent;
const auto pos = currentPos - offset;
memset(&xEvent, 0, sizeof(XEvent));
xEvent.xclient.type = ClientMessage;
xEvent.xclient.message_type = netMoveResize;
xEvent.xclient.display = display;
xEvent.xclient.window = m_current_widget->topLevelWidget()->winId();
xEvent.xclient.format = 32;
xEvent.xclient.data.l[0] = pos.x() * qApp->devicePixelRatio();
xEvent.xclient.data.l[1] = pos.y() * qApp->devicePixelRatio();
xEvent.xclient.data.l[2] = 8;
xEvent.xclient.data.l[3] = Button1;
xEvent.xclient.data.l[4] = 0;
XUngrabPointer(display, CurrentTime);
Window rootWindow = 0;
int screen = 0;
if (auto *x11App = qApp->nativeInterface()) {
screen = DefaultScreen(display);
rootWindow = RootWindow(display, screen);
}
XSendEvent(display, rootWindow,
False, SubstructureNotifyMask | SubstructureRedirectMask,
&xEvent);
XFlush(display);
m_is_draging = false;
//NOTE: use x11 move will ungrab the window focus
//hide and show will restore the focus and it seems
//there is no bad effect for peony main window.
if (isTouchMove) {
if (!m_current_widget->mouseGrabber()) {
m_current_widget->grabMouse();
m_current_widget->releaseMouse();
}
}
if (qobject_cast(m_current_widget)) {
m_current_widget->hide();
m_current_widget->show();
}
//balance mouse release event
QMouseEvent me(QMouseEvent::MouseButtonRelease, e->pos(), e->windowPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers(), Qt::MouseEventSynthesizedByApplication);
qApp->sendEvent(watched, &me);
memset(&xEvent, 0, sizeof(XEvent));
xEvent.type = ButtonRelease;
xEvent.xbutton.button = Button1;
xEvent.xbutton.same_screen = true;
xEvent.xbutton.window = m_current_widget->topLevelWidget()->winId();
XSendEvent(display, m_current_widget->topLevelWidget()->winId(),
False, 0,
&xEvent);
return true;
} else {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
auto widget = qobject_cast(watched);
auto topLevel = widget->topLevelWidget();
topLevel->windowHandle()->startSystemMove();
m_is_draging = false;
#else
//auto me = static_cast(event);
auto widget = qobject_cast(watched);
auto topLevel = widget->topLevelWidget();
auto globalPos = QCursor::pos();
//auto offset = globalPos - m_press_pos;
topLevel->move(globalPos - m_toplevel_offset);
#endif
}
}
//commit id: 339dbaf18b9555d274e69c0589a755457e3f555b [FIX] 【文件管理器】首页页签未按UI设计稿还原 [LINK]94981
/*else {
bool overDragTime = 0 < m_prepare_drag_time && (m_prepare_drag_time + START_DRAG_TIME) < e->timestamp();
bool canDrag = !isTouchMove || overDragTime;
if (canDrag) {
m_is_draging = true;
m_prepare_drag_time = 0;
m_press_pos = QCursor::pos();
m_current_widget = static_cast(watched);
m_toplevel_offset = m_current_widget->topLevelWidget()->mapFromGlobal(m_press_pos);
}
}*/
break;
}
case QEvent::MouseButtonRelease: {
auto me = static_cast(event);
if (me->source() == Qt::MouseEventSynthesizedByApplication)
break;
m_prepare_drag_time = 0;
m_press_pos = QPoint();
m_is_draging = false;
m_current_widget = nullptr;
break;
}
default:
return false;
}
return false;
}
void X11WindowManager::registerWidget(QWidget *widget)
{
widget->removeEventFilter(this);
widget->installEventFilter(this);
}
static XAtomHelper *global_instance1 = nullptr;
XAtomHelper *XAtomHelper::getInstance()
{
if (!global_instance1)
global_instance1 = new XAtomHelper;
return global_instance1;
}
bool XAtomHelper::isFrameLessWindow(int winId)
{
auto hints = getInstance()->getWindowMotifHint(winId);
if (hints.flags == MWM_HINTS_DECORATIONS && hints.functions == 1) {
return true;
}
return false;
}
bool XAtomHelper::isWindowDecorateBorderOnly(int winId)
{
return isWindowMotifHintDecorateBorderOnly(getInstance()->getWindowMotifHint(winId));
}
bool XAtomHelper::isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint)
{
bool isDeco = false;
if (hint.flags & MWM_HINTS_DECORATIONS && hint.flags != MWM_HINTS_DECORATIONS) {
if (hint.decorations == MWM_DECOR_BORDER)
isDeco = true;
}
return isDeco;
}
bool XAtomHelper::isUKUICsdSupported()
{
// fixme:
return false;
}
bool XAtomHelper::isUKUIDecorationWindow(int winId)
{
if (m_ukuiDecorationAtion == None)
return false;
Atom type;
int format;
ulong nitems;
ulong bytes_after;
uchar *data;
bool isUKUIDecoration = false;
Display *display = XAtomHelper::getDisplay();
XGetWindowProperty(display, winId, m_ukuiDecorationAtion,
0, LONG_MAX, false,
m_ukuiDecorationAtion, &type,
&format, &nitems,
&bytes_after, &data);
if (type == m_ukuiDecorationAtion) {
if (nitems == 1) {
isUKUIDecoration = data[0];
}
}
return isUKUIDecoration;
}
UnityCorners XAtomHelper::getWindowBorderRadius(int winId)
{
UnityCorners corners;
Atom type;
int format;
ulong nitems;
ulong bytes_after;
uchar *data;
if (m_unityBorderRadiusAtom != None) {
XGetWindowProperty(XAtomHelper::getDisplay(), winId, m_unityBorderRadiusAtom,
0, LONG_MAX, false,
XA_CARDINAL, &type,
&format, &nitems,
&bytes_after, &data);
if (type == XA_CARDINAL) {
if (nitems == 4) {
corners.topLeft = static_cast(data[0]);
corners.topRight = static_cast(data[1*sizeof (ulong)]);
corners.bottomLeft = static_cast(data[2*sizeof (ulong)]);
corners.bottomRight = static_cast(data[3*sizeof (ulong)]);
}
XFree(data);
}
}
return corners;
}
void XAtomHelper::setWindowBorderRadius(int winId, const UnityCorners &data)
{
if (m_unityBorderRadiusAtom == None)
return;
ulong corners[4] = {data.topLeft, data.topRight, data.bottomLeft, data.bottomRight};
XChangeProperty(XAtomHelper::getDisplay(), winId, m_unityBorderRadiusAtom, XA_CARDINAL,
32, PropModeReplace, (const unsigned char *) &corners, sizeof (corners)/sizeof (corners[0]));
}
void XAtomHelper::setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight)
{
if (m_unityBorderRadiusAtom == None)
return;
ulong corners[4] = {(ulong)topLeft, (ulong)topRight, (ulong)bottomLeft, (ulong)bottomRight};
XChangeProperty(XAtomHelper::getDisplay(), winId, m_unityBorderRadiusAtom, XA_CARDINAL,
32, PropModeReplace, (const unsigned char *) &corners, sizeof (corners)/sizeof (corners[0]));
}
void XAtomHelper::setUKUIDecoraiontHint(int winId, bool set)
{
if (m_ukuiDecorationAtion == None)
return;
XChangeProperty(XAtomHelper::getDisplay(), winId, m_ukuiDecorationAtion, m_ukuiDecorationAtion, 32, PropModeReplace, (const unsigned char *) &set, 1);
}
void XAtomHelper::setWindowMotifHint(int winId, const MotifWmHints &hints)
{
if (m_unityBorderRadiusAtom == None)
return;
XChangeProperty(XAtomHelper::getDisplay(), winId, m_motifWMHintsAtom, m_motifWMHintsAtom,
32, PropModeReplace, (const unsigned char *)&hints, sizeof (MotifWmHints)/ sizeof (ulong));
}
MotifWmHints XAtomHelper::getWindowMotifHint(int winId)
{
MotifWmHints hints;
if (m_unityBorderRadiusAtom == None)
return hints;
uchar *data;
Atom type;
int format;
ulong nitems;
ulong bytes_after;
XGetWindowProperty(XAtomHelper::getDisplay(), winId, m_motifWMHintsAtom,
0, sizeof (MotifWmHints)/sizeof (long), false, AnyPropertyType, &type,
&format, &nitems, &bytes_after, &data);
if (type == None) {
return hints;
} else {
hints = *(MotifWmHints *)data;
XFree(data);
}
return hints;
}
XAtomHelper::XAtomHelper(QObject *parent) : QObject(parent)
{
if (!XAtomHelper::isPlatformX11())
return;
m_motifWMHintsAtom = XInternAtom(XAtomHelper::getDisplay(), "_MOTIF_WM_HINTS", true);
m_unityBorderRadiusAtom = XInternAtom(XAtomHelper::getDisplay(), "_UNITY_GTK_BORDER_RADIUS", false);
m_ukuiDecorationAtion = XInternAtom(XAtomHelper::getDisplay(), "_KWIN_UKUI_DECORAION", false);
}
Atom XAtomHelper::registerUKUICsdNetWmSupportAtom()
{
// fixme:
return None;
}
void XAtomHelper::unregisterUKUICsdNetWmSupportAtom()
{
// fixme:
}
Display *XAtomHelper::getDisplay()
{
auto *x11Application = qGuiApp->nativeInterface();
if (!x11Application) {
return nullptr;
}
return x11Application->display();
}
bool XAtomHelper::isPlatformX11()
{
auto *x11Application = qGuiApp->nativeInterface();
if (!x11Application) {
return false;
}
return true;
}
peony/src/windows/main-window.cpp 0000664 0001750 0001750 00000242445 15154271106 016065 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#include "main-window.h"
#include "header-bar.h"
#include "global-settings.h"
#include "border-shadow-effect.h"
#include
#include
//#include
#include
#include
#include
#include
#include
#include "side-bar-proxy-filter-sort-model.h"
#include "side-bar-model.h"
#include "directory-view-container.h"
#include "tab-widget.h"
#include "x11-window-manager.h"
#include "properties-window-factory-plugin-manager.h"
//#include "properties-window.h"
#include "preview-page-factory-manager.h"
#include "preview-page-plugin-iface.h"
#include "navigation-side-bar.h"
#include "advance-search-bar.h"
#include "status-bar.h"
#include "search-widget.h"
#include "intel/intel-navigation-side-bar.h"
#include "peony-main-window-style.h"
#include "file-label-box.h"
#include "file-operation-manager.h"
#include "file-operation-utils.h"
#include "file-utils.h"
#include "create-template-operation.h"
#include "file-operation-error-dialog.h"
#include "clipboard-utils.h"
#include "search-vfs-uri-parser.h"
#include "file-delete-operation.h"
#include "file-untrash-operation.h"
#include "directory-view-menu.h"
#include "directory-view-widget.h"
#include "main-window-factory.h"
#include "thumbnail-manager.h"
#include "peony-application.h"
#include "global-settings.h"
#include "audio-play-manager.h"
#include "float-pane-widget.h"
#include "side-bar-factory-manager.h"
#include "file-meta-info.h"
#include "sound-effect.h"
#include "location-bar.h"
#include "file-launch-action.h"
#include "file-launch-manager.h"
#include "file-utils.h"
#include "trash-cleaned-watcher.h"
#include "directory-view-factory-manager.h"
#include "manager-control.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
#include
#endif
#include
#include
#include
#include
#include
#include
#include "directoryviewhelper.h"
#include "plugin-manager.h"
// NOTE build failed on Archlinux. Can't detect `QGSettings/QGSettings' header
// fixed by replaced `QGSettings/QGSettings' with `QGSettings'
#include
//#include "xatom-helper.h"
#include "trash-warn-dialog.h"
#include
#ifdef KY_SDK_WAYLANDHELPER
#include
#include
#endif
#define FONT_SETTINGS "org.ukui.style"
#include
#include
static MainWindow *last_resize_window = nullptr;
static QWidgetList blur_window_list;
MainWindow::MainWindow(const QString &uri, QWidget *parent) : QMainWindow(parent)
{
#ifdef KY_SDK_WAYLANDHELPER
m_window_helper = new UkuiWindowHelper(this);
#endif
QString localeName = QLocale::system().name();
if (localeName.contains("ug") || localeName.contains("kk") || localeName.contains("ky")) {
setLayoutDirection(Qt::RightToLeft);
}
// try fix #162452, filedialog changes peony main windows view type and sort options.
setObjectName("_peony_mainwindow");
setAttribute(Qt::WA_AlwaysShowToolTips);
setContextMenuPolicy(Qt::CustomContextMenu);
installEventFilter(this);
//use qApp set window icon, task#29435
qApp->setWindowIcon(QIcon::fromTheme("system-file-manager"));
//setWindowTitle(tr("File Manager"));
//check all settings and init
checkSettings();
//setStyle(PeonyMainWindowStyle::getStyle());
m_effect = new BorderShadowEffect(this);
m_effect->setPadding(0);
m_effect->setBorderRadius(0);
m_effect->setBlurRadius(0);
//setGraphicsEffect(m_effect);
setAnimated(false);
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_TranslucentBackground);
//setAttribute(Qt::WA_OpaquePaintEvent);
//fix double window base buttons issue, not effect MinMax button hints
//auto flags = windowFlags() &~Qt::WindowMinMaxButtonsHint;
//setWindowFlags(flags |Qt::FramelessWindowHint);
//setWindowFlags(windowFlags()|Qt::FramelessWindowHint);
//setContentsMargins(4, 4, 4, 4);
//disable style window manager
setProperty("useStyleWindowManager", false);
//set minimum width by design request
//打开预览框后拉动侧边栏会导致关闭控件被遮盖
//setMinimumWidth(WINDOW_MINIMUM_WIDTH);
//short cut settings
setShortCuts();
bool isTabletMode = false;
m_statusManagerDBus = new QDBusInterface(DBUS_STATUS_MANAGER_IF, "/" ,DBUS_STATUS_MANAGER_IF,QDBusConnection::sessionBus(),this);
if (m_statusManagerDBus) {
qDebug() << "[PeonyDesktopApplication::initGSettings] init statusManagerDBus" << m_statusManagerDBus->isValid();
if (m_statusManagerDBus->isValid()) {
QDBusReply message = m_statusManagerDBus->call("get_current_tabletmode");
if (message.isValid()) {
isTabletMode = message.value();
}
//平板模式切换
connect(m_statusManagerDBus, SIGNAL(mode_change_signal(bool)), this, SLOT(updateTabletModeValue(bool)));
}
}
//init UI after show
auto size = sizeHint();
resize(size);
connect(this, &MainWindow::initUIRequest, this, [=]{
QTimer::singleShot(50, this, [=]{
initUI(uri);
updateTabletModeValue(isTabletMode);
});
});
// set tab order
bool isPlatformX11 = qGuiApp->nativeInterface();
if (isPlatformX11) {
XAtomHelper::getInstance()->setUKUIDecoraiontHint(this->winId(), true);
MotifWmHints hints;
hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS;
hints.functions = MWM_FUNC_ALL;
hints.decorations = MWM_DECOR_BORDER;
XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints);
Window rootWindow = 0;
int screen = 0;
if (auto *x11App = qApp->nativeInterface()) {
Display *display = XAtomHelper::getDisplay();
screen = DefaultScreen(display);
rootWindow = RootWindow(display, screen);
NETWinInfo info(x11App->connection(), this->winId(), rootWindow, NET::Properties(), NET::WM2DesktopFileName);
info.setDesktopFileName("peony");
}
} else {
#ifdef KY_SDK_WAYLANDHELPER
m_window_helper->removeTitleBar();
#endif
}
startMonitorThumbnailForbidStatus();
auto start_cost_time = QDateTime::currentMSecsSinceEpoch()- PeonyApplication::peony_start_time;
qDebug() << "peony start end in main-window time:" <setCurrentSortColumn(this->getCurrentSortColumn());
this->setCurrentSortOrder(this->getCurrentSortOrder());
}
});
m_is_blur_window = true;
#ifdef KY_SDK_WAYLANDHELPER
m_window_helper->setBlurEffect(QRegion());
#else
KWindowEffects::enableBlurBehind(winId(), true);
#endif
#ifdef KY_SDK_DATE
connect(Peony::GlobalSettings::getInstance(),
&Peony::GlobalSettings::updateShortDataFormat,
this,
&MainWindow::updateDateFormat);
#endif
connect(Peony::GlobalSettings::getInstance(), &Peony::GlobalSettings::valueChanged, this, [this](const QString &key){
if (key == SHOW_CREATE_TIME || key == SHOW_RELATIVE_DATE) {
this->refresh();
}
});
connect(this, &MainWindow::setSelection, [=](QStringList selectionUris){
QTimer::singleShot(500, [=] {
getCurrentPage()->getView()->setSelections(selectionUris);
getCurrentPage()->getView()->scrollToSelection(selectionUris.first());
});
});
}
MainWindow::~MainWindow()
{
blur_window_list.removeOne(this);
//fix bug 40913, when window is maximazed, not update size
if (last_resize_window == this && !isMaximized()) {
auto settings = Peony::GlobalSettings::getInstance();
settings->setValue(DEFAULT_WINDOW_WIDTH, this->size().width());
settings->setValue(DEFAULT_WINDOW_HEIGHT, this->size().height());
last_resize_window = nullptr;
}
}
void MainWindow::updateDateFormat(QString dateFormat)
{
//update date and time show format, task #101605
qDebug() << "sdk format signal:"<refresh();
m_date_format = dateFormat;
}
}
void MainWindow::createVirtualTabAndSearch()
{
QString virtualUri = "idm:///New Intelligent Space";
this->addNewTabs(QStringList() << virtualUri);
qDebug() << "=======updateSearchBar";
m_tab->updateCreateVirtualTabShow();
m_header_bar->setSearchBarFocus();
m_last_key.clear();
//m_tab->updateSearchBar(true);
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::MouseMove) {
auto me = static_cast(event);
auto widget = this->childAt(me->pos());
if (!widget) {
// set default sidebar width flag
m_should_save_side_bar_width = true;
}
}
if (event->type() == QEvent::MouseButtonRelease) {
if (m_should_save_side_bar_width) {
// real set default side bar width
auto settings = Peony::GlobalSettings::getInstance();
settings->setValue(DEFAULT_SIDEBAR_WIDTH, m_side_bar->width());
qDebug() << "main window set DEFAULT_SIDEBAR_WIDTH:" << m_side_bar->width();
}
m_should_save_side_bar_width = false;
}
#ifdef KY_SDK_WAYLANDHELPER
if (event->type() == QEvent::ActivationChange) {
bool isActive = this->isActiveWindow();
m_window_helper->setBlurEffect(QRegion(), 0, isActive);
}
#endif
//通过事件过滤拦截器 QMouseEvent中的QEvent::MouseButtonDblClick识别鼠标事件
if (event->type() == QEvent::MouseButtonDblClick && watched == m_tab->tabBar()) {
QMouseEvent *mouseEvent = static_cast(event);
int index = m_tab->tabBar()->tabAt(mouseEvent->pos());
if (index == -1) {
bool tablet = Peony::GlobalSettings::getInstance()->getValue(TABLET_MODE).toBool();
if (!tablet) {
if (mouseEvent->button() == Qt::LeftButton) {
maximizeOrRestore();
} else {
qDebug() << "RightButton or MiddleButton click tabBar";
}
}
}
return false;
}
return false;
}
QSize MainWindow::sizeHint() const
{
auto screenSize = QApplication::primaryScreen()->size();
QSize windowSize;
windowSize.setWidth(screenSize.width()*2/3);
windowSize.setHeight(screenSize.height()*4/5);
QSize defaultSize(Peony::GlobalSettings::getInstance()->getValue(DEFAULT_WINDOW_WIDTH).toInt(),
Peony::GlobalSettings::getInstance()->getValue(DEFAULT_WINDOW_HEIGHT).toInt());
if (!defaultSize.isValid())
return windowSize;
int width = qMin(defaultSize.width(), screenSize.width());
int height = qMin(defaultSize.height(), screenSize.height());
//return screenSize*2/3;
//qreal dpr = qApp->devicePixelRatio();
return QSize(width, height);
}
Peony::FMWindowIface *MainWindow::create(const QString &uri)
{
auto window = new MainWindow(uri);
connect(window, &MainWindow::locationChanged, this, [=](){
if (currentViewSupportZoom())
window->setCurrentViewZoomLevel(this->currentViewZoomLevel());
});
return window;
}
Peony::FMWindowIface *MainWindow::create(const QStringList &uris)
{
if (uris.isEmpty()) {
auto window = new MainWindow;
if (currentViewSupportZoom())
window->setCurrentViewZoomLevel(this->currentViewZoomLevel());
return window;
}
auto uri = uris.first();
auto l = uris;
l.removeAt(0);
auto window = new MainWindow(uri);
if (currentViewSupportZoom())
window->setCurrentViewZoomLevel(this->currentViewZoomLevel());
window->addNewTabs(l);
return window;
}
Peony::FMWindowIface *MainWindow::createWithZoomLevel(const QString &uri, int zoomLevel)
{
auto window = new MainWindow(uri);
if (currentViewSupportZoom())
window->setCurrentViewZoomLevel(zoomLevel);
return window;
}
Peony::FMWindowIface *MainWindow::createWithZoomLevel(const QStringList &uris, int zoomLevel)
{
if (uris.isEmpty()) {
auto window = new MainWindow;
if (currentViewSupportZoom())
window->setCurrentViewZoomLevel(zoomLevel);
return window;
}
auto uri = uris.first();
auto l = uris;
l.removeAt(0);
auto window = new MainWindow(uri);
if (currentViewSupportZoom())
window->setCurrentViewZoomLevel(zoomLevel);
window->addNewTabs(l);
return window;
}
Peony::FMWindowFactory *MainWindow::getFactory()
{
return nullptr;//MainWindowFactory::getInstance();
}
Peony::DirectoryViewContainer *MainWindow::getCurrentPage()
{
return m_tab->currentPage();
}
void MainWindow::checkSettings()
{
if (QGSettings::isSchemaInstalled("org.ukui.style"))
{
//font monitor
QGSettings *fontSetting = new QGSettings(FONT_SETTINGS, QByteArray(), this);
connect(fontSetting, &QGSettings::changed, this, [=](const QString &key){
qDebug() << "fontSetting changed:" << key;
if (key == "systemFont" || key == "systemFontSize") {
QFont font = this->font();
for(auto widget : qApp->allWidgets())
widget->setFont(font);
}
//use qApp set window icon, task#29435
/*else if ("iconThemeName" == key) {
setWindowIcon(QIcon::fromTheme("system-file-manager"));
}*/
});
}
}
void MainWindow::setShortCuts()
{
if (!m_shortcuts_set) {
//stop loading action
QAction *stopLoadingAction = new QAction(this);
stopLoadingAction->setShortcut(QKeySequence(Qt::Key_Escape));
addAction(stopLoadingAction);
connect(stopLoadingAction, &QAction::triggered, this, &MainWindow::forceStopLoading);
//show hidden action
QAction *showHiddenAction = new QAction(this);
showHiddenAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_H));
showHiddenAction->setCheckable(true);
addAction(showHiddenAction);
connect(showHiddenAction, &QAction::triggered, this, [=]() {
//qDebug() << "show hidden";
this->setShowHidden(!getWindowShowHidden());
});
auto undoAction = new QAction(QIcon::fromTheme("edit-undo-symbolic"), tr("Undo"), this);
undoAction->setShortcut(QKeySequence::Undo);
addAction(undoAction);
connect(undoAction, &QAction::triggered, [=]() {
Peony::FileOperationManager::getInstance()->undo();
});
auto redoAction = new QAction(QIcon::fromTheme("edit-redo-symbolic"), tr("Redo"), this);
redoAction->setShortcut(QKeySequence::Redo);
addAction(redoAction);
connect(redoAction, &QAction::triggered, [=]() {
Peony::FileOperationManager::getInstance()->redo();
});
//add CTRL+D for delete operation
auto trashAction = new QAction(this);
trashAction->setShortcuts(QList()<getValue(ENABLE_SHORTCUT_KEYS).toBool()) {
return ;
}
auto currentUri = getCurrentUri();
if(currentUri.startsWith("search://")){
currentUri = Peony::FileUtils::getActualDirFromSearchUri(currentUri);
}
if (currentUri.startsWith("favorite://") || currentUri == "filesafe:///"
|| currentUri.startsWith("kmre://") || currentUri.startsWith("kydroid://")
|| currentUri.startsWith("idm://"))
return;
auto uris = this->getCurrentSelections();
QString desktopPath = "file://" + QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString desktopUri = Peony::FileUtils::getEncodedUri(desktopPath);
QString homeUri = "file://" + QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
QString documentPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
QString musicPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::MusicLocation));
QString moviesPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::MoviesLocation));
QString picturespPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
QString downloadPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
if (currentUri.contains(desktopUri)) {
if (MANAGER_CONTROL->containsWhitelistApp(uris)) {
return;
}
}
if (!uris.isEmpty() && !uris.contains(desktopUri) && !uris.contains(homeUri) && !uris.contains(documentPath) && !uris.contains(musicPath)
&& !uris.contains(moviesPath) && !uris.contains(picturespPath) && !uris.contains(downloadPath)) {
bool canTrash = true;
for (auto uri : uris) {
if(Peony::FileUtils::isLongNameFileOfNotDel2Trash(uri)){/* 在家目录/下载/扩展目录下存放的长文件名文件使用永久删除,link bug#188864 */
canTrash = false;
break;
}
}
bool isTrash = this->getCurrentUri() == "trash:///";
if (!isTrash && canTrash) {
Peony::FileOperationUtils::trash(uris, true, getCurrentUri().startsWith("search://"));
} else {
Peony::FileOperationUtils::executeRemoveActionWithDialog(uris);
}
}
});
addAction(trashAction);
auto deleteAction = new QAction(this);
deleteAction->setShortcuts(QList()<getValue(ENABLE_SHORTCUT_KEYS).toBool()) {
return ;
}
auto currentUri = getCurrentUri();
if(currentUri.startsWith("search://")){
currentUri = Peony::FileUtils::getActualDirFromSearchUri(currentUri);
}
if (currentUri == "filesafe:///" || currentUri.startsWith("kmre://") || currentUri.startsWith("kydroid://") || currentUri.startsWith("idm://"))
return;
auto uris = this->getCurrentSelections();
QString desktopPath = "file://" + QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString documentPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
QString musicPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::MusicLocation));
QString moviesPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::MoviesLocation));
QString picturespPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
QString downloadPath = Peony::FileUtils::getEncodedUri("file://" + QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
QString desktopUri = Peony::FileUtils::getEncodedUri(desktopPath);
QString homeUri = "file://" + QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
if (currentUri.contains(desktopUri)) {
if (MANAGER_CONTROL->containsWhitelistApp(uris)) {
return;
}
}
if (! uris.contains(desktopUri) && !uris.contains(homeUri) && !uris.contains(documentPath) && !uris.contains(musicPath)
&& !uris.contains(moviesPath) && !uris.contains(picturespPath) && !uris.contains(downloadPath)) {
Peony::FileOperationUtils::executeRemoveActionWithDialog(uris);
}
});
auto searchAction = new QAction(this);
//UI improve bug#197559, add Ctrl + E to active search status, and not quit when trigger again
searchAction->setShortcuts(QList()<startEdit(m_is_search);
}
});
addAction(searchAction);
//F4 or Alt+D, change to address
auto locationAction = new QAction(this);
locationAction->setShortcuts(QList()<startEdit();
});
addAction(locationAction);
auto newWindowAction = new QAction(this);
newWindowAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));
connect(newWindowAction, &QAction::triggered, this, [=]() {
MainWindow *newWindow = new MainWindow(getCurrentUri());
newWindow->show();
});
addAction(newWindowAction);
auto closeWindowAction = new QAction(this);
closeWindowAction->setShortcuts(QList()<close();
});
addAction(closeWindowAction);
auto aboutAction = new QAction(this);
aboutAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F2));
connect(aboutAction, &QAction::triggered, this, [=]() {
PeonyApplication::about();
});
addAction(aboutAction);
auto newTabAction = new QAction(this);
newTabAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T));
connect(newTabAction, &QAction::triggered, this, [=]() {
this->addNewTabs(QStringList()<getCurrentUri());
});
addAction(newTabAction);
auto closeTabAction = new QAction(this);
closeTabAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W));
connect(closeTabAction, &QAction::triggered, this, [=]() {
if (m_tab->count() <= 1) {
this->close();
} else {
m_tab->removeTab(m_tab->currentIndex());
}
});
addAction(closeTabAction);
auto nextTabAction = new QAction(this);
nextTabAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Tab));
connect(nextTabAction, &QAction::triggered, this, [=]() {
int currentIndex = m_tab->currentIndex();
if (currentIndex + 1 < m_tab->count()) {
m_tab->setCurrentIndex(currentIndex + 1);
} else {
m_tab->setCurrentIndex(0);
}
});
addAction(nextTabAction);
auto previousTabAction = new QAction(this);
previousTabAction->setShortcuts(QList()<currentIndex();
if (currentIndex > 0) {
m_tab->setCurrentIndex(currentIndex - 1);
} else {
m_tab->setCurrentIndex(m_tab->count() - 1);
}
});
addAction(previousTabAction);
auto newFolderAction = new QAction(this);
newFolderAction->setShortcuts(QList()<setShortcuts(QList()< 0)
{
uris<create(uris);
//Peony::PropertiesWindow *w = new Peony::PropertiesWindow(uris);
w->setAttribute(Qt::WA_DeleteOnClose);
Peony::PropertiesWindowFactoryPluginManager::getInstance()->show();
//w->show();
});
addAction(propertiesWindowAction);
auto helpAction = new QAction(this);
helpAction->setShortcut(QKeySequence(Qt::Key_F1));
connect(helpAction, &QAction::triggered, this, [=]() {
PeonyApplication::help();
});
addAction(helpAction);
auto maxAction = new QAction(this);
maxAction->setShortcut(QKeySequence(Qt::Key_F11));
connect(maxAction, &QAction::triggered, this, [=]() {
//showFullScreen has some issue, change to showMaximized, fix #20043
m_header_bar->cancelEdit();
maximizeOrRestore();
});
addAction(maxAction);
auto previewPageAction = new QAction(this);
connect(this,&MainWindow::tabletModeChanged,previewPageAction,[=](bool isTabletMode){
if(isTabletMode){
previewPageAction->setEnabled(false);
m_header_bar->updatePreviewStatus(false);
}else{
previewPageAction->setEnabled(true);
}
});
previewPageAction->setShortcuts(QList()<getTriggeredPreviewPage();
m_header_bar->updatePreviewStatus(!triggered);
});
addAction(previewPageAction);
auto refreshWindowAction = new QAction(this);
refreshWindowAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
connect(refreshWindowAction, &QAction::triggered, this, [=]() {
this->refresh();
});
addAction(refreshWindowAction);
auto listToIconViewAction = new QAction(this);
listToIconViewAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_1));
connect(listToIconViewAction, &QAction::triggered, this, [=]() {
this->beginSwitchView(QString("Icon View"));
});
addAction(listToIconViewAction);
auto iconToListViewAction = new QAction(this);
iconToListViewAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_2));
connect(iconToListViewAction, &QAction::triggered, this, [=]() {
this->beginSwitchView(QString("List View"));
});
addAction(iconToListViewAction);
auto reverseSelectAction = new QAction(this);
reverseSelectAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_L));
connect(reverseSelectAction, &QAction::triggered, this, [=]() {
this->getCurrentPage()->getView()->invertSelections();
});
addAction(reverseSelectAction);
auto remodelViewAction = new QAction(this);
remodelViewAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_0));
connect(remodelViewAction, &QAction::triggered, this, [=]() {
auto view = this->getCurrentPage()->getView();
auto viewFactory = Peony::DirectoryViewFactoryManager2::getInstance();
if (!viewFactory) {
qCritical() << "can not get view factory for" << view->viewId();
return;
}
int defaultZoomLevel = viewFactory->getFactory(view->viewId())->zoom_level_hint();
qDebug() << QString("View Type: %1 defaultZoomLevel: %2").arg(view->viewId()).arg(defaultZoomLevel);
this->getCurrentPage()->setZoomLevelRequest(defaultZoomLevel);
});
addAction(remodelViewAction);
auto enlargViewAction = new QAction(this);
enlargViewAction->setShortcut(QKeySequence::ZoomIn);
connect(enlargViewAction, &QAction::triggered, this, [=]() {
int defaultZoomLevel = this->currentViewZoomLevel();
if(defaultZoomLevel <= 95){ defaultZoomLevel+=5; }
for (int i = 0; i < 5; i++) {
this->getCurrentPage()->setZoomLevelRequest(defaultZoomLevel);
}
});
addAction(enlargViewAction);
auto shrinkViewAction = new QAction(this);
shrinkViewAction->setShortcut(QKeySequence::ZoomOut);
connect(shrinkViewAction, &QAction::triggered, this, [=]() {
int defaultZoomLevel = this->currentViewZoomLevel();
if (defaultZoomLevel >= 5) {
defaultZoomLevel-=5;
} else {
defaultZoomLevel = 0;
}
this->getCurrentPage()->setZoomLevelRequest(defaultZoomLevel);
});
addAction(shrinkViewAction);
auto quitAllAction = new QAction(this);
quitAllAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
connect(quitAllAction, &QAction::triggered, this, [=]() {
QProcess p(0);
p.start("/usr/bin/peony", QStringList()<<"-q");
p.waitForStarted();
p.waitForFinished();
});
addAction(quitAllAction);
auto refreshAction = new QAction(this);
refreshAction->setShortcut(Qt::Key_F5);
connect(refreshAction, &QAction::triggered, this, [=]() {
this->refresh();
});
addAction(refreshAction);
//select all files in view, fix bug#115442
auto *selectAllAction = new QAction(this);
selectAllAction->setShortcut(QKeySequence::SelectAll);
connect(selectAllAction, &QAction::triggered, this, [=]() {
if (! Peony::GlobalSettings::getInstance()->getValue(ENABLE_SHORTCUT_KEYS).toBool()) {
return ;
}
if (this->getCurrentPage()->getView())
{
/// note: 通过getAllFileUris设置的全选效率过低,如果增加接口则会导致二进制兼容性问题
/// 所以这里使用现有的反选接口实现高效的全选,这个方法在mainwindow中也有用到
//auto allFiles = this->getCurrentPage()->getView()->getAllFileUris();
//this->getCurrentPage()->getView()->setSelections(allFiles);
this->getCurrentPage()->getView()->setSelections(QStringList());
this->getCurrentPage()->getView()->invertSelections();
}
});
addAction(selectAllAction);
//file operations
auto *copyAction = new QAction(this);
copyAction->setShortcut(QKeySequence::Copy);
connect(copyAction, &QAction::triggered, [=]() {
if (! Peony::GlobalSettings::getInstance()->getValue(ENABLE_SHORTCUT_KEYS).toBool()) {
return ;
}
bool is_recent = false;
QStringList currentSelections = this->getCurrentSelections();
if (!currentSelections.isEmpty())
{
// if (currentSelections.first().startsWith("trash://", Qt::CaseInsensitive)) {
// return ;
// }
if (currentSelections.first().startsWith("recent://", Qt::CaseInsensitive)) {
is_recent = true;
}
if (currentSelections.first().startsWith("favorite://", Qt::CaseInsensitive)) {
return ;
}
}
else
return;
QStringList selections;
if (is_recent)
{
for(auto uri: currentSelections)
{
uri = Peony::FileUtils::getTargetUri(uri);
selections << uri;
}
}
else{
selections = currentSelections;
}
Peony::ClipboardUtils::setClipboardFiles(selections, false);
});
addAction(copyAction);
auto *pasteAction = new QAction(this);
pasteAction->setShortcut(QKeySequence::Paste);
connect(pasteAction, &QAction::triggered, [=]() {
if (! Peony::GlobalSettings::getInstance()->getValue(ENABLE_SHORTCUT_KEYS).toBool()) {
return ;
}
auto currentUri = getCurrentUri();
if (currentUri.startsWith("trash://") || currentUri.startsWith("recent://")
|| currentUri.startsWith("computer://") || currentUri.startsWith("favorite://")
|| currentUri.startsWith("search://") || currentUri == "filesafe:///"
|| currentUri.startsWith("burn://"))
{
/* Add hint information,link to bug#107640. */
QMessageBox::warning(this, tr("warn"), tr("This operation is not supported."));
return;
}
//fix bug#183268, not allow paste in mtp, gphoto2 path or can not write path
auto info = Peony::FileInfo::fromUri(currentUri);
//comment to fix bug#191108, huawei phone can paste file success
if (!info->canWrite()) {
QString fileSystem = info.get()->fileSystemType();
if (fileSystem.isEmpty()) {
fileSystem = Peony::FileUtils::getFsTypeFromFile(info.get()->uri());
}
if (!fileSystem.contains("udf")) {
return;
}
}
// if (!info->canWrite() /*|| currentUri.startsWith("mtp://")
// || currentUri.startsWith("gphoto2://")*/) {
// return;
// }
if (Peony::ClipboardUtils::isClipboardHasFiles()) {
//FIXME: how about duplicated copy?
//FIXME: how to deal with a failed move?
auto op = Peony::ClipboardUtils::pasteClipboardFiles(this->getCurrentUri());
if (op) {
connect(op, &Peony::FileOperation::operationFinished, this, [=](){
auto opInfo = op->getOperationInfo();
auto targetUirs = opInfo->dests();
//fix bug#196528, selection files icon not update issue
QTimer::singleShot(300, this, [=](){
setCurrentSelectionUris(targetUirs);
});
}, Qt::BlockingQueuedConnection);
}
else{
//fix paste file in old path not update issue, link to bug#71627
this->getCurrentPage()->getView()->repaintView();
}
}
});
addAction(pasteAction);
auto *cutAction = new QAction(this);
cutAction->setShortcut(QKeySequence::Cut);
connect(cutAction, &QAction::triggered, [=]() {
if (! Peony::GlobalSettings::getInstance()->getValue(ENABLE_SHORTCUT_KEYS).toBool()) {
return ;
}
QStringList currentSelections = this->getCurrentSelections();
if (!currentSelections.isEmpty()) {
// if (currentSelections.first().startsWith("trash://", Qt::CaseInsensitive)) {
// return ;
// }
if (currentSelections.first().startsWith("recent://", Qt::CaseInsensitive)) {
return ;
}
if (currentSelections.first().startsWith("favorite://", Qt::CaseInsensitive)) {
return ;
}
QString currentUri = getCurrentUri();
if(currentUri.startsWith("search://")){
auto selections = this->getCurrentSelections();
bool canCut = Peony::FileUtils::isSearchFilesParentWriteable(selections, getCurrentUri().startsWith("search://"));
if(!canCut){
return;
}
}else{
auto info = Peony::FileInfo::fromUri(currentUri);
if (!info->canWrite()) {
return;
}
}
QString desktopPath = "file://" + QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString desktopUri = Peony::FileUtils::getEncodedUri(desktopPath);
QString homeUri = "file://" + QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
if (!currentSelections.contains(desktopUri) && !currentSelections.contains(homeUri))
{
Peony::ClipboardUtils::setClipboardFiles(currentSelections, true, getCurrentUri().startsWith("search://"));
this->getCurrentPage()->getView()->repaintView();
}
}
});
addAction(cutAction);
m_shortcuts_set = true;
}
}
void MainWindow::updateTabPageTitle()
{
m_tab->updateTabPageTitle();
//FIXME: replace BLOCKING api in ui thread.
auto curUri = getCurrentUri();
auto show = Peony::FileUtils::getFileDisplayName(curUri);
QString title = show;// + "-" + tr("File Manager");
if (curUri.startsWith("search:///"))
title = tr("Search");
if (title.length() <= 0)
title = tr("File Manager");
//qDebug() << "updateTabPageTitle:" <hasError())
return;
auto opInfo = op->getOperationInfo();
//auto targetUri = opInfo->target();
//set a short time delay, fix bug#86070, select two folders
QTimer::singleShot(300, this, [=](){
this->getCurrentPage()->getView()->clearIndexWidget();
this->getCurrentPage()->getView()->setSelections(QStringList());
this->editUri(opInfo->target());
});
}, Qt::BlockingQueuedConnection);
// QTimer::singleShot(500, this, [=]() {
// this->getCurrentPage()->getView()->scrollToSelection(targetUri);
// this->editUri(targetUri);
// });
}
void MainWindow::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Backspace)
{
auto uri = Peony::FileUtils::getParentUri(getCurrentUri());
//qDebug() << "goUp Action" << getCurrentUri() << uri;
if (uri.isNull())
return;
m_tab->goToUri(uri, true, true);
}
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)
{
auto selections = this->getCurrentSelections();
//if select only one item, let view to process
if (selections.count() > 1)
{
QString currentUri = this->getCurrentUri();
if(currentUri == "filesafe:///") {
return ;
}
QStringList files;
QStringList dirs;
for (auto uri : selections) {
auto info = Peony::FileInfo::fromUri(uri);
if (info->isDir() || info->isVolume()) {
dirs<getValue(SHOW_IN_NEW_WINDOW).toBool();
for (auto uri : dirs) {
if (check) {
auto newWindow = dynamic_cast(create(uri));
newWindow->setAttribute(Qt::WA_DeleteOnClose);
newWindow->show();
} else {
m_tab->addPage(uri);
}
}
if (!files.isEmpty()) {
Peony::FileLaunchManager::openFilesByDefaultApplications(files);
}
}
}
return QMainWindow::keyPressEvent(e);
}
void MainWindow::showEvent(QShowEvent *event)
{
if (!m_tab) {
initUIRequest();
}
QMainWindow::showEvent(event);
}
const QString MainWindow::getCurrentUri()
{
return m_tab->getCurrentUri();
}
const QStringList MainWindow::getCurrentSelections()
{
return m_tab->getCurrentSelections();
}
const QStringList MainWindow::getCurrentAllFileUris()
{
return m_tab->getAllFileUris();
}
Qt::SortOrder MainWindow::getCurrentSortOrder()
{
return m_tab->getSortOrder();
}
int MainWindow::getCurrentSortColumn()
{
return m_tab->getSortType();
}
bool MainWindow::getWindowShowHidden()
{
auto settings = Peony::GlobalSettings::getInstance();
if (settings->getValue(USE_GLOBAL_DEFAULT_SORTING).toBool()) {
return settings->getValue(SHOW_HIDDEN_PREFERENCE).toBool();
} else {
auto uri = getCurrentUri();
auto metaInfo = Peony::FileMetaInfo::fromUri(uri);
if (metaInfo) {
return metaInfo->getMetaInfoVariant(SHOW_HIDDEN_PREFERENCE).isValid()? metaInfo->getMetaInfoVariant(SHOW_HIDDEN_PREFERENCE).toBool(): false;
} else {
qDebug()<<"can not get file meta info"<getValue(SHOW_HIDDEN_PREFERENCE).toBool();
}
}
}
bool MainWindow::getWindowUseDefaultNameSortOrder()
{
auto settings = Peony::GlobalSettings::getInstance();
if (settings->getValue(USE_GLOBAL_DEFAULT_SORTING).toBool()) {
return settings->getValue(SORT_CHINESE_FIRST).isValid()? settings->getValue(SORT_CHINESE_FIRST).toBool(): true;
} else {
auto uri = getCurrentUri();
auto metaInfo = Peony::FileMetaInfo::fromUri(uri);
if (metaInfo) {
return metaInfo->getMetaInfoVariant(SORT_CHINESE_FIRST).isValid()? metaInfo->getMetaInfoVariant(SORT_CHINESE_FIRST).toBool(): true;
} else {
qDebug()<<"can not get file meta info"<getValue(SORT_CHINESE_FIRST).isValid()? settings->getValue(SORT_CHINESE_FIRST).toBool(): true;
}
}
}
bool MainWindow::getWindowSortFolderFirst()
{
auto settings = Peony::GlobalSettings::getInstance();
if (settings->getValue(USE_GLOBAL_DEFAULT_SORTING).toBool()) {
return settings->getValue(SORT_FOLDER_FIRST).isValid()? settings->getValue(SORT_FOLDER_FIRST).toBool(): true;
} else {
auto uri = getCurrentUri();
auto metaInfo = Peony::FileMetaInfo::fromUri(uri);
if (metaInfo) {
return metaInfo->getMetaInfoVariant(SORT_FOLDER_FIRST).isValid()? metaInfo->getMetaInfoVariant(SORT_FOLDER_FIRST).toBool(): true;
} else {
qDebug()<<"can not get file meta info"<getValue(SORT_FOLDER_FIRST).isValid()? settings->getValue(SORT_FOLDER_FIRST).toBool(): true;
}
}
}
int MainWindow::currentViewZoomLevel()
{
if (getCurrentPage()) {
if (auto view = getCurrentPage()->getView()) {
return view->currentZoomLevel();
}
}
int defaultZoomLevel = Peony::GlobalSettings::getInstance()->getValue(DEFAULT_VIEW_ZOOM_LEVEL).toInt();
if (defaultZoomLevel >= 0 && defaultZoomLevel <= 100) {
return defaultZoomLevel;
}
return m_tab->m_status_bar->m_slider->value();
}
bool MainWindow::currentViewSupportZoom()
{
if (getCurrentPage()) {
if (auto view = getCurrentPage()->getView()) {
return view->supportZoom();
}
}
return m_tab->m_status_bar->m_slider->isEnabled();
}
void MainWindow::maximizeOrRestore()
{
if (getCurrentPage()) {
if (auto view = getCurrentPage()->getView()) {
QStringList uris = view->getSelections();
view->clearIndexWidget();
view->setSelections(uris);
}
}
if (!this->isMaximized()) {
this->showMaximized();
} else {
this->showNormal();
}
//maybe not need update icons? comment to try fix bug#77966
//m_header_bar->updateIcons();
m_header_bar->updateMaximizeState();
}
void MainWindow::syncControlsLocation(const QString &uri)
{
m_tab->goToUri(uri, false, false);
}
void MainWindow::updateHeaderBar()
{
m_header_bar->setLocation(getCurrentUri());
m_header_bar->updateIcons();
//fix bug#82685
m_header_bar->updateSortTypeEnable();
//fix bug#66336, 83711
m_header_bar->updateViewTypeEnable();
//m_status_bar->update();
m_header_bar->updatePreviewPageVisible();
}
void MainWindow::updateWindowIcon()
{
auto currentUri = getCurrentUri();
if (currentUri.startsWith("trash://"))
{
QIcon icon = QIcon::fromTheme("user-trash");
qApp->setWindowIcon(icon);
}
else if (currentUri.startsWith("computer://"))
{
QIcon icon = QIcon::fromTheme("computer");
qApp->setWindowIcon(icon);
}
else
{
QIcon icon = QIcon::fromTheme("system-file-manager");
qApp->setWindowIcon(icon);
}
}
void MainWindow::goToUri(const QString &uri, bool addHistory, bool force)
{
if (!getCurrentPage() || !getCurrentPage()->getView()) {
return;
}
auto viewId = this->getCurrentPage()->getView()->viewId();
if (QString::compare(viewId, "Icon View", Qt::CaseSensitive) == 0) {
//FIXME: 判空
auto iface2 = Peony::DirectoryViewHelper::globalInstance()->getViewIface2ByDirectoryViewWidget(getCurrentPage()->getView());
if (iface2) {
iface2->doMultiSelect(false);
}
}
QUrl url(uri);
auto realUri = uri;
if (uri == "computer:///ukui-data-volume") {
realUri = "file:///data";
}
//story 28545, improve data block solution, when has no user file in /data, go to usershare
if ((uri == "file:///data" || realUri == "file:///data") &&
Peony::FileUtils::isFileExsit("file:///data/usershare") &&
! Peony::FileUtils::isDataBlockHasUserFile()) {
realUri = "file:///data/usershare";
}
//process open symbolic link
auto info = Peony::FileInfo::fromUri(uri);
if (info->isSymbolLink() && info->symlinkTarget().length() >0 &&
(uri.startsWith("file://") || uri.startsWith("favorite://")))
realUri = "file://" + info->symlinkTarget();
//try to fix bug#174666, part phone mtp mode access wrong issue
if (url.scheme().isEmpty() && ! uri.startsWith("mtp://") && ! uri.startsWith("gphoto2://")) {
qDebug() << "transform special uri:"<closeSearch();
}
if (!m_tab->handleEditConditionSwitchPath()) {
return;
}
m_tab->handleSwitchModeAndShow(realUri);
if (getCurrentUri() == realUri) {
if (!force) {
refresh();
return;
}
}
locationChangeStart();
m_tab->goToUri(realUri, addHistory, force);
m_header_bar->setLocation(uri);
// m_label_box->clearSelection();
//Q_EMIT m_label_box->leftClickOnBlank();
}
void MainWindow::updateSearch(const QString &uri, const QString &key, bool updateKey)
{
qDebug() << "updateSearch:" <enableSearchBar(key.length() != 0);
if (m_last_search_path == "" || ! Peony::FileUtils::isSamePath(uri, m_last_search_path))
{
//qDebug() << "updateSearch:" <clearAllMapsCount();
}
if (updateKey)
{
needUpdate = true;
m_last_key = key;
}
if (needUpdate)
{
//qDebug() << "updateSearch needUpdate:" <m_status_bar->updateSearchProgress(false);
m_tab->updateFilterContent("");
m_searching = false;
}
else
{
bool isSearchEngine = true;
const QByteArray id(UKUI_SEARCH_SCHEMAS);
if (QGSettings::isSchemaInstalled(id)) {
QGSettings *searchSettings = new QGSettings(id, QByteArray(), this);
if (!searchSettings || !searchSettings->keys().contains(SEARCH_METHOD_KEY)) {
isSearchEngine = false;
}
} else {
isSearchEngine = false;
}
if (!m_last_search_path.startsWith("file:///") && !m_last_search_path.startsWith("computer:///")) {
isSearchEngine = false;
}
QString targetUri = m_last_search_path;
if (!targetUri.startsWith("search://")) {
targetUri = Peony::SearchVFSUriParser::parseSearchKey(m_last_search_path,
m_last_key, true, false, "", true);
targetUri = Peony::SearchVFSUriParser::addSearchKey(targetUri, isSearchEngine);
}
//qDebug() << "updateSearch targetUri:" <m_status_bar->updateSearchProgress(true);
m_tab->updateFilterContent(m_last_key);
m_searching = true;
}
}
}
void MainWindow::addNewTabs(const QStringList &uris)
{
//fix search path add new tab,page title show abnormal issue
if (uris.count() == 1)
{
m_tab->addPage(uris.first(), true);
return;
}
for (auto uri : uris) {
m_tab->addPage(uri, false);
}
}
void MainWindow::beginSwitchView(const QString &viewId)
{
//not allow change to other view when in computer, link to bug#83711
if (getCurrentUri() == "computer:///")
return;
if (!getCurrentPage() || !getCurrentPage()->getView())
return;
auto selection = getCurrentSelections();
// int sortType = getCurrentSortColumn();
// Qt::SortOrder sortOrder = getCurrentSortOrder();
m_tab->switchViewType(viewId);
if (m_tab->currentPage()->getView()->supportZoom()) {
// save zoom level
Peony::GlobalSettings::getInstance()->setValue(DEFAULT_VIEW_ZOOM_LEVEL, currentViewZoomLevel());
}
m_tab->setCurrentSelections(selection);
bool supportZoom = m_tab->currentPage()->getView()->supportZoom();
m_tab->m_status_bar->m_slider->setEnabled(supportZoom);
// m_tab->m_status_bar->m_slider->setVisible(supportZoom);
//fix slider value not update issue
int zoomLevel = currentViewZoomLevel();
setCurrentViewZoomLevel(zoomLevel);
m_tab->currentPage()->getView()->setCurrentZoomLevel(zoomLevel);
}
void MainWindow::refresh()
{
if (getCurrentPage()) {
if (getCurrentPage()->getView()) {
this->getCurrentPage()->getView()->setDirectoryUri(getCurrentUri());
}
}
locationChangeStart();
m_tab->refresh();
//fix refresh clear copy files issue, link to bug#109247
if (Peony::ClipboardUtils::isPeonyFilesBeCut())
Peony::ClipboardUtils::clearClipboard();/* Refresh clear cut status */
//goToUri(getCurrentUri(), false, true);
}
void MainWindow::advanceSearch()
{
qDebug()<<"advanceSearch clicked";
initAdvancePage();
}
void MainWindow::clearRecord()
{
//qDebug()<<"clearRecord clicked";
// m_search_bar->clearSearchRecord();
// m_clear_record->setDisabled(true);
}
void MainWindow::searchFilter(QString target_path, QString keyWord, bool search_file_name, bool search_content)
{
// auto targetUri = SearchVFSUriParser::parseSearchKey(target_path, keyWord, search_file_name, search_content);
// //qDebug()<<"targeturi:"<goToUri(targetUri, true);
}
void MainWindow::filterUpdate(int type_index, int time_index, int size_index)
{
//qDebug()<<"filterUpdate:";
//m_tab->getActivePage()->setSortFilter(type_index, time_index, size_index);
}
void MainWindow::setLabelNameFilter(QString name)
{
if (!getCurrentPage()) {
return;
}
//update filter flag
if (name == "")
m_filter_working = false;
else
m_filter_working = true;
//m_header_bar->updateHeaderState();
getCurrentPage()->setFilterLabelConditions(name);
}
void MainWindow::setShowHidden(bool showHidden)
{
if (!getCurrentPage()) {
return;
}
getCurrentPage()->setShowHidden(showHidden);
//显示隐藏文件,更新项目个数
Q_EMIT m_tab->updateItemsNum();
}
void MainWindow::setShowFileExtensions(bool checked)
{
if (!getCurrentPage()) {
return;
}
getCurrentPage()->setShowFileExtensions(checked);
}
void MainWindow::setUseDefaultNameSortOrder(bool use)
{
if (!getCurrentPage()) {
return;
}
getCurrentPage()->setUseDefaultNameSortOrder(use);
}
void MainWindow::setSortFolderFirst(bool set)
{
if (!getCurrentPage()) {
return;
}
getCurrentPage()->setSortFolderFirst(set);
}
void MainWindow::forceStopLoading()
{
m_tab->stopLoading();
//Key_escape also use as cancel
if (Peony::ClipboardUtils::isClipboardHasFiles())
{
Peony::ClipboardUtils::clearClipboard();
this->getCurrentPage()->getView()->repaintView();
}
}
void MainWindow::setCurrentSelectionUris(const QStringList &uris)
{
m_tab->setCurrentSelections(uris);
//move scrollToSelection to m_tab to try fix new unzip file show two same icon issue
//Fix me, Unknown caused reason
// if (uris.isEmpty())
// return;
// getCurrentPage()->getView()->scrollToSelection(uris.first());
}
void MainWindow::setCurrentSortOrder(Qt::SortOrder order)
{
m_tab->setSortOrder(order);
}
void MainWindow::setCurrentSortColumn(int sortColumn)
{
m_tab->setSortType(sortColumn);
}
void MainWindow::editUri(const QString &uri)
{
m_tab->editUri(uri);
}
void MainWindow::editUris(const QStringList &uris)
{
m_tab->editUris(uris);
}
void MainWindow::setCurrentViewZoomLevel(int zoomLevel)
{
if (currentViewSupportZoom())
m_tab->m_status_bar->m_slider->setValue(zoomLevel);
}
QString MainWindow::getLastSearchKey()
{
return m_last_key;
}
void MainWindow::clearLastSearchPath()
{
m_last_search_path = "";
}
void MainWindow::resizeEvent(QResizeEvent *e)
{
QMainWindow::resizeEvent(e);
//may not need update? comment to try fix bug#77966
//m_header_bar->updateMaximizeState();
//validBorder();
//update();
if (!isMaximized()) {
// set save window size flag
last_resize_window = this;
}
}
/*!
* \note
* The window has a noticeable tearing effect due to the drawing of shadow effects.
* I should consider do not painting a shadow when resizing.
*/
void MainWindow::paintEvent(QPaintEvent *e)
{
if (!m_tab) {
QPainter p(this);
p.fillRect(this->rect(), this->palette().base().color());
QRect iconRect(0, 0, 96, 96);
iconRect.moveCenter(this->rect().center());
qApp->style()->drawItemPixmap(&p, iconRect, Qt::AlignCenter, QIcon::fromTheme("system-file-manager").pixmap(QSize(96, 96)));
return;
}
bool isActive = this->isActiveWindow();
QColor color = qApp->palette().color(isActive? QPalette::Active: QPalette::Inactive, QPalette::Window);
if (!qApp->property("kcontain-secondary-normal").isNull()) {
if (isActive) {
color = qApp->property("kcontain-secondary-normal").value();
} else {
color = qApp->property("kcontain-secondary-inactive").value();
}
}
QColor colorBase =color;
auto sidebarOpacity = Peony::GlobalSettings::getInstance()->getValue(SIDEBAR_BG_OPACITY).toInt();
if (m_is_blur_window && isActive) {
colorBase.setAlphaF(sidebarOpacity/100.0);
}
auto pos = m_tab->mapTo(this, QPoint());
auto tmpRect = QRect(pos, m_tab->size());
QPainterPath deletePath;
QPainterPath tmpPath;
tmpPath.addRect(rect());
QPoint sideBarPos = m_side_bar->mapTo(this, QPoint());
QPainterPath sideBarPath;
sideBarPath.setFillRule(Qt::FillRule::WindingFill);
sideBarPath.addRect(QRect(sideBarPos, m_side_bar->size()));
sideBarPath.addRect(0,0, rect().width(), 48);
deletePath = tmpPath - sideBarPath;
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing); // 抗锯齿
p.fillPath(sideBarPath,colorBase);
QPainter painter(this);
if(m_is_first_tab)
deletePath.addRect(m_tab->x(),48,16,16);
deletePath.setFillRule(Qt::FillRule::WindingFill);
painter.fillPath(deletePath,this->palette().base());
QMainWindow::paintEvent(e);
auto brush = qvariant_cast(qApp->property("button-active"));
QPen pen;
pen.setColor(brush.color());
pen.setWidth(1);
painter.setPen(pen);
painter.drawLine(m_side_bar->rect().topRight() + QPoint(3, 0) + sideBarPos, m_side_bar->rect().bottomRight() + QPoint(3, 0) + sideBarPos);
}
void MainWindow::mousePressEvent(QMouseEvent *e)
{
//qDebug()<<"mouse pressed"<button() == Qt::LeftButton && !e->isAccepted()) {
m_is_draging = true;
m_offset = mapFromGlobal(QCursor::pos());
}
}
void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
//NOTE: when starting a X11 window move, the mouse move event
//will unreachable when draging, and after draging we could not
//get the release event correctly.
//qDebug()<<"mouse move";
QMainWindow::mouseMoveEvent(e);
// if (!m_is_draging)
// return;
// qreal dpiRatio = qApp->devicePixelRatio();
// if (QX11Info::isPlatformX11()) {
// Display *display = QX11Info::display();
// Atom netMoveResize = XInternAtom(display, "_NET_WM_MOVERESIZE", False);
// XEvent xEvent;
// const auto pos = QCursor::pos();
// memset(&xEvent, 0, sizeof(XEvent));
// xEvent.xclient.type = ClientMessage;
// xEvent.xclient.message_type = netMoveResize;
// xEvent.xclient.display = display;
// xEvent.xclient.window = this->winId();
// xEvent.xclient.format = 32;
// xEvent.xclient.data.l[0] = pos.x() * dpiRatio;
// xEvent.xclient.data.l[1] = pos.y() * dpiRatio;
// xEvent.xclient.data.l[2] = 8;
// xEvent.xclient.data.l[3] = Button1;
// xEvent.xclient.data.l[4] = 0;
// XUngrabPointer(display, CurrentTime);
// XSendEvent(display, QX11Info::appRootWindow(QX11Info::appScreen()),
// False, SubstructureNotifyMask | SubstructureRedirectMask,
// &xEvent);
// //XFlush(display);
// XEvent xevent;
// memset(&xevent, 0, sizeof(XEvent));
// xevent.type = ButtonRelease;
// xevent.xbutton.button = Button1;
// xevent.xbutton.window = this->winId();
// xevent.xbutton.x = e->pos().x() * dpiRatio;
// xevent.xbutton.y = e->pos().y() * dpiRatio;
// xevent.xbutton.x_root = pos.x() * dpiRatio;
// xevent.xbutton.y_root = pos.y() * dpiRatio;
// xevent.xbutton.display = display;
// XSendEvent(display, this->effectiveWinId(), False, ButtonReleaseMask, &xevent);
// XFlush(display);
// if (e->source() == Qt::MouseEventSynthesizedByQt) {
// if (!this->mouseGrabber()) {
// this->grabMouse();
// this->releaseMouse();
// }
// }
// m_is_draging = false;
// } else {
// this->move((QCursor::pos() - m_offset) * dpiRatio);
// }
}
void MainWindow::mouseReleaseEvent(QMouseEvent *e)
{
/*!
* \bug
* release event sometimes "disappear" when we request
* X11 window manager for movement.
*/
QMainWindow::mouseReleaseEvent(e);
//qDebug()<<"mouse released";
m_is_draging = false;
}
void MainWindow::validBorder()
{
return;
}
#include "file-utils.h"
void MainWindow::initUI(const QString &uri)
{
Peony::PluginManager::init();
m_searching = false;
connect(this, &MainWindow::locationChangeStart, this, [=]() {
//comment to fix bug 33527
//m_side_bar->blockSignals(true);
m_header_bar->blockSignals(true);
QCursor c;
c.setShape(Qt::BusyCursor);
this->setCursor(c);
m_tab->setCursor(c);
m_side_bar->setCursor(c);
//m_status_bar->update();
});
connect(this, &MainWindow::locationChangeEnd, this, [=]() {
//comment to fix bug 33527
//m_side_bar->blockSignals(false);
m_header_bar->blockSignals(false);
QCursor c;
c.setShape(Qt::ArrowCursor);
this->setCursor(c);
m_tab->setCursor(c);
m_side_bar->setCursor(c);
updateHeaderBar();
//function for UKUI3.1, update window icon
//updateWindowIcon();
//m_status_bar->update();
if (m_searching) {
m_tab->m_status_bar->updateSearchProgress(false);
Q_EMIT m_header_bar->updateSearchProgress(false);
m_searching = false;
}
setShortCuts();
});
//HeaderBar
m_tab = new TabWidget;
m_header_bar = new HeaderBar(this);
m_headerBarContainer = new HeaderBarContainer(this);
m_headerBarContainer->addHeaderBar(m_header_bar);
m_headerBarContainer->addMenu(this);
TopMenuBar *top = new TopMenuBar(m_header_bar, this);
m_tab->setMenuBar(top);
// m_tab->m_header_bar_layout->insertWidget(0,headerBarContainer);
m_tab->addToolBar(m_headerBarContainer);
//m_header_bar->setVisible(false);
Peony::GlobalSettings::getInstance()->setValue(LABLE_ALIGNMENT, 1);
connect(m_header_bar, &HeaderBar::updateLocationRequest, this, &MainWindow::goToUri);
connect(m_header_bar, &HeaderBar::viewTypeChangeRequest, this, &MainWindow::beginSwitchView);
connect(m_header_bar, &HeaderBar::updateZoomLevelHintRequest, this, [=](int zoomLevelHint) {
if (zoomLevelHint >= 0) {
m_tab->m_status_bar->m_slider->setEnabled(true);
m_tab->m_status_bar->m_slider->setValue(zoomLevelHint);
} else {
m_tab->m_status_bar->m_slider->setEnabled(false);
}
});
connect(m_tab, &TabWidget::searchStateChanged, this, [this](bool isSearching, const QString &searchKey) {
if (isSearching) {
m_header_bar->startEdit(true); // 进入搜索状态
m_header_bar->m_searchWidget->setSearchMode(true);
m_header_bar->m_searchWidget->setSearchText(searchKey);
} else {
m_header_bar->m_searchWidget->clearSearchBox();
}
});
//SideBar
auto sideBarFactory = Peony::SideBarFactoryManager::getInstance()->getFactoryFromPlatformName();
if (!sideBarFactory) {
NavigationSideBarContainer *sidebar = new NavigationSideBarContainer(this);
m_side_bar = sidebar;
} else {
m_side_bar = sideBarFactory->create(this);
}
m_transparent_area_widget = m_side_bar;
connect(m_side_bar, &Peony::SideBar::updateWindowLocationRequest, this, &MainWindow::goToUri);
connect(m_side_bar, &Peony::SideBar::updateWindowLocationRequest, m_header_bar, &HeaderBar::cancleSelect);
connect(m_side_bar, &Peony::SideBar::createVirtualTabAndSearch, this, &MainWindow::createVirtualTabAndSearch);
if (layoutDirection() == Qt::RightToLeft) {
m_tab->addDockWidget(Qt::RightDockWidgetArea, m_side_bar);
} else {
m_tab->addDockWidget(Qt::LeftDockWidgetArea, m_side_bar);
}
// auto labelDialog = new FileLabelBox(this);
// labelDialog->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// labelDialog->hide();
// m_label_box = labelDialog;
// connect(labelDialog->selectionModel(), &QItemSelectionModel::selectionChanged, [=]()
// {
// auto selected = labelDialog->selectionModel()->selectedIndexes();
// //qDebug() << "FileLabelBox selectionChanged:" < 0)
// {
// auto name = selected.first().data().toString();
// setLabelNameFilter(name);
// }
// });
//when clicked in blank, currentChanged may not triggered
//connect(labelDialog, &FileLabelBox::leftClickOnBlank, [=]()
// {
// setLabelNameFilter("");
// });
// sidebarContainer->setWidget(navigationSidebarContainer);
// addDockWidget(Qt::LeftDockWidgetArea, sidebarContainer);
// m_status_bar = new Peony::StatusBar(this, this);
// setStatusBar(m_status_bar);
// auto views = new TabWidget;
if (uri.isNull()) {
auto home = "file://" + QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
m_tab->addPage(home, true);
} else {
m_tab->addPage(uri, true);
//m_header_bar->setLocation(uri);
}
QTimer::singleShot(1, this, [=]() {
// FIXME:
// it is strange that if we set size hint by qsettings,
// the tab bar will "shrink" until we update geometry
// after a while (may resize window or move splitter).
// we should find out the reason and remove this dirty
// code.
m_tab->updateTabBarGeometry();
m_tab->updateStatusBarGeometry();
});
connect(Peony::GlobalSettings::getInstance(), &Peony::GlobalSettings::valueChanged, this, [=](const QString &key) {
if (key == ZOOM_SLIDER_VISIBLE) {
m_tab->updateStatusBarGeometry();
}
});
m_tab->tabBar()->installEventFilter(this);
connect(m_tab,&TabWidget::tabBarIndexUpdate,this,[=](int index){
if(index == 0)
m_is_first_tab = true;
else
m_is_first_tab = false;
update();
});
connect(m_tab, &TabWidget::closeWindowRequest, this, &QWidget::close);
connect(m_header_bar->m_searchWidget, &Peony::SearchWidget::updateSearchRequest, m_tab, &TabWidget::updateSearchBar);
connect(m_header_bar->m_searchWidget, &Peony::SearchWidget::updateSearchRequest, this, [=](bool showSearch){
m_is_search = showSearch;
});
//connect(m_header_bar, &HeaderBar::updateSearchRequest, this, &MainWindow::updateSearchStatus);
connect(m_header_bar->m_searchWidget, &Peony::SearchWidget::updateSearch, this, &MainWindow::updateSearch);
X11WindowManager *tabBarHandler = X11WindowManager::getInstance();
tabBarHandler->registerWidget(m_tab->tabBar());
//tabBarHandler->registerWidget(m_header_bar);
setCentralWidget(m_tab);
// auto paneAndViews = new FloatPaneWidget(views, labelDialog, this);
// connect(m_side_bar, &NavigationSideBar::labelButtonClicked, this, [=](bool checked)
// {
// bool visible = checked;
// //quit label filter, clear conditions
// if (visible)
// {
// setLabelNameFilter("");
// m_label_box->clearSelection();
// } else {
// setLabelNameFilter("");
// }
// paneAndViews->setFloatWidgetVisible(visible);
// });
// setCentralWidget(paneAndViews);
// // check slider zoom level
// if (currentViewSupportZoom())
// setCurrentViewZoomLevel(currentViewZoomLevel());
//bind signals
connect(m_tab, &TabWidget::searchRecursiveChanged, m_header_bar, &HeaderBar::updateSearchRecursive);
connect(m_tab, &TabWidget::closeSearch, m_header_bar->m_searchWidget, &Peony::SearchWidget::closeSearch);
connect(m_tab, &TabWidget::closeSearch, this, [=](){
this->updateSearchStatus(false);
});
connect(m_tab, &TabWidget::viewSelectStatus, m_header_bar, &HeaderBar::switchSelectStatus);
connect(m_tab, &TabWidget::updateWindowLocationRequest, m_header_bar, &HeaderBar::cancleSelect);
connect(m_tab, &TabWidget::globalSearch, m_header_bar, &HeaderBar::setGlobalFlag);
connect(m_tab, &TabWidget::clearTrash, this, &MainWindow::cleanTrash);
// connect(this, &MainWindow::trashcleaned, m_tab, [=](){
// m_tab->updateTabPageTitle();
// });
// connect(this, &MainWindow::trashcleaned, m_header_bar, &HeaderBar::clearTrash);
connect(m_tab, &TabWidget::recoverFromTrash, this, &MainWindow::recoverFromTrash);
connect(m_tab, &TabWidget::updateWindowLocationRequest, this, &MainWindow::goToUri);
connect(m_tab, &TabWidget::updateSearch, this, &MainWindow::updateSearch);
connect(m_tab, &TabWidget::activePageLocationChanged, this, &MainWindow::locationChangeEnd);
connect(m_tab, &TabWidget::activePageViewTypeChanged, this, &MainWindow::updateHeaderBar);
connect(m_tab, &TabWidget::activePageChanged, this, &MainWindow::updateHeaderBar);
connect(m_tab, &TabWidget::activePageChanged, this, [=](){
// check slider zoom level
setCurrentViewZoomLevel(currentViewZoomLevel());
});
connect(m_tab, &TabWidget::signal_itemAdded, this, [=](const QString& uri){
/* 新建文件/文件夹,可编辑文件名,copy时不能编辑 */
if(this->m_uris_to_edit.isEmpty())
return;
QString editUri = Peony::FileUtils::urlDecode(this->m_uris_to_edit.first());
QString infoUri = Peony::FileUtils::urlDecode(uri);
if (editUri == infoUri ) {
this->getCurrentPage()->getView()->scrollToSelection(uri);
this->editUri(uri);
}
this->m_uris_to_edit.clear();
});
connect(m_tab, &TabWidget::menuRequest, this, [=](const QPoint &pos) {
//fix bug#162775, show mutiple menu issue
if (! m_is_show_menu){
m_is_show_menu = true;
Peony::DirectoryViewMenu menu(this, this);
/* 菜单执行弹出操作时停止更新,超过1s或者结束菜单都启用更新;linkto bug#205332【文件管理器】选中一万个文本文件后,点击鼠标右键,右键菜单会闪烁 */
m_tab->setUpdatesEnabled(false);
QTimer::singleShot(1000, this, [=](){
if(!m_tab->updatesEnabled()){
m_tab->setUpdatesEnabled(true);
}
});
//fix bug#250273,right menu not show complete issue
QScreen *screen=qApp->primaryScreen();
QRect geometry = screen->availableGeometry();
menu.setMaximumHeight(geometry.height());
menu.exec(pos);
m_tab->setUpdatesEnabled(true);//end
m_uris_to_edit = menu.urisToEdit();
m_is_show_menu = false;
}
});
connect(m_tab, &TabWidget::updateWindowSelectionRequest, this, [=](const QStringList &uris){
//setCurrentSelectionUris(uris);
//fix bug#196528, selection files icon not update issue
//修复拖拽拷贝情况下,未更新图标问题
QTimer::singleShot(300, this, [=](){
setCurrentSelectionUris(uris);
});
});
connect(m_tab, &TabWidget::currentSelectionChanged, this, [=](){
int num = this->getCurrentPage()->getView()->getSelections().count();
bool isSelect = num > 0 ? true :false;
m_header_bar->switchSelectStatus(isSelect);
});
connect(Peony::ThumbnailManager::getInstance(), &Peony::ThumbnailManager::updateFileThumbnail, this, [=](){
this->refresh();
});
setTabOrder(m_side_bar, m_tab);
m_tab->setWindow(this);
// if (QGSettings::isSchemaInstalled("org.ukui.peony.settings")) {
// m_thumbnail = new QGSettings("org.ukui.peony.settings", QByteArray(), this);
// connect(m_thumbnail, &QGSettings::changed, this, [=](const QString &key) {
// if (FORBID_THUMBNAIL_IN_VIEW == key) {
// auto settings = Peony::GlobalSettings::getInstance();
// if (m_do_not_thumbnail != settings->getValue(FORBID_THUMBNAIL_IN_VIEW).toBool()) {
// m_do_not_thumbnail = settings->getValue(FORBID_THUMBNAIL_IN_VIEW).toBool();
// if (true == m_do_not_thumbnail) {
// Peony::ThumbnailManager::getInstance()->clearThumbnail();
// }
// refresh();
// }
// }
// });
// }
auto iscleaned = Peony::TrashCleanedWatcher::getInstance();
connect(iscleaned,&Peony::TrashCleanedWatcher::updateTrashIcon, m_tab, [=](){
m_tab->updateTabPageTitle();
});
}
void MainWindow::updateSearchStatus(bool showSearch)
{
m_tab->updateSearchBar(showSearch);
m_header_bar->setSearchMode(showSearch);
m_is_search = showSearch;
}
void MainWindow::cleanTrash()
{
auto uris = getCurrentAllFileUris();
Peony::AudioPlayManager::getInstance()->playWarningAudio();
if (uris.count() >0)
{
if (Peony::GlobalSettings::getInstance()->getProjectName() == V10_SP1_EDU) {
Peony::TrashWarnDialog *dialog = new Peony::TrashWarnDialog(nullptr);
connect(dialog, &Peony::TrashWarnDialog::accepted, [=]{
Peony::FileOperationUtils::remove(uris);
});
dialog->exec();
} else {
auto removeop = Peony::FileOperationUtils::clearRecycleBinWithDialog(uris, this);
qApp->setProperty("clearTrash",true);
// if(removeop){
// removeop->connect(removeop,&Peony::FileDeleteOperation::operationFinished,this,[=](){
// Peony::SoundEffect::getInstance()->recycleBinClearMusic();
// Q_EMIT trashcleaned();
// });
// }
}
}
else
{ /* 由于QMessageBox的setParent还不支持,暂先注释处理,link to bug#22692 【回收站】清空时,其他工作区的文件管理器会转到当前工作区 */
// QMessageBox::information(nullptr, tr("Tips info"),
// tr("Trash has no file need to be cleaned."));
}
}
void MainWindow::recoverFromTrash()
{
auto m_selections = getCurrentSelections();
if (m_selections.isEmpty())
m_selections = getCurrentAllFileUris();
if (m_selections.count() == 1) {
auto untrashop = Peony::FileOperationUtils::restore(m_selections.first());
if(untrashop){
connect(untrashop,&Peony::FileUntrashOperation::operationFinished,[=](){
Peony::SoundEffect::getInstance()->copyOrMoveSucceedMusic();
});
}
} else {
auto untrashop = Peony::FileOperationUtils::restore(m_selections);
if(untrashop){
connect(untrashop,&Peony::FileUntrashOperation::operationFinished,[=](){
Peony::SoundEffect::getInstance()->copyOrMoveSucceedMusic();
});
}
}
// qApp->setProperty("restoreFile",true);
}
void MainWindow::initAdvancePage()
{
//Fix me: advance search page, need the new design to develop new UI
//auto filterBar = new Peony::AdvanceSearchBar(this);
}
QRect MainWindow::sideBarRect()
{
auto pos = m_transparent_area_widget->mapTo(this, QPoint());
return QRect(pos, m_transparent_area_widget->size());
}
void MainWindow::startMonitorThumbnailForbidStatus()
{
m_do_not_thumbnail = Peony::GlobalSettings::getInstance()->getValue(FORBID_THUMBNAIL_IN_VIEW).toBool();
m_thumbnail_watcher = new QFileSystemWatcher(this);
QString peonySettingFile = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
+ "/.config/org.ukui/peony-qt-preferences.conf";
m_thumbnail_watcher->addPath(peonySettingFile);
connect(m_thumbnail_watcher, &QFileSystemWatcher::fileChanged, [=](const QString &uri){
auto settings = Peony::GlobalSettings::getInstance();
if (m_do_not_thumbnail != settings->getValue(FORBID_THUMBNAIL_IN_VIEW).toBool()) {
m_do_not_thumbnail = settings->getValue(FORBID_THUMBNAIL_IN_VIEW).toBool();
// fix #213036
if (true == m_do_not_thumbnail) {
Peony::ThumbnailManager::getInstance()->clearThumbnail();
if (getCurrentPage()) {
if (getCurrentPage()->getView()) {
getCurrentPage()->getView()->repaintView();
}
} else {
refresh();
}
} else {
if (getCurrentPage()) {
getCurrentPage()->updateCurrentFilesThumbnails();
} else {
refresh();
}
}
}
//qDebug()<<"peonySettingFile:"<addPath(uri);
});
}
const QList> MainWindow::getCurrentSelectionFileInfos()
{
const QStringList uris = getCurrentSelections();
QList> infos;
for(auto uri : uris) {
auto info = Peony::FileInfo::fromUri(uri);
infos<currentPage() && m_tab->currentPage()->getView()) {
iface2 = Peony::DirectoryViewHelper::globalInstance()->getViewIface2ByDirectoryViewWidget(m_tab->currentPage()->getView());
iface2->setItemsVisible(false);
qApp->processEvents();
}
//task#106007 【文件管理器】文件管理器应用做平板UI适配,切换模式
qApp->setProperty("tabletMode", isTabletMode);
if(isTabletMode) {
m_headerBarContainer->setFixedHeight(72);
m_headerBarContainer->m_topMenu->show();
} else {
m_headerBarContainer->setFixedHeight(60);
m_headerBarContainer->m_topMenu->hide();
}
m_tab->updateTabletModeValue(isTabletMode);
m_tab->menuWidget()->setVisible(!isTabletMode);
m_header_bar->updateTabletModeValue(isTabletMode);
Q_EMIT tabletModeChanged(isTabletMode);
if (iface2) {
iface2->setItemsVisible(true);
}
}
void MainWindow::setKeepAbove(bool keepAbove)
{
if (m_keepAbove == keepAbove) {
return;
}
m_keepAbove = keepAbove;
if (QApplication::platformName().toLower().contains("wayland")) {
#ifdef KY_SDK_WAYLANDHELPER
UkuiWindowHelper::States defaultStates = UkuiWindowHelper::States(0xff);
if (m_keepAbove) {
m_window_helper->setWindowState(defaultStates | UkuiWindowHelper::State::KeepAbove);
} else {
m_window_helper->setWindowState(static_cast(
static_cast(defaultStates) &
~static_cast(UkuiWindowHelper::State::KeepAbove)));
}
#endif
} else {
//use kf5 interface to fix set on top has no effect issue
// if (m_keepAbove)
// KWindowSystem::setState(winId(), NET::KeepAbove);
// else
// KWindowSystem::clearState(winId(), NET::KeepAbove);
setWindowFlag(Qt::WindowStaysOnTopHint, keepAbove);
show();
}
}
bool MainWindow::isKeepAbove() const
{
return m_keepAbove;
}
peony/src/windows/main-window-factory.h 0000664 0001750 0001750 00000003315 15154271070 017166 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#ifndef MAINWINDOWFACTORY_H
#define MAINWINDOWFACTORY_H
#include
#include "main-window-factory-iface.h"
#include
/*!
* \brief The MainWindowFactory class
* \deprecated
*/
class PEONYCORESHARED_EXPORT MainWindowFactory : public QObject, public Peony::MainWindowFactoryIface
{
Q_OBJECT
// Q_PLUGIN_METADATA(IID MainWindowFactoryIface_iid)
// Q_INTERFACES(Peony::MainWindowFactoryIface)
public:
const QString name()
{
return "ukui4.0";
}
static Peony::MainWindowFactoryIface *getInstance();
Peony::FMWindowIface *create(const QString &uri);
Peony::FMWindowIface *create(const QStringList &uris);
QWidget *createWindow(const QString &uri = nullptr);
QWidget *createWindow(const QStringList &uris);
QWidget *createWindow(const QString &uri, QStringList selectUris);
//private:
explicit MainWindowFactory(QObject *parent = nullptr);
};
#endif // MAINWINDOWFACTORY_H
peony/src/windows/about-dialog.cpp 0000664 0001750 0001750 00000017717 15154271106 016205 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#include "about-dialog.h"
#include "ui_about-dialog.h"
#include "xatom-helper.h"
#include
#include
#include
#include
#include
#include
#include
#ifdef KY_SDK_WAYLANDHELPER
#include
#include
#endif
//#include
#include "xatom-helper.h"
#ifdef KY_SDK_QT_WIDGETS
AboutDialog::AboutDialog(QWidget *parent) :
kdk::KAboutDialog(parent)
{
setAppIcon(QIcon::fromTheme("system-file-manager"));
setAppName(tr("Peony"));
setAppSupport(tr("Service & Support: ") + "support@kylinos.cn
");
setAppVersion(QString(tr("Version number: %1")).arg(getCurrentVersion()));
setBodyText(tr("Peony is a graphical software to help users manage system files. "
"It provides common file operation functions for users, such as file viewing, "
"file copy, paste, cut, delete, rename, file selection, application opening, "
"file search, file sorting, file preview, etc. it is convenient for users to "
"manage system files intuitively on the interface."));
setBodyTextVisiable(true);
}
#else
AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent)
{
this->initUI();
}
#endif
AboutDialog::~AboutDialog()
{
#ifndef KY_SDK_QT_WIDGETS
delete ui;
#endif
}
void AboutDialog::initUI()
{
setAutoFillBackground(true);
setBackgroundRole(QPalette::Base);
setFixedWidth(420);
bool isPlatformX11 = qGuiApp->nativeInterface();
if (isPlatformX11) {
XAtomHelper::getInstance()->setUKUIDecoraiontHint(this->winId(), true);
MotifWmHints hints;
hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS;
hints.functions = MWM_FUNC_ALL;
hints.decorations = MWM_DECOR_BORDER;
XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints);
} else {
#ifdef KY_SDK_WAYLANDHELPER
auto windowHelper = new UkuiWindowHelper(this);
windowHelper->removeTitleBar();
#endif
}
ui = new Ui::AboutDialog;
ui->setupUi(this);
ui->logoLabel->setPixmap(QIcon::fromTheme("system-file-manager").pixmap(24,24));
ui->titleLabel->setText(tr("Peony"));
ui->closeBtn->setFlat(true);
ui->closeBtn->setProperty("isIcon", true);
ui->closeBtn->setFixedSize(QSize(30, 30));
ui->closeBtn->setProperty("isWindowButton", 2);
ui->closeBtn->setProperty("useIconHighlightEffect", 0x8);
ui->closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic"));
ui->iconLabel->setPixmap(QIcon::fromTheme("system-file-manager").pixmap(96,96));
auto font = qApp->font();
QFont namefont = font;
namefont.setBold(true);
namefont.setPointSize(font.pointSize()*1.28);
ui->nameLabel->setFont(namefont);
ui->nameLabel->setText(tr("Peony"));
ui->versionLabel->setFont(font);
ui->versionLabel->setText(QString(tr("Version number: %1")).arg(getCurrentVersion()));
ui->briefTextedit->setReadOnly(true);
QTextCursor textCursor;
QTextBlockFormat blockFormat;
blockFormat.setLineHeight(font.pointSize()+10, QTextBlockFormat::SingleHeight);//font-line-hight
textCursor = ui->briefTextedit->textCursor(); //before the setText().
//bug#101112 关于界面自适应大小
QTextDocument* doc = new QTextDocument(ui->briefTextedit);
doc->setPlainText(tr("Peony is a graphical software to help users manage system files. "
"It provides common file operation functions for users, such as file viewing, "
"file copy, paste, cut, delete, rename, file selection, application opening, "
"file search, file sorting, file preview, etc. it is convenient for users to "
"manage system files intuitively on the interface."));
ui->briefTextedit->setDocument(doc);
textCursor.setBlockFormat(blockFormat);
ui->briefTextedit->setTextCursor(textCursor);
doc->setTextWidth(420-32-32);
if (QGSettings::isSchemaInstalled("org.ukui.style")) {
m_gSettings = new QGSettings("org.ukui.style", QByteArray(), this);
connect(m_gSettings, &QGSettings::changed, this, [=](const QString &key) {
if (key == "styleName") {
setSupportText();
}
else if("systemFontSize" == key)
{
auto appfont = qApp->font();
QFont namefont = appfont;
namefont.setBold(true);
namefont.setPointSize(appfont.pointSize()*1.28);
ui->nameLabel->setFont(namefont);
resetSize();
}
else if("iconThemeName" == key)
{
ui->iconLabel->setPixmap(QIcon::fromTheme("system-file-manager").pixmap(96,96));
ui->logoLabel->setPixmap(QIcon::fromTheme("system-file-manager").pixmap(24,24));
}
});
}
this->setSupportText();
ui->openlinkLabel->setOpenExternalLinks(true);
}
void AboutDialog::setSupportText()
{
QString text = tr("Service & Support: ") + "support@kylinos.cn
";
ui->openlinkLabel->setText(text);
}
QString AboutDialog::convertRGB16HexStr(const QColor &color)
{
if (color == Qt::transparent)
return "#000000";//透明则显示黑色
QString red = QString("%1").arg(color.red(),2,16,QChar('0'));
QString green = QString("%1").arg(color.green(),2,16,QChar('0'));
QString blue = QString("%1").arg(color.blue(),2,16,QChar('0'));
QString hexStr = "#" + red + green + blue;
return hexStr;
}
QString AboutDialog::getCurrentVersion()
{
//use self define main version
//return VERSION;
FILE *pp = NULL;
char *line = NULL;
size_t len = 0;
ssize_t read;
char *q = NULL;
QString version = VERSION;
//fix bug#125289, use dpkg query version instead of self define version
pp = popen("dpkg -l peony", "r");
if(NULL == pp)
return version;
while((read = getline(&line, &len, pp)) != -1){
q = strrchr(line, '\n');
*q = '\0';
QString content = line;
QStringList list = content.split(" ");
list.removeAll("");
if (list.size() >= 3)
version = list.at(2);
}
free(line);
pclose(pp);
return version;
}
void AboutDialog::on_closeBtn_clicked()
{
close();
}
void AboutDialog::resetSize()
{
int minHeight = 324;
int maxHeight = 560;
int newHeight = ui->briefTextedit->document()->size().height();
int changeHeight = newHeight - ui->briefTextedit->height();
int finalHeight = this->height() + changeHeight + 10;
if( finalHeight > maxHeight)
{
finalHeight = maxHeight;
}
else if(finalHeight < minHeight)
{
finalHeight = minHeight;
}
this->setFixedHeight(finalHeight);
ui->verticalLayout_3->update();
}
peony/src/windows/trash-warn-dialog.cpp 0000664 0001750 0001750 00000010744 15154271106 017152 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2021, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Wenfei He
*
*/
#include "trash-warn-dialog.h"
#include
#include
#include
#include
using namespace Peony;
void TrashWarnDialog::paintEvent(QPaintEvent *event)
{
const QPalette &palette = this->palette();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
painter.setBrush(palette.brush(QPalette::Window));
painter.setPen(palette.color(QPalette::Window));
QRect rect = this->rect();
rect.setWidth(rect.width() - 1);
rect.setHeight(rect.height() - 1);
painter.drawRoundedRect(rect, 16, 16);
QWidget::paintEvent(event);
}
TrashWarnDialog::TrashWarnDialog(QWidget *parent) : QDialog(parent)
{
//调整大小
this->setFixedSize(320,344);
//去掉窗口图标和标题,只显示关闭按钮,模态窗口
this->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
this->setWindowModality(Qt::ApplicationModal);
this->setAttribute(Qt::WA_TranslucentBackground);
this->setAttribute(Qt::WA_DeleteOnClose);
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
//清除默认边距
dialogLayout->setContentsMargins(0, 0, 0, 0);
this->setLayout(dialogLayout);
QHBoxLayout *floor1 = new QHBoxLayout(this);
floor1->setContentsMargins(0, 16, 16, 0);
floor1->setAlignment(Qt::AlignRight);
//去掉窗口标题后手动设置一个关闭按钮
QPushButton *closeButton = new QPushButton(this);
closeButton->setFixedSize(16, 16);
closeButton->setIcon(QIcon::fromTheme("window-close-symbolic"));
//设置按钮的悬停事件和点击事件颜色
closeButton->setStyleSheet("QPushButton:hover{background-color: #FF9E9E;border-radius:4px;border:none;}"
"QPushButton:pressed{background-color:#FB5050;border-radius:4px;border:none;}");
floor1->addWidget(closeButton);
dialogLayout->addLayout(floor1);
QHBoxLayout *floor2 = new QHBoxLayout(this);
floor2->setContentsMargins(0, 40, 0, 0);
floor2->setAlignment(Qt::AlignHCenter);
QLabel *iconLabel = new QLabel(this);
iconLabel->setContentsMargins(0, 0, 0, 0);
iconLabel->setAlignment(Qt::AlignHCenter);
QPixmap pixmap = QIcon::fromTheme("user-trash-full").pixmap(64, 64);
iconLabel->setPixmap(pixmap);
floor2->addWidget(iconLabel);
dialogLayout->addLayout(floor2);
QHBoxLayout *floor3 = new QHBoxLayout(this);
floor3->setContentsMargins(24, 24, 24, 0);
QLabel *textLineLabel = new QLabel(this);
textLineLabel->setContentsMargins(0, 0, 0, 0);
textLineLabel->setWordWrap(true);
textLineLabel->setAlignment(Qt::AlignHCenter);
textLineLabel->setText(tr("Are you sure that you want to delete these files? Once you start a deletion, "
"the files deleting will never be restored again."));
floor3->addWidget(textLineLabel);
dialogLayout->addLayout(floor3);
QHBoxLayout *floor4 = new QHBoxLayout(this);
floor4->setContentsMargins(24, 0, 24, 24);
QPushButton *deleteButton = new QPushButton(this);
QPushButton *cancelButton = new QPushButton(this);
deleteButton->setFixedSize(124, 48);
cancelButton->setFixedSize(124, 48);
deleteButton->setText(tr("Delete"));
cancelButton->setText(tr("Cancel"));
floor4->addWidget(cancelButton);
floor4->addStretch(1);
floor4->addWidget(deleteButton);
dialogLayout->addLayout(floor4);
connect(closeButton, &QPushButton::clicked, this, [=]{
Q_EMIT rejected();
close();
});
connect(cancelButton, &QPushButton::clicked, this, [=]{
Q_EMIT rejected();
close();
});
connect(deleteButton, &QPushButton::clicked, this, [=]{
Q_EMIT accepted();
close();
});
}
peony/src/windows/windows.pri 0000664 0001750 0001750 00000000621 15154271070 015322 0 ustar feng feng INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/trash-warn-dialog.h \
$$PWD/about-dialog.h \
# $$PWD/main-window-factory.h \
# $$PWD/main-window.h \
$$PWD/x11-window-manager.h
SOURCES += \
$$PWD/trash-warn-dialog.cpp \
$$PWD/about-dialog.cpp \
# $$PWD/main-window-factory.cpp \
# $$PWD/main-window.cpp \
$$PWD/x11-window-manager.cpp
FORMS += \
$$PWD/about-dialog.ui
peony/src/windows/about-dialog.h 0000664 0001750 0001750 00000003104 15154271070 015633 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#ifndef ABOUTDIALOG_H
#define ABOUTDIALOG_H
#include
#include
#include
#include
#include
#ifdef KY_SDK_QT_WIDGETS
#include
#endif
namespace Ui {
class AboutDialog;
}
#ifdef KY_SDK_QT_WIDGETS
class AboutDialog : public kdk::KAboutDialog
#else
class AboutDialog : public QDialog
#endif
{
Q_OBJECT
public:
explicit AboutDialog(QWidget *parent = nullptr);
~AboutDialog();
void resetSize();
private:
void initUI();
QString getCurrentVersion();
private Q_SLOTS:
void on_closeBtn_clicked();
private:
Ui::AboutDialog *ui;
QGSettings *m_gSettings;
void setSupportText();
//颜色转换
QString convertRGB16HexStr(const QColor &color);
bool m_isFirstLoad = false;
};
#endif // ABOUTDIALOG_H
peony/src/windows/main-window.h 0000664 0001750 0001750 00000015737 15154271106 015534 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include "FMWindowIface.h"
#include "header-bar.h"
#include "file-label-box.h"
#include
#include
class MainWindowPrivate;
class BorderShadowEffect;
class HeaderBar;
class NavigationSideBar;
class TabWidget;
class QWidgetResizeHandler;
class QStackedWidget;
class QGSettins;
class QDBusInterface;
class UkuiWindowHelper;
namespace Peony {
class DirectoryViewContainer;
class FileInfo;
class StatusBar;
class SideBar;
}
class MainWindow : public QMainWindow, public Peony::FMWindowIface
{
friend class HeaderBar;
friend class TopMenuBar;
Q_OBJECT
public:
explicit MainWindow(const QString &uri = nullptr, QWidget *parent = nullptr);
~MainWindow();
bool eventFilter(QObject *watched, QEvent *event);
QSize sizeHint() const;
Peony::FMWindowIface *create(const QString &uri);
Peony::FMWindowIface *create(const QStringList &uris);
Peony::FMWindowIface *createWithZoomLevel(const QString &uri, int zoomLevel);
Peony::FMWindowIface *createWithZoomLevel(const QStringList &uris, int zoomLevel);
Peony::FMWindowFactory *getFactory();
Peony::DirectoryViewContainer *getCurrentPage();
const QString getCurrentUri();
const QStringList getCurrentSelections();
const QStringList getCurrentAllFileUris();
const QList> getCurrentSelectionFileInfos();
Qt::SortOrder getCurrentSortOrder();
int getCurrentSortColumn();
bool getWindowShowHidden();
bool getWindowUseDefaultNameSortOrder();
bool getWindowSortFolderFirst();
int currentViewZoomLevel();
bool currentViewSupportZoom();
void setKeepAbove(bool keepAbove);
bool isKeepAbove() const;
Q_SIGNALS:
void windowSelectionChanged();
void locationChanged(const QString &uri);
void viewLoaded(bool successed = true);
void trashcleaned();
/*!
* \brief locationChangeStart
* \details
* This signal is used to tell the window doing a location change.
* When a window is excuting a location change, it should not execute another
* one util the location change finished.
*/
void locationChangeStart();
/*!
* \brief endLocationChange
* \details
* This signal is used to tell the window that a location change finished.
* Once a location change finished, we can start a new location change.
*/
void locationChangeEnd();
void signal_itemAdded(const QString& uri);/* 新增文件(夹),item创建完成 */
void tabletModeChanged(bool isTabletMode);
void setSelection(QStringList selectionUris);
void initUIRequest();
public Q_SLOTS:
void maximizeOrRestore();
void syncControlsLocation(const QString &uri);
void updateHeaderBar();
void updateWindowIcon();
//void updateSearchStatus(bool showSearch);
void updateSearch(const QString &uri, const QString &key="", bool updateKey=false);
void createFolderOperation();
void goToUri(const QString &uri, bool addHistory = false, bool force = false);
void addNewTabs(const QStringList &uris);
void beginSwitchView(const QString &viewId);
void refresh();
void forceStopLoading();
//imigrate from fm-window
void advanceSearch();
void clearRecord();
void searchFilter(QString target_path, QString keyWord, bool search_file_name, bool search_content);
void filterUpdate(int type_index=0, int time_index=0, int size_index=0);
void setShowHidden(bool showHidden);
void setShowFileExtensions(bool checked);
void setUseDefaultNameSortOrder(bool use);
void setSortFolderFirst(bool set);
void setShortCuts();
void checkSettings();
void setLabelNameFilter(QString name);
void updateTabPageTitle();
//trash quick operations
void cleanTrash();
void recoverFromTrash();
bool getFilterWorking(){return m_filter_working;}
void setCurrentSelectionUris(const QStringList &uris);
void setCurrentSortOrder (Qt::SortOrder order);
void setCurrentSortColumn (int sortColumn);
void editUri(const QString &uri);
void editUris(const QStringList &uris);
void setCurrentViewZoomLevel(int zoomLevel);
QString getLastSearchKey();
void clearLastSearchPath();
void updateTabletModeValue(bool isTabletMode);
void updateSearchStatus(bool isSearching);
void updateDateFormat(QString dateFormat);
void createVirtualTabAndSearch();
protected:
void resizeEvent(QResizeEvent *e);
void paintEvent(QPaintEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void keyPressEvent(QKeyEvent *e);
void showEvent(QShowEvent *event);
void validBorder();
void initUI(const QString &uri);
void initAdvancePage();
QRect sideBarRect();
void startMonitorThumbnailForbidStatus();
private:
BorderShadowEffect *m_effect;
#ifdef KY_SDK_WAYLANDHELPER
UkuiWindowHelper *m_window_helper;
#endif
HeaderBar *m_header_bar;
HeaderBarContainer *m_headerBarContainer;
Peony::SideBar *m_side_bar;
QWidget *m_transparent_area_widget;
QStackedWidget *m_side_bar_container;
TabWidget *m_tab = nullptr;
Peony::StatusBar *m_status_bar;
FileLabelBox *m_label_box;
QString m_last_search_path = "";
QString m_last_key = "";
bool m_is_draging = false;
bool m_is_search = false;
bool m_is_clear_serach = false;
bool m_filter_working = false;
bool m_should_save_side_bar_width = false;
bool m_should_save_window_size = false;
bool m_is_first_tab =true;
bool m_searching = false;
QPoint m_offset;
QWidgetList m_focus_list;
bool m_shortcuts_set = false;
QFileSystemWatcher *m_thumbnail_watcher;
bool m_do_not_thumbnail = false;
QGSettings* m_thumbnail = nullptr;
//change minimum width to avoid bug#90366
const int WINDOW_MINIMUM_WIDTH = 740;
QStringList m_uris_to_edit;/* 新建文件/文件夹,可编辑文件名list */
QDBusInterface *m_statusManagerDBus = nullptr;
bool m_is_blur_window = false;
bool m_is_show_menu = false;
QString m_date_format = "";
QDBusInterface *mDbusDateServer;
bool m_keepAbove = false;
};
#endif // MAINWINDOW_H
peony/src/windows/windows-peony.pri 0000664 0001750 0001750 00000000256 15154271070 016456 0 ustar feng feng INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/main-window.h \
$$PWD/main-window-factory.h \
SOURCES += \
$$PWD/main-window.cpp \
$$PWD/main-window-factory.cpp \
peony/src/windows/main-window-factory.cpp 0000664 0001750 0001750 00000004341 15154271070 017521 0 ustar feng feng /*
* Peony-Qt
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology Co., Ltd.
*
* This program 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.
*
* This program 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 this program. If not, see .
*
* Authors: Yue Lan
*
*/
#include "main-window-factory.h"
#include "main-window.h"
MainWindowFactory *global_instance = nullptr;
Peony::MainWindowFactoryIface *MainWindowFactory::getInstance()
{
auto g = global_instance;
if (!global_instance)
global_instance = new MainWindowFactory;
return global_instance;
}
Peony::FMWindowIface *MainWindowFactory::create(const QString &uri)
{
auto window = new MainWindow(uri);
return window;
}
Peony::FMWindowIface *MainWindowFactory::create(const QStringList &uris)
{
if (uris.isEmpty())
return new MainWindow;
auto uri = uris.first();
auto l = uris;
l.removeAt(0);
auto window = new MainWindow(uri);
window->addNewTabs(l);
return window;
}
QWidget *MainWindowFactory::createWindow(const QString &uri)
{
auto window = new MainWindow(uri);
return window;
}
QWidget *MainWindowFactory::createWindow(const QStringList &uris)
{
if (uris.isEmpty())
return new MainWindow;
auto uri = uris.first();
auto l = uris;
l.removeAt(0);
auto window = new MainWindow(uri);
window->addNewTabs(l);
return window;
}
QWidget *MainWindowFactory::createWindow(const QString &uri, QStringList selectUris)
{
auto window = new MainWindow(uri);
connect(window, &MainWindow::locationChangeEnd, [=]() {
Q_EMIT window->setSelection(selectUris);
});
return window;
}
MainWindowFactory::MainWindowFactory(QObject *parent) : Peony::MainWindowFactoryIface()
{
}
peony/src/man/ 0000775 0001750 0001750 00000000000 15154271070 012176 5 ustar feng feng peony/src/man/peony.1 0000664 0001750 0001750 00000001410 15154271070 013406 0 ustar feng feng .\" Man Page for Peony
.TH Peony 1 "09 December 2019" "UKUI Desktop Environment"
.SH "NAME"
Peony \- The default File Manager of UKUI3.0.
.SH "SYNOPSIS"
.B peony [OPTION] [FILE1, FILE2...]
.SH "DESCRIPTION"
Peony is default FileManager of UKUI3.0.
This program provides several commands for interactions with the program.
.TP
\fB -q, --quit\fR
Close all windows and quit.
.TP
\fB -i, --show-items\fR
Show items in directories and select them.
.TP
\fB -f, --show-folders\fR
Show folders.
.TP
\fB -p, --show-properties\fR
Show files properties.
.SH "BUGS"
.SS Should you encounter any bugs, they may be reported at:
https://github.com/ukui/peony/issues
.SH "AUTHORS"
.SS This Manual Page has been written for the UKUI Desktop Environment by:
Yue Lan (2019)
peony/src/custome.qrc 0000664 0001750 0001750 00000001060 15154271106 013606 0 ustar feng feng
icons/child-folder.png
icons/child-folder2.png
icons/ukui-down-symbolic.svg
icons/ukui-end-symbolic.svg
icons/ukui-start-symbolic.svg
icons/ukui-up-symbolic.svg
icons/sign.svg
icons/sign.png
icons/kylin-data-manager.svg
icons/folder-space.svg
peony/src/main-window-factory-plugin-manager.h 0000664 0001750 0001750 00000003321 15154271070 020375 0 ustar feng feng /*
* Peony-Qt's Library
*
* Copyright (C) 2020, Tianjin KYLIN Information Technology 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 .
*
* Authors:Yan Wei Yang
*
*/
#ifndef FMWINDOWFACTORY_H
#define FMWINDOWFACTORY_H
#include
#include "FMWindowIface.h"
#include "main-window-factory-iface.h"
#include
/*!
* \brief The FMWindowFactoryPluginManager class
* \deprecated
*/
class MainWindowFactoryPluginManager : public QObject
{
public:
static MainWindowFactoryPluginManager *getInstance();
QString setVersion();
QWidget *create(const QString &uri = nullptr);
QWidget *create(const QStringList &uris);
QWidget *create(const QString &uri, QStringList selectUris);
const QStringList getPluginIds();
QObject *getPlugin(const QString &pluginId);
bool registerPlugin(Peony::MainWindowFactoryIface *plugin);
void close();
protected:
void loadAsync();
private:
explicit MainWindowFactoryPluginManager(QObject *parent = nullptr);
QHash m_hash;
};
#endif // FMWINDOWFACTORY_H
peony/src/icons/ 0000775 0001750 0001750 00000000000 15154271106 012536 5 ustar feng feng peony/src/icons/folder-space.svg 0000664 0001750 0001750 00000034155 15154271106 015633 0 ustar feng feng