@@ -683,17 +683,61 @@ ParsedFlatpakRef parseInstalledFlatpakLine(const QString &line)
683683 const bool isRuntime = token.startsWith (" runtime/" ) || token.contains (" .runtime/" ) || token.contains (" .Platform" );
684684 // If the token already lacks the app/runtime prefix, keep it intact
685685 const bool hasTypePrefix = token.startsWith (" app/" ) || token.startsWith (" runtime/" );
686- return {hasTypePrefix ? token.section (' /' , 1 ) : token, isRuntime};
686+ QString ref = hasTypePrefix ? token.section (' /' , 1 ) : token;
687+ return {ref.trimmed (), isRuntime};
687688 }
688689 }
689690
690691 // Fallback: return the line as-is if it looks like a ref without type prefix
691- const QString fallbackRef = line.contains (' /' ) ? line : QString ();
692+ const QString fallbackRef = line.contains (' /' ) ? line. trimmed () : QString ();
692693 const bool isRuntime = fallbackRef.contains (" .runtime/" ) || fallbackRef.contains (" .Platform" );
693694 return {fallbackRef, isRuntime};
694695}
695696} // namespace
696697
698+ namespace {
699+ struct RemoteLsEntry {
700+ QString version;
701+ QString ref;
702+ QString size;
703+ };
704+
705+ RemoteLsEntry parseRemoteLsLine (const QString &line)
706+ {
707+ RemoteLsEntry entry;
708+
709+ QStringList tabParts = line.split (' \t ' , Qt::SkipEmptyParts);
710+ if (tabParts.size () >= 3 ) {
711+ entry.version = tabParts.at (0 );
712+ entry.ref = tabParts.at (1 );
713+ entry.size = tabParts.last ();
714+ return entry;
715+ }
716+
717+ QStringList tokens = line.split (QRegularExpression (" \\ s+" ), Qt::SkipEmptyParts);
718+ int refIndex = -1 ;
719+ for (int i = 0 ; i < tokens.size (); ++i) {
720+ if (tokens.at (i).count (' /' ) >= 2 ) { // Looks like a Flatpak ref
721+ entry.ref = tokens.at (i);
722+ refIndex = i;
723+ break ;
724+ }
725+ }
726+
727+ if (!entry.ref .isEmpty ()) {
728+ entry.version = tokens.value (0 );
729+ if (refIndex >= 0 && refIndex + 1 < tokens.size ()) {
730+ entry.size = tokens.mid (refIndex + 1 ).join (' ' );
731+ }
732+ return entry;
733+ }
734+
735+ entry.ref = line.trimmed ();
736+ entry.version = entry.ref .section (' /' , -1 );
737+ return entry;
738+ }
739+ } // namespace
740+
697741void MainWindow::refreshPopularApps ()
698742{
699743 qDebug () << " +++" << __PRETTY_FUNCTION__ << " +++" ;
@@ -901,23 +945,12 @@ void MainWindow::displayFilteredFP(QStringList list, bool raw)
901945 ui->treeFlatpak ->setUpdatesEnabled (false );
902946
903947 auto normalizeRef = [](const QString &line) {
904- QStringList parts = line.split (' \t ' );
905-
906- // Remove empty parts that might occur if the line starts with a tab
907- if (!parts.isEmpty () && parts.first ().isEmpty ()) {
908- parts.removeFirst ();
948+ const RemoteLsEntry entry = parseRemoteLsLine (line);
949+ QString ref = entry.ref .trimmed ();
950+ if (ref.startsWith (" app/" ) || ref.startsWith (" runtime/" )) {
951+ ref = ref.section (' /' , 1 ); // Strip leading type segment (app/runtime)
909952 }
910-
911- QString ref;
912- if (parts.size () >= 4 ) {
913- ref = parts.at (2 );
914- } else if (parts.size () >= 2 ) {
915- ref = parts.at (1 );
916- } else {
917- ref = parts.value (0 );
918- }
919-
920- return ref.section (' /' , 1 ); // Strip leading type segment (app/runtime)
953+ return ref;
921954 };
922955
923956 QMutableStringListIterator i (list);
@@ -926,9 +959,24 @@ void MainWindow::displayFilteredFP(QStringList list, bool raw)
926959 i.setValue (normalizeRef (i.next ()));
927960 }
928961 }
962+
963+ auto normalizeForMatch = [](const QString &ref) {
964+ QString normalized = ref.trimmed ();
965+ if (normalized.startsWith (" app/" ) || normalized.startsWith (" runtime/" )) {
966+ normalized = normalized.section (' /' , 1 );
967+ }
968+ return normalized;
969+ };
970+
971+ QSet<QString> refSet;
972+ for (const QString &ref : std::as_const (list)) {
973+ refSet.insert (normalizeForMatch (ref));
974+ }
975+
929976 uint total = 0 ;
930977 for (QTreeWidgetItemIterator it (currentTree); (*it) != nullptr ; ++it) {
931- if (list.contains ((*it)->data (FlatCol::FullName, Qt::UserRole).toString ())) {
978+ const QString itemRef = normalizeForMatch ((*it)->data (FlatCol::FullName, Qt::UserRole).toString ());
979+ if (refSet.contains (itemRef)) {
932980 ++total;
933981 (*it)->setHidden (false );
934982 (*it)->setData (0 , Qt::UserRole, true ); // Displayed flag
@@ -960,6 +1008,11 @@ void MainWindow::displayFilteredFP(QStringList list, bool raw)
9601008 ui->treeFlatpak ->blockSignals (false );
9611009 blockInterfaceFP (false );
9621010 ui->treeFlatpak ->setUpdatesEnabled (true );
1011+
1012+ // Auto-adjust column widths after filter changes for Flatpak tab
1013+ for (int i = 0 ; i < ui->treeFlatpak ->columnCount (); ++i) {
1014+ ui->treeFlatpak ->resizeColumnToContents (i);
1015+ }
9631016}
9641017
9651018void MainWindow::displayPackages ()
@@ -1205,23 +1258,19 @@ void MainWindow::populateFlatpakTree()
12051258
12061259QTreeWidgetItem *MainWindow::createFlatpakItem (const QString &item, const QStringList &installed_all) const
12071260{
1208- QStringList parts = item. split ( ' \t ' );
1261+ const RemoteLsEntry entry = parseRemoteLsLine (item );
12091262
1210- // Remove empty parts that might occur if item starts with \t
1211- if (!parts.isEmpty () && parts.at (0 ).isEmpty ()) {
1212- parts.removeAt (0 );
1213- }
1214-
1215- const bool hasBranchColumn = parts.size () >= 4 ;
1216- const QString ref = hasBranchColumn ? parts.at (2 )
1217- : ((parts.size () >= 2 ) ? parts.at (1 ) : parts.value (0 ));
1218- QString version = parts.value (0 );
1219- if (version.isEmpty ()) {
1263+ QString ref = entry.ref ;
1264+ QString version = entry.version ;
1265+ if (version.isEmpty () || version.contains (' /' )) {
12201266 version = ref.section (' /' , -1 );
12211267 }
1222- const QString branch = hasBranchColumn ? parts.at (1 ) : ref.section (' /' , -1 );
1223- const QString size = parts.last ();
1224- const QString name = ref.section (' /' , 1 );
1268+ const QString size = entry.size ;
1269+ const bool hasTypePrefix = ref.startsWith (" app/" ) || ref.startsWith (" runtime/" );
1270+ const QString name = hasTypePrefix ? ref.section (' /' , 1 ) : ref;
1271+ if (name.isEmpty ()) {
1272+ return nullptr ;
1273+ }
12251274 const QString long_name = name.section (' /' , 0 , 0 );
12261275 const QString short_name = long_name.section (' .' , -1 );
12271276
@@ -1237,7 +1286,6 @@ QTreeWidgetItem *MainWindow::createFlatpakItem(const QString &item, const QStrin
12371286 widget_item->setText (FlatCol::Name, short_name);
12381287 widget_item->setText (FlatCol::LongName, long_name);
12391288 widget_item->setText (FlatCol::Version, version);
1240- widget_item->setText (FlatCol::Branch, branch);
12411289 widget_item->setText (FlatCol::Size, size);
12421290 widget_item->setData (FlatCol::FullName, Qt::UserRole, name);
12431291 widget_item->setData (0 , Qt::UserRole, true );
@@ -2253,7 +2301,7 @@ QStringList MainWindow::listFlatpaks(const QString &remote, const QString &type)
22532301 const bool isUserScope = fpUser.startsWith (" --user" );
22542302
22552303 auto buildRemoteLsCommand = [&](const QString &scope) {
2256- return " flatpak remote-ls " + scope + remote + ' ' + arch_fp + " --columns=ver,branch, ref,installed-size " ;
2304+ return " flatpak remote-ls " + scope + remote + ' ' + arch_fp + " --columns=ver,ref,installed-size " ;
22572305 };
22582306
22592307 QString typeFlag;
0 commit comments