2121#include < QAction>
2222#include < QHBoxLayout>
2323#include < QGuiApplication>
24+ #include < QScreen>
2425#include < QTimer>
2526#include < QWindow>
2627#include < QMimeType>
@@ -66,7 +67,7 @@ FilePreviewDialog::~FilePreviewDialog()
6667void FilePreviewDialog::updatePreviewList (const QList<QUrl> &previewUrllist)
6768{
6869 qCInfo (logLibFilePreview) << " FilePreviewDialog: updating preview list with" << previewUrllist.size () << " files" ;
69-
70+
7071 // 视频预览的前一秒禁止再次播放
7172 if (playingVideo) {
7273 qCDebug (logLibFilePreview) << " FilePreviewDialog: video is playing, ignoring preview list update" ;
@@ -95,7 +96,7 @@ void FilePreviewDialog::setEntryUrlList(const QList<QUrl> &urlList)
9596 qCDebug (logLibFilePreview) << " FilePreviewDialog: empty URL list provided for entry list" ;
9697 return ;
9798 }
98-
99+
99100 QUrl currentUrl = fileList.at (currentPageIndex);
100101 if (urlList.contains (currentUrl)) {
101102 qCInfo (logLibFilePreview) << " FilePreviewDialog: setting directory preview mode with" << urlList.size () << " files" ;
@@ -158,7 +159,7 @@ void FilePreviewDialog::handleFileInfoRefreshFinished(const QUrl url, const QStr
158159{
159160 Q_UNUSED (infoPtr)
160161 Q_UNUSED (isLinkOrg)
161-
162+
162163 if (UniversalUtils::urlEquals (url, fileList.at (currentPageIndex))) {
163164 qCDebug (logLibFilePreview) << " FilePreviewDialog: file info refreshed for current file, updating preview:" << url.toString ();
164165 switchToPage (currentPageIndex);
@@ -247,7 +248,7 @@ bool FilePreviewDialog::eventFilter(QObject *obj, QEvent *event)
247248void FilePreviewDialog::initUI ()
248249{
249250 qCDebug (logLibFilePreview) << " FilePreviewDialog: initializing UI components" ;
250-
251+
251252 closeBtn = new DFloatingButton (DStyle::SP_CloseButton, this );
252253 closeBtn->setStyleSheet (" background-color: transparent;" );
253254 closeBtn->setFixedSize (46 , 46 );
@@ -286,19 +287,22 @@ void FilePreviewDialog::initUI()
286287 connect (statusBar->preButton (), &QPushButton::clicked, this , &FilePreviewDialog::previousPage);
287288 connect (statusBar->nextButton (), &QPushButton::clicked, this , &FilePreviewDialog::nextPage);
288289 connect (statusBar->openButton (), &QPushButton::clicked, this , &FilePreviewDialog::openFile);
289-
290+
290291 qCDebug (logLibFilePreview) << " FilePreviewDialog: UI initialization completed" ;
291292}
292293
293294void FilePreviewDialog::switchToPage (int index)
294295{
295296 qCInfo (logLibFilePreview) << " FilePreviewDialog: switching to page" << index << " of" << fileList.count () << " files" ;
296-
297+
297298 if (index < 0 || index >= fileList.count ()) {
298299 qCWarning (logLibFilePreview) << " FilePreviewDialog: invalid page index:" << index << " valid range: 0 -" << (fileList.count () - 1 );
299300 return ;
300301 }
301-
302+
303+ // 在切换视图前记录当前窗口中心位置(如果窗口可见)
304+ saveCenterPos ();
305+
302306 currentPageIndex = index;
303307 statusBar->preButton ()->setEnabled (index > 0 );
304308 statusBar->nextButton ()->setEnabled (index < fileList.count () - 1 );
@@ -356,6 +360,7 @@ void FilePreviewDialog::switchToPage(int index)
356360 int newPerviewHeight = preview->contentWidget ()->size ().height ();
357361 setFixedSize (newPerviewWidth, newPerviewHeight + statusBar->height ());
358362 playCurrentPreviewFile ();
363+ restoreCenterPos ();
359364 qCInfo (logLibFilePreview) << " FilePreviewDialog: successfully reused preview for file:" << fileList.at (index).toString ();
360365 return ;
361366 }
@@ -427,7 +432,10 @@ void FilePreviewDialog::switchToPage(int index)
427432 int newPerviewHeight = preview->contentWidget ()->size ().height ();
428433 setFixedSize (newPerviewWidth, newPerviewHeight + statusBar->height ());
429434 updateTitle ();
430-
435+
436+ // 切换并调整大小后,尝试将窗口移动回之前的中心位置
437+ restoreCenterPos ();
438+
431439 qCInfo (logLibFilePreview) << " FilePreviewDialog: successfully switched to page" << index << " for file:" << fileList.at (index).toString ();
432440}
433441
@@ -485,7 +493,7 @@ void FilePreviewDialog::updateTitle()
485493 }
486494 statusBar->title ()->setText (elidedText);
487495 statusBar->title ()->setHidden (statusBar->title ()->text ().isEmpty ());
488-
496+
489497 qCDebug (logLibFilePreview) << " FilePreviewDialog: updated title to:" << elidedText;
490498}
491499
@@ -498,3 +506,56 @@ QString FilePreviewDialog::generalKey(const QString &key)
498506
499507 return key;
500508}
509+
510+ void FilePreviewDialog::saveCenterPos ()
511+ {
512+ if (!isVisible ()) {
513+ // 窗口不可见时不记录
514+ return ;
515+ }
516+
517+ // 使用 frameGeometry 来考虑窗口装饰
518+ QRect fg = frameGeometry ();
519+ previousCenter = fg.center ();
520+ qCDebug (logLibFilePreview) << " FilePreviewDialog: saved center position:" << previousCenter;
521+ }
522+
523+ void FilePreviewDialog::restoreCenterPos ()
524+ {
525+ if (previousCenter.isNull ()) {
526+ // 没有记录过中心点
527+ return ;
528+ }
529+
530+ // 计算新的左上角位置以保持中心点不变
531+ QSize s = size ();
532+ QPoint newTopLeft (previousCenter.x () - s.width () / 2 , previousCenter.y () - s.height () / 2 );
533+
534+ // 限制窗口位置到记录中心所在屏幕的可用区域,避免跨屏显示
535+ QScreen *scr = QGuiApplication::screenAt (previousCenter);
536+ QRect avail;
537+ if (scr) {
538+ avail = scr->availableGeometry ();
539+ } else if (QGuiApplication::primaryScreen ()) {
540+ avail = QGuiApplication::primaryScreen ()->availableGeometry ();
541+ }
542+
543+ if (!avail.isNull ()) {
544+ // 如果窗口大小大于可用区域,则将窗口居中显示在该屏幕内
545+ if (s.width () > avail.width () || s.height () > avail.height ()) {
546+ QPoint centered (avail.center ().x () - s.width () / 2 , avail.center ().y () - s.height () / 2 );
547+ newTopLeft = centered;
548+ } else {
549+ // 将 newTopLeft 限定在 avail 内
550+ int x = qBound (avail.left (), newTopLeft.x (), avail.right () - s.width ());
551+ int y = qBound (avail.top (), newTopLeft.y (), avail.bottom () - s.height ());
552+ newTopLeft = QPoint (x, y);
553+ }
554+ }
555+
556+ // 将窗口移动到新位置,但确保在主线程和可见时操作
557+ if (isVisible ()) {
558+ move (newTopLeft);
559+ qCDebug (logLibFilePreview) << " FilePreviewDialog: restored window to keep center at" << previousCenter << " moved to" << newTopLeft;
560+ }
561+ }
0 commit comments