diff --git a/reader/MainWindow.cpp b/reader/MainWindow.cpp index 4ae0dca6..897ce934 100755 --- a/reader/MainWindow.cpp +++ b/reader/MainWindow.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. // SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -479,6 +479,14 @@ void MainWindow::resizeFullTitleWidget() qCDebug(appLog) << "MainWindow::resizeFullTitleWidget() - Resize completed"; } +void MainWindow::setInitialActiveFile(const QString &filePath) +{ + qCDebug(appLog) << "MainWindow::setInitialActiveFile - file:" << filePath; + if (m_central && !filePath.isEmpty()) { + m_central->docPage()->setActiveTabByFilePath(filePath); + } +} + MainWindow *MainWindow::windowContainSheet(DocSheet *sheet) { qCDebug(appLog) << "Finding window containing sheet:" << (sheet ? sheet->filePath() : "null"); diff --git a/reader/MainWindow.h b/reader/MainWindow.h index 2b08e9d9..aa18c4ba 100644 --- a/reader/MainWindow.h +++ b/reader/MainWindow.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -70,6 +70,13 @@ class MainWindow : public Dtk::Widget::DMainWindow */ void resizeFullTitleWidget(); + /** + * @brief setInitialActiveFile + * 设置初始打开后需要激活的文件,用于恢复上次激活的标签页 + * @param filePath 文件路径 + */ + void setInitialActiveFile(const QString &filePath); + /** * @brief 更新TAB控件顺序 * @param orderlst diff --git a/reader/browser/SheetBrowser.cpp b/reader/browser/SheetBrowser.cpp index 5c7b7043..73e8f12f 100644 --- a/reader/browser/SheetBrowser.cpp +++ b/reader/browser/SheetBrowser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 ~ 2026 Uniontech Software Technology Co.,Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. // SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -222,6 +222,7 @@ void SheetBrowser::init(SheetOperation &operation, const QSet &bookmarks) m_hasLoaded = true; qCInfo(appLog) << "SheetBrowser initialized successfully, initial page:" << m_initPage; + qCDebug(appLog) << "init done m_initPage=" << m_initPage << "currentPage=" << operation.currentPage << "hasLoaded=" << m_hasLoaded << "scaleMode=" << operation.scaleMode; } void SheetBrowser::setMouseShape(const Dr::MouseShape &shape) @@ -693,6 +694,7 @@ void SheetBrowser::onRemoveIconAnnotSelect() void SheetBrowser::onInit() { + qCDebug(appLog) << "onInit enter m_initPage=" << m_initPage << "hasLoaded=" << m_hasLoaded; qCDebug(appLog) << "SheetBrowser::onInit() - Starting init"; if (1 != m_initPage) { setCurrentPage(m_initPage); @@ -1086,7 +1088,7 @@ void SheetBrowser::deform(SheetOperation &operation) setSceneRect(0, 0, maxWidth, maxHeight); if (page > 0 && page <= m_items.count()) { - qCDebug(appLog) << "SheetBrowser::deform() - Setting scroll bar value for page:" << page; + qCDebug(appLog) << "deform set vbar page=" << page << "y=" << m_items[page - 1]->getTopLeftPos().y(); verticalScrollBar()->setValue(static_cast(m_items[page - 1]->getTopLeftPos().y())); horizontalScrollBar()->setValue(static_cast(m_items[page - 1]->getTopLeftPos().x())); } @@ -1113,6 +1115,7 @@ bool SheetBrowser::hasLoaded() void SheetBrowser::resizeEvent(QResizeEvent *event) { + qCDebug(appLog) << "resizeEvent hasLoaded=" << m_hasLoaded << "scaleMode=" << (m_sheet ? m_sheet->operation().scaleMode : -1) << "newsize=" << event->size(); // qCDebug(appLog) << "SheetBrowser::resizeEvent() - Starting resize event"; if (hasLoaded() && m_sheet->operation().scaleMode != Dr::ScaleFactorMode) { // qCDebug(appLog) << "SheetBrowser::resizeEvent() - Has loaded, deforming"; @@ -1725,6 +1728,7 @@ int SheetBrowser::currentScrollValueForPage() void SheetBrowser::setCurrentPage(int page) { + qCDebug(appLog) << "setCurrentPage(" << page << ") curPage=" << m_currentPage << "vbar[" << (verticalScrollBar() ? verticalScrollBar()->minimum() : -1) << (verticalScrollBar() ? verticalScrollBar()->maximum() : -1) << (verticalScrollBar() ? verticalScrollBar()->value() : -1) << "]"; // qCDebug(appLog) << "SheetBrowser::setCurrentPage() - Setting current page to:" << page; if (page < 1 || page > allPages()) { qCWarning(appLog) << "Invalid page number:" << page << "max pages:" << allPages(); @@ -1897,6 +1901,7 @@ void SheetBrowser::dragEnterEvent(QDragEnterEvent *event) void SheetBrowser::showEvent(QShowEvent *event) { + qCDebug(appLog) << "showEvent scheduling onInit +100ms"; // qCDebug(appLog) << "SheetBrowser::showEvent() - Showing event"; QTimer::singleShot(100, this, SLOT(onInit())); @@ -2103,6 +2108,7 @@ void SheetBrowser::handleFindFinished(int searchcnt) void SheetBrowser::curpageChanged(int curpage) { + qCDebug(appLog) << "curpageChanged(" << curpage << ") prev=" << m_currentPage; qCDebug(appLog) << "SheetBrowser::curpageChanged() - Current page changed"; if (m_currentPage != curpage) { m_currentPage = curpage; @@ -2441,11 +2447,16 @@ float SheetBrowser::getScrollPosition() void SheetBrowser::restoreScrollPosition(float position) { - qCDebug(appLog) << "Restoring scroll position:" << position; QScrollBar *vBar = verticalScrollBar(); + int vmin = vBar ? vBar->minimum() : -1; + int vmax = vBar ? vBar->maximum() : -1; + int vcur = vBar ? vBar->value() : -1; + qCDebug(appLog) << "restoreScrollPosition(" << position << ") vbar[" << vmin << vmax << vcur << "]"; if (!vBar || vBar->maximum() <= vBar->minimum()) { + qCDebug(appLog) << "restoreScrollPosition SKIP (range not ready)"; return; } int value = vBar->minimum() + static_cast(position * (vBar->maximum() - vBar->minimum())); vBar->setValue(value); + qCDebug(appLog) << "restoreScrollPosition set value=" << value << "-> after val=" << vBar->value(); } diff --git a/reader/main.cpp b/reader/main.cpp index 4b6901fc..ff132430 100755 --- a/reader/main.cpp +++ b/reader/main.cpp @@ -24,6 +24,7 @@ #include #include #include +#include DGUI_USE_NAMESPACE DWIDGET_USE_NAMESPACE @@ -110,6 +111,7 @@ int main(int argc, char *argv[]) // 这是第一个实例(没有其他 deepin-reader 在运行),恢复上次的标签页组 // 不管命令行是否指定了文件,都恢复之前的标签页 // 注意:当前仅恢复 windowIndex=0 的标签页组(多窗口场景的完整恢复待后续优化) + QString initialActiveFile; { int savedActiveIndex = 0; QStringList restoredFiles = Database::instance()->readTabGroup(0, savedActiveIndex); @@ -132,21 +134,43 @@ int main(int argc, char *argv[]) localArguments.append(arg); } - // 合并文件列表:先恢复历史标签页,再把用户指定的文件放到末尾(成为活动标签页) - // 如果用户指定的文件已在恢复列表中,先移除再追加到末尾 + // 合并文件列表:保留历史标签页及其拖拽后的顺序,仅追加新打开的文件 + // 这样重新打开相同文件时能保持上次的标签顺序;打开新文件时历史不会丢失 QStringList allFiles = validRestored; - int existingCount = 0; + QSet restoredSet(validRestored.begin(), validRestored.end()); + int newFileCount = 0; for (const QString &fp : localArguments) { - if (allFiles.removeAll(fp) > 0) - existingCount++; - if (QFile::exists(fp)) + if (QFile::exists(fp) && !restoredSet.contains(fp)) { allFiles.append(fp); + newFileCount++; + } } - arguments = allFiles; - int newFileCount = localArguments.size() - existingCount; - qCInfo(appLog) << "Restoring" << validRestored.size() << "tabs from last session" - << "+" << newFileCount << "new files"; + + // 计算需要激活的标签页: + // - 用户指定了文件时,激活用户指定的第一个有效文件(优先响应用户意图) + // - 用户未指定文件时,恢复上次激活的标签页(按保存时的路径定位) + if (!localArguments.isEmpty()) { + for (const QString &fp : localArguments) { + if (QFile::exists(fp) && restoredSet.contains(fp)) { + initialActiveFile = fp; + break; + } + } + // 指定的文件不在历史中(新追加的),激活最后一个新文件 + if (initialActiveFile.isEmpty() && newFileCount > 0) { + initialActiveFile = allFiles.last(); + } + } else if (savedActiveIndex >= 0 && savedActiveIndex < restoredFiles.size()) { + QString savedActivePath = restoredFiles.at(savedActiveIndex); + if (restoredSet.contains(savedActivePath)) + initialActiveFile = savedActivePath; + } + + int existingCount = allFiles.size() - newFileCount; + qCInfo(appLog) << "Restoring" << existingCount << "tabs from last session" + << "+" << newFileCount << "new files" + << "active:" << initialActiveFile; } } @@ -169,6 +193,12 @@ int main(int argc, char *argv[]) MainWindow *w = MainWindow::createWindow(arguments); w->winId(); qApp->setAttribute(Qt::AA_ForceRasterWidgets, false); + + // 恢复上次激活的标签页(需在事件循环启动前设置,以覆盖 insertSheet 的延时 setCurrentIndex) + if (!initialActiveFile.isEmpty()) { + w->setInitialActiveFile(initialActiveFile); + } + w->show(); qCDebug(appLog) << __FUNCTION__ << "主窗口已创建并显示"; diff --git a/reader/uiframe/CentralDocPage.cpp b/reader/uiframe/CentralDocPage.cpp index 851b3d1e..5c3fbdb6 100644 --- a/reader/uiframe/CentralDocPage.cpp +++ b/reader/uiframe/CentralDocPage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. // SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -533,6 +533,40 @@ QList CentralDocPage::getSheets() return m_tabBar->getSheets(); } +void CentralDocPage::setActiveTabByFilePath(const QString &filePath) +{ + qCInfo(appLog) << "setActiveTabByFilePath - file:" << filePath; + if (!m_tabBar || filePath.isEmpty()) + return; + + // 设置 m_delayIndex,使后续 onSetCurrentIndex 延时定时器激活正确的标签 + m_tabBar->setPendingActiveFile(filePath); + + int idx = m_tabBar->indexOfFilePath(filePath); + if (idx < 0) + return; + + if (m_tabBar->currentIndex() != idx) { + // 标签栏索引不同,切换会触发 currentChanged → onTabChanged → 内容自动切换 + m_tabBar->setCurrentIndex(idx); + } else { + // 标签栏索引已正确,但内容区可能不一致 + // (addFileAsync 每次都调用 setCurrentWidget,导致内容区停留在最后一个文档) + // 此时 setCurrentIndex(idx) 不会触发 currentChanged,需要同步触发当前标签页选中文档的渲染 + DocSheet *sheet = getSheet(filePath); + if (sheet && m_stackedLayout->currentWidget() != sheet) { + QPointer prevSheet = qobject_cast(m_stackedLayout->currentWidget()); + if (prevSheet && prevSheet != sheet && prevSheet->opened()) { + prevSheet->saveCurrentViewState(); + } + m_stackedLayout->setCurrentWidget(sheet); + sheet->restoreSavedViewState(); + sheet->defaultFocus(); + emit sigCurSheetChanged(sheet); + } + } +} + bool CentralDocPage::saveCurrent() { qCDebug(appLog) << "Attempting to save current document"; diff --git a/reader/uiframe/CentralDocPage.h b/reader/uiframe/CentralDocPage.h index db6a9348..3f36c66e 100644 --- a/reader/uiframe/CentralDocPage.h +++ b/reader/uiframe/CentralDocPage.h @@ -1,4 +1,4 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. // SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -126,6 +126,13 @@ class CentralDocPage : public BaseWidget */ QList getSheets(); + /** + * @brief setActiveTabByFilePath + * 设置需要激活的标签页(按文件路径),用于批量打开后恢复上次的激活位置 + * @param filePath 文件路径 + */ + void setActiveTabByFilePath(const QString &filePath); + /** * @brief getCurSheet * 返回当前显示的sheet,不存在返回nullptr diff --git a/reader/uiframe/DocSheet.cpp b/reader/uiframe/DocSheet.cpp index dddd17cb..e991f2d7 100644 --- a/reader/uiframe/DocSheet.cpp +++ b/reader/uiframe/DocSheet.cpp @@ -400,7 +400,10 @@ void DocSheet::setBookMark(int index, int state) m_browser->setBookMark(index, state); - setBookmarkChanged(true); + Database::instance()->saveBookmarks(filePath(), m_bookmarks); + Database::instance()->flushToDisk(); + m_bookmarkChanged = false; + qCDebug(appLog) << "setBookMark end"; } @@ -423,7 +426,10 @@ void DocSheet::setBookMarks(const QList &indexlst, int state) if (!state) showTips(tr("The bookmark has been removed")); - setBookmarkChanged(true); + Database::instance()->saveBookmarks(filePath(), m_bookmarks); + Database::instance()->flushToDisk(); + m_bookmarkChanged = false; + qCDebug(appLog) << "setBookMarks end"; } @@ -1268,6 +1274,8 @@ void DocSheet::onSideAniFinished() void DocSheet::onOpened(deepin_reader::Document::Error error) { + qCInfo(appLog) << "onOpened enter error=" << error << "restored=" << m_restoredFromState + << "currentPage=" << m_operation.currentPage << "scrollPos=" << m_operation.scrollPosition; qCDebug(appLog) << "onOpened"; if (deepin_reader::Document::NeedPassword == error) { qCDebug(appLog) << "onOpened NeedPassword"; @@ -1292,12 +1300,21 @@ void DocSheet::onOpened(deepin_reader::Document::Error error) } m_browser->init(m_operation, m_bookmarks); + qCInfo(appLog) << "onOpened after init: restored=" << m_restoredFromState + << "currentPage=" << m_operation.currentPage << "scrollPos=" << m_operation.scrollPosition + << "sidebarW=" << m_operation.sidebarWidth << "changed=" << m_operation.sidebarWidthChanged + << "sidebarVisible=" << m_operation.sidebarVisible << "scaleMode=" << m_operation.scaleMode; // 恢复滚动位置 if (m_restoredFromState && m_operation.scrollPosition > 0.0f) { + qCDebug(appLog) << "onOpened scheduling restoreScrollPosition +" << kRestoreScrollDelayMs << "ms"; // 延迟恢复滚动位置(等 deform 和布局完成后) QTimer::singleShot(kRestoreScrollDelayMs, this, [this]() { + qCDebug(appLog) << "onOpened restore timer FIRE currentPage=" << m_operation.currentPage + << "scrollPos=" << m_operation.scrollPosition; m_browser->restoreScrollPosition(m_operation.scrollPosition); + qCDebug(appLog) << "onOpened after restoreScrollPosition currentPage=" << m_operation.currentPage + << "browserCurPage=" << m_browser->currentPage(); // 显示恢复提示条 m_needsRestoreTip = true; emit sigShowRestoreTip(this); @@ -1474,6 +1491,7 @@ void DocSheet::docBasicInfo(deepin_reader::FileInfo &tFileInfo) void DocSheet::onBrowserPageChanged(int page) { + qCDebug(appLog) << "onBrowserPageChanged" << page << "prev currentPage=" << m_operation.currentPage; qCDebug(appLog) << "onBrowserPageChanged"; if (m_operation.currentPage != page) { m_operation.currentPage = page; @@ -1518,6 +1536,14 @@ void DocSheet::onBrowserOperaAnnotation(int type, int index, deepin_reader::Anno qCDebug(appLog) << "onBrowserOperaAnnotation"; m_sidebar->handleAnntationMsg(type, index, anno); setDocumentChanged(true); + + // 注释变化后立即触发自动保存(不等待 30 秒),确保尽快落盘 + // 注意:不在 UI 回调中直接调 renderer->save(),因为 DPdfDoc::save() + // 会做整个 PDF 重写 + fsync,大文件会导致明显卡顿 + // 使用 3 秒短间隔触发,兼顾及时落盘和 UI 流畅度 + if (m_autoSaveTimer) { + m_autoSaveTimer->start(3000); + } } void DocSheet::prepareSearch() @@ -1628,18 +1654,26 @@ void DocSheet::setAlive(bool alive) if (Database::instance()->readOperation(this)) { qCInfo(appLog) << "read from database config"; + qCInfo(appLog) << "setAlive readOperation HIT currentPage=" << m_operation.currentPage + << "scrollPos=" << m_operation.scrollPosition; m_restoredFromState = true; } else if (Database::instance()->matchOperationByContent(QFileInfo(m_filePath), this)) { // 文件移动/重命名后通过内容特征匹配恢复状态 qCInfo(appLog) << "read from content match config"; + qCInfo(appLog) << "setAlive matchByContent HIT currentPage=" << m_operation.currentPage + << "scrollPos=" << m_operation.scrollPosition; m_restoredFromState = true; } else if (readLastFileOperation()) { qCInfo(appLog) << "read from last operation file config"; + qCInfo(appLog) << "setAlive readLastFileOperation currentPage=" << m_operation.currentPage + << "scrollPos=" << m_operation.scrollPosition; } else { qCInfo(appLog) << "read from default config"; + qCInfo(appLog) << "setAlive default currentPage=" << m_operation.currentPage; } Database::instance()->readBookmarks(m_filePath, m_bookmarks); + qCInfo(appLog) << "setAlive readBookmarks(" << m_filePath << ") count=" << m_bookmarks.count(); } else { qCDebug(appLog) << "setAlive alive"; @@ -1664,10 +1698,26 @@ void DocSheet::setAlive(bool alive) m_autoSaveTimer->stop(); } + if (m_documentChanged && m_renderer) { + if (m_renderer->save()) { + m_documentChanged = false; + m_sidebar->changeResetModelData(); + } else { + qCWarning(appLog) << "Failed to save document annotations on close for:" << m_filePath; + } + } + // 关闭时重新计算内容哈希(文件可能已修改) m_cachedContentHash = Database::computeContentHash(m_filePath); Database::instance()->saveOperation(this, m_cachedContentHash); + if (m_bookmarkChanged) { + Database::instance()->saveBookmarks(filePath(), m_bookmarks); + m_bookmarkChanged = false; + } + + Database::instance()->flushToDisk(); + g_lock.lockForWrite(); int index = g_uuidList.indexOf(m_uuid); @@ -2004,6 +2054,48 @@ void DocSheet::onAutoSave() m_cachedContentHash = Database::computeContentHash(m_filePath); } Database::instance()->saveOperation(this, m_cachedContentHash); + + // 兜底保存书签(正常情况 setBookMark 已立即落盘,此处分防其他路径设的脏标记) + if (m_bookmarkChanged) { + Database::instance()->saveBookmarks(filePath(), m_bookmarks); + m_bookmarkChanged = false; + } + + // 保存文档注释(高亮、文本标注等),防止异常退出时注释丢失 + if (m_documentChanged) { + if (m_renderer && m_renderer->save()) { + m_documentChanged = false; + m_sidebar->changeResetModelData(); + } else { + qCWarning(appLog) << "Auto-save: failed to save document annotations for:" << m_filePath; + } + } + + CentralDocPage *docPage = qobject_cast(parent()); + if (docPage && docPage->getCurSheet() == this) { + QList sheets = docPage->getSheets(); + if (!sheets.isEmpty()) { + MainWindow *mainWnd = qobject_cast(docPage->topLevelWidget()); + int windowIndex = mainWnd ? MainWindow::m_list.indexOf(mainWnd) : -1; + if (windowIndex >= 0) { + QStringList filePaths; + int activeIndex = 0; + for (int i = 0; i < sheets.size(); ++i) { + filePaths.append(sheets[i]->filePath()); + if (sheets[i] == this) + activeIndex = i; + } + Database::instance()->saveTabGroup(windowIndex, filePaths, activeIndex); + } + } + } + + Database::instance()->flushToDisk(); + + // 保存完成后重置定时器间隔为 30 秒(注释变化时临时设为 3 秒) + if (m_autoSaveTimer) { + m_autoSaveTimer->setInterval(30000); + } } bool DocSheet::needsRestoreTip() const diff --git a/reader/uiframe/DocTabBar.cpp b/reader/uiframe/DocTabBar.cpp index f15bf87b..c44cdd2c 100644 --- a/reader/uiframe/DocTabBar.cpp +++ b/reader/uiframe/DocTabBar.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2019 ~ 2026 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -77,6 +77,23 @@ int DocTabBar::indexOfFilePath(const QString &filePath) return -1; } +void DocTabBar::setPendingActiveFile(const QString &filePath) +{ + qCDebug(appLog) << "DocTabBar::setPendingActiveFile - file:" << filePath; + if (filePath.isEmpty()) + return; + + int idx = indexOfFilePath(filePath); + if (idx >= 0) { + // 覆盖 insertSheet 设置的 m_delayIndex,待延时的 onSetCurrentIndex 触发时生效 + // 这样可恢复上次激活的标签页,而非总是激活最后一个插入的标签 + m_delayIndex = idx; + qCDebug(appLog) << "Set pending active index to" << idx; + } else { + qCDebug(appLog) << "File not in tab bar, pending active unchanged"; + } +} + void DocTabBar::insertSheet(DocSheet *sheet, int index) { if (sheet == nullptr) { @@ -140,19 +157,8 @@ QList DocTabBar::getSheets() sheets.append(sheet); } - if (sheets.isEmpty()) - return sheets; - - //需要按倒序排列 - QList orderSheets; - QList allSheets = DocSheet::getSheets(); - for (int i = allSheets.count() - 1; i >= 0; --i) { - if (sheets.contains(allSheets[i])) - orderSheets.append(allSheets[i]); - } - qCDebug(appLog) << "DocTabBar::getSheets end"; - return orderSheets; + return sheets; } void DocTabBar::updateTabWidth() diff --git a/reader/uiframe/DocTabBar.h b/reader/uiframe/DocTabBar.h index ba8b10e7..08cae75e 100644 --- a/reader/uiframe/DocTabBar.h +++ b/reader/uiframe/DocTabBar.h @@ -1,5 +1,5 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -35,6 +35,16 @@ class DocTabBar : public DTabBar */ int indexOfFilePath(const QString &filePath); + /** + * @brief setPendingActiveFile + * 设置批量打开文件后需要激活的标签页(按文件路径)。 + * 利用 insertSheet 已有的延时 setCurrentIndex 机制(m_delayIndex), + * 覆盖最后一个插入的位置,使上次激活的标签页得以恢复。 + * 必须在事件循环启动前调用(即所有 insertSheet 之后)。 + * @param filePath 需要激活的文件路径 + */ + void setPendingActiveFile(const QString &filePath); + /** * @brief insertSheet * 插入一个sheet,添加对应的tab @@ -59,7 +69,7 @@ class DocTabBar : public DTabBar /** * @brief getSheets - * 获取包含的所有的sheet(会按打开的倒序排列) + * 获取包含的所有的sheet(按标签栏的视觉顺序排列) * @return */ QList getSheets();