Browse Source

LibGUI: Add symlink targets as a column in GFileSystemModel

Also make sure to hide this column by default where we don't expect
to see it.
Andreas Kling 5 years ago
parent
commit
f7b394af7d

+ 1 - 0
Applications/FileManager/main.cpp

@@ -115,6 +115,7 @@ int main(int argc, char** argv)
     tree_view->set_column_hidden(GFileSystemModel::Column::Permissions, true);
     tree_view->set_column_hidden(GFileSystemModel::Column::ModificationTime, true);
     tree_view->set_column_hidden(GFileSystemModel::Column::Inode, true);
+    tree_view->set_column_hidden(GFileSystemModel::Column::SymlinkTarget, true);
     tree_view->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill);
     tree_view->set_preferred_size(150, 0);
     auto directory_view = DirectoryView::construct(splitter);

+ 1 - 0
Libraries/LibGUI/GFilePicker.cpp

@@ -110,6 +110,7 @@ GFilePicker::GFilePicker(Mode mode, const StringView& file_name, const StringVie
     m_view->set_column_hidden(GFileSystemModel::Column::Group, true);
     m_view->set_column_hidden(GFileSystemModel::Column::Permissions, true);
     m_view->set_column_hidden(GFileSystemModel::Column::Inode, true);
+    m_view->set_column_hidden(GFileSystemModel::Column::SymlinkTarget, true);
     m_model->set_root_path(path);
 
     location_textbox->on_return_pressed = [&] {

+ 19 - 0
Libraries/LibGUI/GFileSystemModel.cpp

@@ -68,6 +68,17 @@ bool GFileSystemModel::Node::fetch_data(const String& full_path, bool is_root)
     gid = st.st_gid;
     inode = st.st_ino;
     mtime = st.st_mtime;
+
+    if (S_ISLNK(mode)) {
+        char buffer[PATH_MAX];
+        int length = readlink(full_path.characters(), buffer, sizeof(buffer));
+        if (length < 0) {
+            perror("readlink");
+        } else {
+            symlink_target = String(buffer, length);
+        }
+    }
+
     return true;
 }
 
@@ -360,6 +371,8 @@ GVariant GFileSystemModel::data(const GModelIndex& index, Role role) const
             return node.mtime;
         case Column::Inode:
             return (int)node.inode;
+        case Column::SymlinkTarget:
+            return node.symlink_target;
         }
         ASSERT_NOT_REACHED();
     }
@@ -382,6 +395,8 @@ GVariant GFileSystemModel::data(const GModelIndex& index, Role role) const
             return timestamp_string(node.mtime);
         case Column::Inode:
             return (int)node.inode;
+        case Column::SymlinkTarget:
+            return node.symlink_target;
         }
     }
 
@@ -508,6 +523,8 @@ String GFileSystemModel::column_name(int column) const
         return "Modified";
     case Column::Inode:
         return "Inode";
+    case Column::SymlinkTarget:
+        return "Symlink target";
     }
     ASSERT_NOT_REACHED();
 }
@@ -531,6 +548,8 @@ GModel::ColumnMetadata GFileSystemModel::column_metadata(int column) const
         return { 65, TextAlignment::CenterLeft };
     case Column::Inode:
         return { 60, TextAlignment::CenterRight };
+    case Column::SymlinkTarget:
+        return { 120, TextAlignment::CenterLeft };
     }
     ASSERT_NOT_REACHED();
 }

+ 2 - 0
Libraries/LibGUI/GFileSystemModel.h

@@ -53,6 +53,7 @@ public:
         Permissions,
         ModificationTime,
         Inode,
+        SymlinkTarget,
         __Count,
     };
 
@@ -60,6 +61,7 @@ public:
         ~Node() { close(m_watch_fd); }
 
         String name;
+        String symlink_target;
         size_t size { 0 };
         mode_t mode { 0 };
         uid_t uid { 0 };