@@ -22,16 +22,26 @@ constexpr bool kDebug = false;
2222
2323} // anonymous namespace
2424
25- SidebarModel::SidebarModel (
26- QObject* parent)
25+ const ConfigKey kLastSelectedFeatureConfigKey = ConfigKey(" [Library]" , " last_selected_feature" );
26+ const ConfigKey kLastSelectedChildConfigKey = ConfigKey(" [Library]" , " last_selected_child" );
27+
28+ SidebarModel::SidebarModel (UserSettingsPointer pConfig, QObject* parent)
2729 : QAbstractItemModel(parent),
2830 m_iDefaultSelectedIndex(0 ),
29- m_pressedUntilClickedTimer(new QTimer(this )) {
31+ m_pConfig(pConfig),
32+ m_pressedUntilClickedTimer(new QTimer(this )),
33+ m_saveTimer(new QTimer(this )) {
3034 m_pressedUntilClickedTimer->setSingleShot (true );
3135 connect (m_pressedUntilClickedTimer,
3236 &QTimer::timeout,
3337 this ,
3438 &SidebarModel::slotPressedUntilClickedTimeout);
39+
40+ m_saveTimer->setSingleShot (true );
41+ connect (m_saveTimer,
42+ &QTimer::timeout,
43+ this ,
44+ &SidebarModel::performSave);
3545}
3646
3747void SidebarModel::addLibraryFeature (LibraryFeature* pFeature) {
@@ -351,19 +361,35 @@ void SidebarModel::clicked(const QModelIndex& index) {
351361 // When triggered by a mouse event pressed() has been
352362 // invoked immediately before. That doesn't matter,
353363 // because we stop any running timer before handling
354- // this event .
364+ // the click .
355365 stopPressedUntilClickedTimer ();
356- if (index.isValid ()) {
357- if (index.internalPointer () == this ) {
358- m_sFeatures[index.row ()]->activate ();
359- } else {
360- TreeItem* pTreeItem = static_cast <TreeItem*>(index.internalPointer ());
361- if (pTreeItem) {
362- LibraryFeature* pFeature = pTreeItem->feature ();
363- DEBUG_ASSERT (pFeature);
364- pFeature->activateChild (index);
365- }
366- }
366+
367+ if (!index.isValid ()) {
368+ return ;
369+ }
370+
371+ // Schedule save for this selection change
372+ scheduleSelectionSave (index);
373+
374+ TreeItem* pTreeItem = static_cast <TreeItem*>(index.internalPointer ());
375+ VERIFY_OR_DEBUG_ASSERT (pTreeItem) {
376+ return ;
377+ }
378+
379+ LibraryFeature* pFeature = pTreeItem->getFeature ();
380+ VERIFY_OR_DEBUG_ASSERT (pFeature) {
381+ return ;
382+ }
383+
384+ if (kDebug ) {
385+ kLogger .debug () << " Activating feature:"
386+ << pFeature->title ();
387+ }
388+
389+ if (index.parent ().isValid ()) {
390+ pFeature->activateChild (index);
391+ } else {
392+ pFeature->activate ();
367393 }
368394}
369395
@@ -614,3 +640,108 @@ void SidebarModel::slotFeatureSelect(LibraryFeature* pFeature,
614640 }
615641 emit selectIndex (ind, scrollTo);
616642}
643+
644+ void SidebarModel::scheduleSelectionSave (const QModelIndex& index) {
645+ if (!index.isValid ()) {
646+ return ;
647+ }
648+ m_pendingSelection = index;
649+ m_saveTimer->stop ();
650+ m_saveTimer->start (3000 );
651+ }
652+
653+ void SidebarModel::performSave () {
654+ if (m_pendingSelection.isValid ()) {
655+ saveSelectionToConfig (m_pendingSelection);
656+ emit saveScrollPosition ();
657+ }
658+ }
659+
660+ void SidebarModel::saveSelectionToConfig (const QModelIndex& index) {
661+ if (!index.isValid () || !m_pConfig) {
662+ return ;
663+ }
664+
665+ TreeItem* pTreeItem = static_cast <TreeItem*>(index.internalPointer ());
666+ VERIFY_OR_DEBUG_ASSERT (pTreeItem) {
667+ return ;
668+ }
669+
670+ LibraryFeature* pFeature = pTreeItem->getFeature ();
671+ VERIFY_OR_DEBUG_ASSERT (pFeature) {
672+ return ;
673+ }
674+
675+ // Save feature icon name for robust matching
676+ QString featureIconName = pFeature->getIconName ();
677+ m_pConfig->setValue (kLastSelectedFeatureConfigKey , featureIconName);
678+
679+ // Save child data if it's a child item
680+ if (index.parent ().isValid ()) {
681+ QVariant childData = index.data (DataRole);
682+ if (childData.isValid ()) {
683+ m_pConfig->setValue (kLastSelectedChildConfigKey , childData);
684+ } else {
685+ m_pConfig->setValue (kLastSelectedChildConfigKey , QVariant ());
686+ }
687+ } else {
688+ // Root feature selected - clear child data
689+ m_pConfig->setValue (kLastSelectedChildConfigKey , QVariant ());
690+ }
691+ }
692+
693+ void SidebarModel::restoreLastSelection () {
694+ if (!m_pConfig) {
695+ return ;
696+ }
697+
698+ QString savedFeatureIcon = m_pConfig->getValueString (kLastSelectedFeatureConfigKey );
699+ if (savedFeatureIcon.isEmpty ()) {
700+ return ;
701+ }
702+
703+ QVariant savedChildData = m_pConfig->getValue (kLastSelectedChildConfigKey );
704+
705+ // Find the feature by icon name
706+ LibraryFeature* pTargetFeature = nullptr ;
707+ int featureIndex = -1 ;
708+ for (int i = 0 ; i < m_sFeatures.size (); ++i) {
709+ if (m_sFeatures[i]->getIconName () == savedFeatureIcon) {
710+ pTargetFeature = m_sFeatures[i];
711+ featureIndex = i;
712+ break ;
713+ }
714+ }
715+
716+ if (!pTargetFeature) {
717+ return ;
718+ }
719+
720+ QModelIndex targetIndex = index (featureIndex, 0 );
721+
722+ // If we have child data, try to find the matching child
723+ if (savedChildData.isValid () && pTargetFeature->getChildModel ()) {
724+ QAbstractItemModel* pChildModel = pTargetFeature->getChildModel ();
725+ const QModelIndexList matches = pChildModel->match (
726+ pChildModel->index (0 , 0 ),
727+ DataRole,
728+ savedChildData,
729+ 1 ,
730+ Qt::MatchExactly);
731+
732+ VERIFY_OR_DEBUG_ASSERT (!matches.isEmpty () && matches.first ().isValid ()) {
733+ // Child not found, select feature root
734+ emit selectIndex (targetIndex, true );
735+ return ;
736+ }
737+
738+ // Translate child index to sidebar index
739+ QModelIndex childIndex = matches.first ();
740+ TreeItem* pTreeItem = static_cast <TreeItem*>(childIndex.internalPointer ());
741+ if (pTreeItem) {
742+ targetIndex = createIndex (childIndex.row (), childIndex.column (), pTreeItem);
743+ }
744+ }
745+
746+ emit selectIndex (targetIndex, true );
747+ }
0 commit comments