mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-06-28 14:35:28 +00:00
Compare commits
139 Commits
ab7e7b9421
...
ce573608d8
Author | SHA1 | Date | |
---|---|---|---|
|
ce573608d8 | ||
|
58450f8f22 | ||
|
4fd70e94a0 | ||
|
054ad3f049 | ||
|
a926372a7c | ||
|
dcbd17359b | ||
|
8ba056abd1 | ||
|
d196abfe47 | ||
|
744d8599ed | ||
|
5e8615e36d | ||
|
a1e5c2b494 | ||
|
402ae03e0b | ||
|
d4a066da31 | ||
|
ccf81c1b0d | ||
|
24d4307b61 | ||
|
6636a22ffd | ||
|
5c2f55663a | ||
|
f5cacef579 | ||
|
4db38919c2 | ||
|
f7bb6975a5 | ||
|
2e4151ca3d | ||
|
f0d5b36a6a | ||
|
588062afbc | ||
|
c5a3dad7a4 | ||
|
21f2c91d69 | ||
|
3e8b382fce | ||
|
874150b017 | ||
|
7360be440a | ||
|
c908c94108 | ||
|
911e366ca9 | ||
|
a58739f30d | ||
|
85c44aa42b | ||
|
02c67b8879 | ||
|
23e41c5aef | ||
|
e419ffb7bd | ||
|
25f445f4d7 | ||
|
972d717816 | ||
|
0e6e3946eb | ||
|
746f9c4247 | ||
|
da4dd182a1 | ||
|
2d6f4b8280 | ||
|
13ae2e6fd3 | ||
|
9dbe8569c3 | ||
|
3f17995dbc | ||
|
9edcd430c3 | ||
|
78e22d0448 | ||
|
e19923adf8 | ||
|
c57c9f57ae | ||
|
2288345ba2 | ||
|
88a941ff74 | ||
|
d98967693e | ||
|
33aedd51fd | ||
|
00019651b6 | ||
|
cc9374e87d | ||
|
d1742d078d | ||
|
0c5d28bcd6 | ||
|
9698bcaccf | ||
|
c036a1178c | ||
|
a501907f70 | ||
|
c3d4cbdd0e | ||
|
095f699da1 | ||
|
13e0bba7ff | ||
|
0f52276179 | ||
|
3efa7fa6e8 | ||
|
22d214e818 | ||
|
30194a1fdc | ||
|
bb9231b6a0 | ||
|
6bd4e06faa | ||
|
c960cfa439 | ||
|
e5e53ea2c9 | ||
|
10d823295a | ||
|
d4bc511f69 | ||
|
89ae1730b9 | ||
|
fceb9ee923 | ||
|
fa7b77fe6c | ||
|
626a04509c | ||
|
16b81477b3 | ||
|
12980ee1bd | ||
|
e4deb16def | ||
|
37634b960b | ||
|
fcbfcd4c5d | ||
|
6d47c4c1f3 | ||
|
0ff13a90f0 | ||
|
3494cd79df | ||
|
c674046e29 | ||
|
da79c2f3bf | ||
|
7e6af9d61d | ||
|
d1437e9fd6 | ||
|
41b3bed264 | ||
|
a157d6d07f | ||
|
e845387f80 | ||
|
8ce91a54b6 | ||
|
b72f62f65c | ||
|
0a78f8cee2 | ||
|
a0a54a72dd | ||
|
2e9fca4510 | ||
|
c19589fc43 | ||
|
1906daebd8 | ||
|
1d9332c6c9 | ||
|
62c4a979ba | ||
|
2e59a031c1 | ||
|
7c12611bd0 | ||
|
6997f3a5eb | ||
|
b85d0773a4 | ||
|
cbee15bd21 | ||
|
13f3ec9f35 | ||
|
41c0c1f624 | ||
|
f0d250d0cc | ||
|
7776f13c69 | ||
|
61032380f3 | ||
|
6d47fce9c9 | ||
|
ce35cd2441 | ||
|
c7d515942b | ||
|
3c23786c8c | ||
|
3153252095 | ||
|
4511a7ab9b | ||
|
0aab4b8458 | ||
|
a9ca62f771 | ||
|
56a9882610 | ||
|
6dd4f7ef9f | ||
|
bfde9badb5 | ||
|
5a7347867f | ||
|
356570978c | ||
|
a011010567 | ||
|
7e427c0ba7 | ||
|
26480b7017 | ||
|
3aca4ce418 | ||
|
4dd0e6aa57 | ||
|
3bdf93975a | ||
|
ced25b64e3 | ||
|
08ec5c4b45 | ||
|
1ff52d2e46 | ||
|
f92141abb8 | ||
|
facd45d7c2 | ||
|
f2b853ca5b | ||
|
d7b9b3722f | ||
|
df0878e3ce | ||
|
cc6378b337 | ||
|
eb285df21d |
|
@ -29,7 +29,7 @@ git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
|
|||
|
||||
## Runtime dependencies
|
||||
- [Bubblewrap](https://github.com/projectatomic/bubblewrap) installed. Used for security reasons.
|
||||
- [Tracker (including tracker-miners)](https://gitlab.gnome.org/GNOME/tracker) properly set up and with all features enabled. Used for fast search and metadata extraction, starred files and batch renaming.
|
||||
- [LocalSearch](https://gitlab.gnome.org/GNOME/localsearch) properly set up and with all features enabled. Used for fast search and metadata extraction, starred files and batch renaming.
|
||||
|
||||
## Discourse
|
||||
|
||||
|
|
|
@ -29,8 +29,12 @@
|
|||
"--talk-name=org.gnome.Settings",
|
||||
"--talk-name=org.gnome.Console",
|
||||
"--env=DCONF_USER_CONFIG_DIR=.config/dconf",
|
||||
"--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Audio",
|
||||
"--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Documents",
|
||||
"--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:FileSystem",
|
||||
"--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Documents"
|
||||
"--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Pictures",
|
||||
"--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Music",
|
||||
"--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Video"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
|
@ -67,11 +71,11 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "tracker-miners",
|
||||
"name": "localsearch",
|
||||
"buildsystem": "meson",
|
||||
"cleanup": [
|
||||
"/etc",
|
||||
"/libexec/tracker-3",
|
||||
"/libexec/localsearch-3",
|
||||
"/share/dbus-1/services/org.freedesktop.Tracker3.Miner.Extract.service",
|
||||
"/share/dbus-1/services/org.freedesktop.Tracker3.Miner.Files.service",
|
||||
"/share/dbus-1/services/org.freedesktop.Tracker3.Miner.Files.Control.service"
|
||||
|
@ -90,8 +94,8 @@
|
|||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/tracker-miners.git",
|
||||
"branch": "master"
|
||||
"url": "https://gitlab.gnome.org/GNOME/localsearch.git",
|
||||
"branch": "main"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -4,6 +4,7 @@ leak:libfontconfig.so.1
|
|||
leak:libEGL_mesa.so.0
|
||||
leak:libtracker-sparql-3.0.so.0
|
||||
leak:gtk_init
|
||||
leak:adw_init
|
||||
leak:xdg_mime_init
|
||||
leak:gtk_at_context_create
|
||||
leak:libim-ibus.so
|
|
@ -1,11 +1,12 @@
|
|||
# Files needed for running Tracker inside the Flatpak sandbox, for systems
|
||||
# which don't have a suitable version of Tracker in the host OS.
|
||||
# Files needed for running LocalSearch (historically known as Tracker) inside
|
||||
# the Flatpak sandbox, for systems which don't have a suitable version of
|
||||
# LocalSearch in the host OS.
|
||||
#
|
||||
# We must export the .service files from the sandbox so they work on the
|
||||
# session bus. This means the Tracker domain name must correspond with the
|
||||
# session bus. This means the LocalSearch domain name must correspond with the
|
||||
# application ID.
|
||||
|
||||
domain_ontologies_dir = get_option('datadir') / 'tracker3' / 'domain-ontologies'
|
||||
domain_ontologies_dir = get_option('datadir') / 'localsearch3' / 'domain-ontologies'
|
||||
dbus_services_dir = get_option('datadir') / 'dbus-1' / 'services'
|
||||
|
||||
tracker_domain_config = configuration_data()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[D-BUS Service]
|
||||
Name=@application_id@.Tracker3.Miner.Extract
|
||||
Exec=/app/libexec/tracker-extract-3 --domain-ontology @domain_rule@
|
||||
Exec=/app/libexec/localsearch-extractor-3 --domain-ontology @domain_rule@
|
||||
|
||||
# Miner details needed for tracker-control
|
||||
# Miner details needed for localsearch-control
|
||||
Path=/org/freedesktop/Tracker3/Miner/Extract
|
||||
NameSuffix=Miner.Files
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[D-BUS Service]
|
||||
Name=@application_id@.Tracker3.Miner.Files
|
||||
Exec=/app/libexec/tracker-miner-fs-3 --domain-ontology @domain_rule@ --initial-sleep 0
|
||||
Exec=/app/libexec/localsearch-3 --domain-ontology @domain_rule@ --initial-sleep 0
|
||||
|
||||
# Miner details needed for tracker-control
|
||||
# Miner details needed for localsearch-control
|
||||
Path=/org/freedesktop/Tracker3/Miner/Files
|
||||
NameSuffix=Miner.Files
|
||||
|
|
|
@ -36,15 +36,18 @@ src/nautilus-file-undo-operations.c
|
|||
src/nautilus-file-utilities.c
|
||||
src/nautilus-filename-utilities.c
|
||||
src/nautilus-global-preferences.c
|
||||
src/nautilus-internal-place-file.c
|
||||
src/nautilus-list-view.c
|
||||
src/nautilus-location-banner.c
|
||||
src/nautilus-location-entry.c
|
||||
src/nautilus-main.c
|
||||
src/nautilus-mime-actions.c
|
||||
src/nautilus-network-address-bar.c
|
||||
src/nautilus-network-cell.c
|
||||
src/nautilus-network-view.c
|
||||
src/nautilus-new-folder-dialog.c
|
||||
src/nautilus-operations-ui-manager.c
|
||||
src/nautilus-pathbar.c
|
||||
src/nautilus-places-view.c
|
||||
src/nautilus-preferences-window.c
|
||||
src/nautilus-program-choosing.c
|
||||
src/nautilus-progress-info.c
|
||||
|
@ -80,6 +83,8 @@ src/resources/ui/nautilus-files-view.ui
|
|||
src/resources/ui/nautilus-grid-cell.ui
|
||||
src/resources/ui/nautilus-history-controls.ui
|
||||
src/resources/ui/nautilus-name-cell.ui
|
||||
src/resources/ui/nautilus-network-address-bar.ui
|
||||
src/resources/ui/nautilus-network-cell.ui
|
||||
src/resources/ui/nautilus-operations-ui-manager-request-passphrase.ui
|
||||
src/resources/ui/nautilus-pathbar-context-menu.ui
|
||||
src/resources/ui/nautilus-preferences-window.ui
|
||||
|
@ -92,10 +97,5 @@ src/resources/ui/nautilus-toolbar.ui
|
|||
src/resources/ui/nautilus-toolbar-view-menu.ui
|
||||
src/resources/ui/nautilus-view-controls.ui
|
||||
src/resources/ui/nautilus-window.ui
|
||||
src/gtk/nautilusgtkplacesview.c
|
||||
src/gtk/nautilusgtkplacesviewrow.c
|
||||
src/gtk/nautilusgtkplacesviewrow.ui
|
||||
src/gtk/nautilusgtkplacesview.ui
|
||||
src/gtk/nautilusgtkbookmarksmanager.c
|
||||
src/gtk/nautilusgtkplacessidebar.c
|
||||
src/gtk/nautilusgtksidebarrow.ui
|
||||
|
|
200
po/eu.po
200
po/eu.po
|
@ -12,7 +12,7 @@
|
|||
msgid ""
|
||||
msgstr "Project-Id-Version: nautilus master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/nautilus/issues\n"
|
||||
"POT-Creation-Date: 2024-02-22 20:12+0000\n"
|
||||
"POT-Creation-Date: 2024-04-04 12:02+0000\n"
|
||||
"PO-Revision-Date: 2024-02-25 10:00+0100\n"
|
||||
"Last-Translator: Asier Sarasua Garmendia <asiersarasua@ni.eus>\n"
|
||||
"Language-Team: Basque <librezale@librezale.eus>\n"
|
||||
|
@ -55,16 +55,16 @@ msgid ""
|
|||
"can be extended with plugins and scripts."
|
||||
msgstr "Nautilus aplikazioak fitxategi-kudeatzaile baten oinarrizko funtzioak eta askoz gehiago ditu. Zure fitxategiak eta karpetak bilatu eta kudeatu ditzake, bai lokalean baita sarean ere. Datuak euskarri aldagarrietatik irakurri eta idatzi ditzake, scriptak exekutatu eta aplikazioak abiarazi. Hiru ikuspegi ditu: ikonoen sareta, ikonoen zerrenda eta zuhaitzaren zerrenda. Bere gaitasunak hedatu daitezke pluginen eta scripten bidez."
|
||||
|
||||
#: data/org.gnome.Nautilus.metainfo.xml.in.in:52 src/nautilus-view.c:150
|
||||
#: data/org.gnome.Nautilus.metainfo.xml.in.in:53 src/nautilus-view.c:150
|
||||
msgid "Grid View"
|
||||
msgstr "Sareta-ikuspegia"
|
||||
|
||||
#: data/org.gnome.Nautilus.metainfo.xml.in.in:56 src/nautilus-view.c:154
|
||||
#: data/org.gnome.Nautilus.metainfo.xml.in.in:57 src/nautilus-view.c:154
|
||||
#: src/nautilus-view.c:158
|
||||
msgid "List View"
|
||||
msgstr "Zerrenda-ikuspegia"
|
||||
|
||||
#: data/org.gnome.Nautilus.metainfo.xml.in.in:60 src/nautilus-query.c:542
|
||||
#: data/org.gnome.Nautilus.metainfo.xml.in.in:61 src/nautilus-query.c:542
|
||||
#: src/nautilus-search-directory-file.c:177
|
||||
#: src/nautilus-search-directory-file.c:231
|
||||
#: src/nautilus-search-directory-file.c:271
|
||||
|
@ -72,7 +72,7 @@ msgstr "Zerrenda-ikuspegia"
|
|||
msgid "Search"
|
||||
msgstr "Bilatu"
|
||||
|
||||
#: data/org.gnome.Nautilus.metainfo.xml.in.in:64 src/nautilus-bookmark.c:106
|
||||
#: data/org.gnome.Nautilus.metainfo.xml.in.in:65 src/nautilus-bookmark.c:106
|
||||
#: src/nautilus-file.c:4238 src/nautilus-file-utilities.c:75
|
||||
#: src/nautilus-pathbar.c:386 src/gtk/nautilusgtkplacesview.ui:158
|
||||
#: src/gtk/nautilusgtkplacessidebar.c:1435
|
||||
|
@ -970,7 +970,7 @@ msgid "The type of the file."
|
|||
msgstr "Fitxategi mota."
|
||||
|
||||
#: src/nautilus-column-utilities.c:90
|
||||
#: src/resources/ui/nautilus-properties-window.ui:602
|
||||
#: src/resources/ui/nautilus-properties-window.ui:601
|
||||
msgid "Modified"
|
||||
msgstr "Aldatze-data"
|
||||
|
||||
|
@ -987,7 +987,7 @@ msgid "The detailed type of the file."
|
|||
msgstr "Fitxategiaren mota xehea"
|
||||
|
||||
#: src/nautilus-column-utilities.c:106
|
||||
#: src/resources/ui/nautilus-properties-window.ui:564
|
||||
#: src/resources/ui/nautilus-properties-window.ui:563
|
||||
msgid "Accessed"
|
||||
msgstr "Atzitze-data"
|
||||
|
||||
|
@ -996,7 +996,7 @@ msgid "The date the file was accessed."
|
|||
msgstr "Fitxategia atzitu zeneko data."
|
||||
|
||||
#: src/nautilus-column-utilities.c:115
|
||||
#: src/resources/ui/nautilus-properties-window.ui:640
|
||||
#: src/resources/ui/nautilus-properties-window.ui:639
|
||||
msgid "Created"
|
||||
msgstr "Sortze-data"
|
||||
|
||||
|
@ -1040,7 +1040,7 @@ msgid "The date the file was accessed by the user."
|
|||
msgstr "Erabiltzaileak fitxategia atzitu zueneko data."
|
||||
|
||||
#: src/nautilus-column-utilities.c:159 src/nautilus-properties-window.c:741
|
||||
#: src/nautilus-star-cell.c:73
|
||||
#: src/nautilus-star-cell.c:66
|
||||
msgid "Star"
|
||||
msgstr "Izarra"
|
||||
|
||||
|
@ -1817,7 +1817,7 @@ msgid "Deleting Files"
|
|||
msgstr "Fitxategiak ezabatzen"
|
||||
|
||||
#. Translators: %s is a file name formatted for display
|
||||
#: src/nautilus-file-operations.c:2331 src/nautilus-files-view.c:6837
|
||||
#: src/nautilus-file-operations.c:2331 src/nautilus-files-view.c:6874
|
||||
#: src/gtk/nautilusgtkplacessidebar.c:2689
|
||||
#: src/gtk/nautilusgtkplacessidebar.c:2718
|
||||
#, c-format
|
||||
|
@ -1844,7 +1844,7 @@ msgid "Do _not Empty Trash"
|
|||
msgstr "_Ez hustu zakarrontzia"
|
||||
|
||||
#. Translators: %s is a file name formatted for display
|
||||
#: src/nautilus-file-operations.c:2655 src/nautilus-files-view.c:6785
|
||||
#: src/nautilus-file-operations.c:2655 src/nautilus-files-view.c:6822
|
||||
#: src/gtk/nautilusgtkplacessidebar.c:2049
|
||||
#, c-format
|
||||
msgid "Unable to access “%s”"
|
||||
|
@ -2393,39 +2393,39 @@ msgstr[1] "%'d fitxategi “%s”(e)n konprimatuta"
|
|||
msgid "Compressing Files"
|
||||
msgstr "Fitxategiak konprimatzen"
|
||||
|
||||
#: src/nautilus-files-view.c:392
|
||||
#: src/nautilus-files-view.c:390
|
||||
msgid "Searching…"
|
||||
msgstr "Bilatzen…"
|
||||
|
||||
#: src/nautilus-files-view.c:392 src/nautilus-window-slot.c:911
|
||||
#: src/nautilus-files-view.c:390 src/nautilus-window-slot.c:911
|
||||
msgid "Loading…"
|
||||
msgstr "Kargatzen…"
|
||||
|
||||
#: src/nautilus-files-view.c:1874
|
||||
#: src/nautilus-files-view.c:1872
|
||||
msgid "Examples: "
|
||||
msgstr "Adibideak: "
|
||||
|
||||
#: src/nautilus-files-view.c:2931
|
||||
#: src/nautilus-files-view.c:2929
|
||||
msgid "Could not paste files"
|
||||
msgstr "Ezin izan dira fitxategiak itsatsi"
|
||||
|
||||
#: src/nautilus-files-view.c:2932
|
||||
#: src/nautilus-files-view.c:2930
|
||||
msgid "Permissions do not allow pasting files in this directory"
|
||||
msgstr "Baimenek ez dute uzten direktorio honetan fitxategiak itsasten"
|
||||
|
||||
#: src/nautilus-files-view.c:3575 src/nautilus-files-view.c:3622
|
||||
#: src/nautilus-files-view.c:3583 src/nautilus-files-view.c:3630
|
||||
#, c-format
|
||||
msgid "“%s” selected"
|
||||
msgstr "“%s” hautatuta"
|
||||
|
||||
#: src/nautilus-files-view.c:3579
|
||||
#: src/nautilus-files-view.c:3587
|
||||
#, c-format
|
||||
msgid "%'d folder selected"
|
||||
msgid_plural "%'d folders selected"
|
||||
msgstr[0] "Karpeta %'d hautatuta"
|
||||
msgstr[1] "%'d karpeta hautatuta"
|
||||
|
||||
#: src/nautilus-files-view.c:3593
|
||||
#: src/nautilus-files-view.c:3601
|
||||
#, c-format
|
||||
msgid "(containing %'d item)"
|
||||
msgid_plural "(containing %'d items)"
|
||||
|
@ -2433,14 +2433,14 @@ msgstr[0] "(elementu %'d du)"
|
|||
msgstr[1] "(%'d elementu ditu)"
|
||||
|
||||
#. translators: this is preceded with a string of form 'N folders' (N more than 1)
|
||||
#: src/nautilus-files-view.c:3608
|
||||
#: src/nautilus-files-view.c:3616
|
||||
#, c-format
|
||||
msgid "(containing a total of %'d item)"
|
||||
msgid_plural "(containing a total of %'d items)"
|
||||
msgstr[0] "(guztira elementu %'d du)"
|
||||
msgstr[1] "(guztira %'d elementu ditu)"
|
||||
|
||||
#: src/nautilus-files-view.c:3627
|
||||
#: src/nautilus-files-view.c:3635
|
||||
#, c-format
|
||||
msgid "%'d item selected"
|
||||
msgid_plural "%'d items selected"
|
||||
|
@ -2448,7 +2448,7 @@ msgstr[0] "Eementu %'d hautatuta"
|
|||
msgstr[1] "%'d elementu hautatuta"
|
||||
|
||||
#. Folders selected also, use "other" terminology
|
||||
#: src/nautilus-files-view.c:3636
|
||||
#: src/nautilus-files-view.c:3644
|
||||
#, c-format
|
||||
msgid "%'d other item selected"
|
||||
msgid_plural "%'d other items selected"
|
||||
|
@ -2459,7 +2459,7 @@ msgstr[1] "Beste %'d elementu hautatuta"
|
|||
#. * needs to use something other than parentheses. The
|
||||
#. * the message in parentheses is the size of the selected items.
|
||||
#.
|
||||
#: src/nautilus-files-view.c:3651
|
||||
#: src/nautilus-files-view.c:3659
|
||||
#, c-format
|
||||
msgid "(%s)"
|
||||
msgstr "(%s)"
|
||||
|
@ -2471,153 +2471,153 @@ msgstr "(%s)"
|
|||
#. * message about the number of other items and the
|
||||
#. * total size of those items.
|
||||
#.
|
||||
#: src/nautilus-files-view.c:3701
|
||||
#: src/nautilus-files-view.c:3709
|
||||
#, c-format
|
||||
msgid "%s, %s"
|
||||
msgstr "%s, %s"
|
||||
|
||||
#: src/nautilus-files-view.c:3764
|
||||
#: src/nautilus-files-view.c:3772
|
||||
msgid "Search _Settings"
|
||||
msgstr "Bilaketa-e_zarpenak"
|
||||
|
||||
#: src/nautilus-files-view.c:3776
|
||||
#: src/nautilus-files-view.c:3784
|
||||
msgid "Search _Everywhere"
|
||||
msgstr "Bilatu _edonon"
|
||||
|
||||
#: src/nautilus-files-view.c:3813
|
||||
#: src/nautilus-files-view.c:3821
|
||||
msgid "More locations can be added to search in the settings"
|
||||
msgstr "Ezarpenetan kokaleku gehiago gehitu daitezke bilaketak egiteko"
|
||||
|
||||
#. Translators: %s is the name of the search location formatted for display
|
||||
#: src/nautilus-files-view.c:3821
|
||||
#: src/nautilus-files-view.c:3829
|
||||
#, c-format
|
||||
msgid "No matches in “%s”"
|
||||
msgstr "Ez dago bat etortzerik hemen: “%s”"
|
||||
|
||||
#: src/nautilus-files-view.c:3829 src/gtk/nautilusgtkplacesview.ui:193
|
||||
#: src/nautilus-files-view.c:3837 src/gtk/nautilusgtkplacesview.ui:193
|
||||
msgid "No Results Found"
|
||||
msgstr "Ez da emaitzarik aurkitu"
|
||||
|
||||
#: src/nautilus-files-view.c:3834
|
||||
#: src/nautilus-files-view.c:3842
|
||||
msgid "Trash is Empty"
|
||||
msgstr "Zakarrontzia hutsik dago"
|
||||
|
||||
#: src/nautilus-files-view.c:3840
|
||||
#: src/nautilus-files-view.c:3848
|
||||
msgid "No Starred Files"
|
||||
msgstr "Ez dago izardun fitxategirik"
|
||||
|
||||
#: src/nautilus-files-view.c:3846
|
||||
#: src/nautilus-files-view.c:3854
|
||||
msgid "No Recent Files"
|
||||
msgstr "Ez dago azken aldiko fitxategirik"
|
||||
|
||||
#: src/nautilus-files-view.c:3852
|
||||
#: src/nautilus-files-view.c:3860
|
||||
msgid "Folder is Empty"
|
||||
msgstr "Karpeta hutsik dago"
|
||||
|
||||
#: src/nautilus-files-view.c:6011
|
||||
#: src/nautilus-files-view.c:6076
|
||||
msgid "Select Move Destination"
|
||||
msgstr "Hautatu helburua eramateko"
|
||||
|
||||
#: src/nautilus-files-view.c:6015
|
||||
#: src/nautilus-files-view.c:6080
|
||||
msgid "Select Copy Destination"
|
||||
msgstr "Hautatu helburua kopiatzeko"
|
||||
|
||||
#: src/nautilus-files-view.c:6021 src/nautilus-files-view.c:6425
|
||||
#: src/nautilus-files-view.c:6086 src/nautilus-files-view.c:6475
|
||||
#: src/nautilus-properties-window.c:4077
|
||||
#: src/resources/ui/nautilus-files-view-select-items.ui:24
|
||||
msgid "_Select"
|
||||
msgstr "_Hautatu"
|
||||
|
||||
#: src/nautilus-files-view.c:6424
|
||||
#: src/nautilus-files-view.c:6474
|
||||
msgid "Select Extract Destination"
|
||||
msgstr "Hautatu erauzketaren helburua"
|
||||
|
||||
#: src/nautilus-files-view.c:6513
|
||||
#: src/nautilus-files-view.c:6550
|
||||
msgid "Error sending email."
|
||||
msgstr "Errorea mezua bidaltzean"
|
||||
|
||||
#. Translators: %s is a file name formatted for display
|
||||
#: src/nautilus-files-view.c:6811
|
||||
#: src/nautilus-files-view.c:6848
|
||||
#, c-format
|
||||
msgid "Unable to remove “%s”"
|
||||
msgstr "Ezin da “%s” kendu"
|
||||
|
||||
#: src/nautilus-files-view.c:6861
|
||||
#: src/nautilus-files-view.c:6898
|
||||
msgid "Unable to stop drive"
|
||||
msgstr "Ezin da unitatea gelditu"
|
||||
|
||||
#. Translators: %s is a file name formatted for display
|
||||
#: src/nautilus-files-view.c:6972 src/gtk/nautilusgtkplacessidebar.c:2011
|
||||
#: src/nautilus-files-view.c:7009 src/gtk/nautilusgtkplacessidebar.c:2011
|
||||
#: src/gtk/nautilusgtkplacessidebar.c:2915
|
||||
#, c-format
|
||||
msgid "Unable to start “%s”"
|
||||
msgstr "Ezin da “%s” abiatu"
|
||||
|
||||
#: src/nautilus-files-view.c:7956
|
||||
#: src/nautilus-files-view.c:7993
|
||||
#, c-format
|
||||
msgid "New Folder with Selection (%'d Item)"
|
||||
msgid_plural "New Folder with Selection (%'d Items)"
|
||||
msgstr[0] "Karpeta berria hautapenarekin (elementu %'d)"
|
||||
msgstr[1] "Karpeta berria hautapenarekin (%'d elementu)"
|
||||
|
||||
#: src/nautilus-files-view.c:8011
|
||||
#: src/nautilus-files-view.c:8048
|
||||
#, c-format
|
||||
msgid "Open With %s"
|
||||
msgstr "Ireki honekin: %s"
|
||||
|
||||
#: src/nautilus-files-view.c:8022
|
||||
#: src/nautilus-files-view.c:8059
|
||||
msgid "Run"
|
||||
msgstr "Exekutatu"
|
||||
|
||||
#: src/nautilus-files-view.c:8027
|
||||
#: src/nautilus-files-view.c:8064
|
||||
#: src/resources/ui/nautilus-operations-ui-manager-request-passphrase.ui:17
|
||||
msgid "Extract"
|
||||
msgstr "Erauzi"
|
||||
|
||||
#: src/nautilus-files-view.c:8028
|
||||
#: src/nautilus-files-view.c:8065
|
||||
msgid "Extract to…"
|
||||
msgstr "Erauzi hona…"
|
||||
|
||||
#: src/nautilus-files-view.c:8032
|
||||
#: src/nautilus-files-view.c:8069
|
||||
#: src/resources/ui/nautilus-files-view-context-menus.ui:89
|
||||
msgid "Open"
|
||||
msgstr "Ireki"
|
||||
|
||||
#: src/nautilus-files-view.c:8110
|
||||
#: src/nautilus-files-view.c:8147
|
||||
#: src/resources/ui/nautilus-files-view-context-menus.ui:153
|
||||
#: src/gtk/nautilusgtkplacessidebar.c:3345
|
||||
msgid "_Start"
|
||||
msgstr "_Hasi"
|
||||
|
||||
#: src/nautilus-files-view.c:8116 src/gtk/nautilusgtkplacesview.c:1724
|
||||
#: src/nautilus-files-view.c:8153 src/gtk/nautilusgtkplacesview.c:1724
|
||||
msgid "_Connect"
|
||||
msgstr "_Konektatu"
|
||||
|
||||
#: src/nautilus-files-view.c:8122
|
||||
#: src/nautilus-files-view.c:8159
|
||||
msgid "_Start Multi-disk Drive"
|
||||
msgstr "_Abiatu disko anitzeko unitatea"
|
||||
|
||||
#: src/nautilus-files-view.c:8128
|
||||
#: src/nautilus-files-view.c:8165
|
||||
msgid "U_nlock Drive"
|
||||
msgstr "_Desblokeatu unitatea"
|
||||
|
||||
#: src/nautilus-files-view.c:8146
|
||||
#: src/nautilus-files-view.c:8183
|
||||
msgid "Stop Drive"
|
||||
msgstr "Gelditu unitatea"
|
||||
|
||||
#: src/nautilus-files-view.c:8152 src/gtk/nautilusgtkplacessidebar.c:3362
|
||||
#: src/nautilus-files-view.c:8189 src/gtk/nautilusgtkplacessidebar.c:3362
|
||||
msgid "_Safely Remove Drive"
|
||||
msgstr "_Kendu unitatea modu seguruan"
|
||||
|
||||
#: src/nautilus-files-view.c:8158 src/gtk/nautilusgtkplacesview.c:1713
|
||||
#: src/nautilus-files-view.c:8195 src/gtk/nautilusgtkplacesview.c:1713
|
||||
msgid "_Disconnect"
|
||||
msgstr "_Deskonektatu"
|
||||
|
||||
#: src/nautilus-files-view.c:8164
|
||||
#: src/nautilus-files-view.c:8201
|
||||
msgid "_Stop Multi-disk Drive"
|
||||
msgstr "_Gelditu disko anitzeko unitatea"
|
||||
|
||||
#: src/nautilus-files-view.c:8170
|
||||
#: src/nautilus-files-view.c:8207
|
||||
msgid "_Lock Drive"
|
||||
msgstr "_Blokeatu unitatea"
|
||||
|
||||
|
@ -3723,7 +3723,7 @@ msgstr "Jaregin duzun fitxategia ez da irudia."
|
|||
|
||||
#. Translators: This is a verb for tagging or untagging a file with a star.
|
||||
#. Unmarks a file as starred (starred)
|
||||
#: src/nautilus-properties-window.c:741 src/nautilus-star-cell.c:73
|
||||
#: src/nautilus-properties-window.c:741 src/nautilus-star-cell.c:66
|
||||
#: src/resources/ui/nautilus-files-view-context-menus.ui:247
|
||||
msgid "Unstar"
|
||||
msgstr "Kendu izarra"
|
||||
|
@ -3960,6 +3960,11 @@ msgstr "_Berregin"
|
|||
msgid "Open %s"
|
||||
msgstr "Ireki %s"
|
||||
|
||||
#: src/nautilus-window.c:2494 src/nautilus-window.c:2499
|
||||
#: src/nautilus-window.c:2504 src/nautilus-window.c:2524
|
||||
msgid "The GNOME Project"
|
||||
msgstr "GNOME proiektua"
|
||||
|
||||
#: src/nautilus-window.c:2511
|
||||
msgid "No plugins currently installed."
|
||||
msgstr "Ez dago pluginik instalatuta."
|
||||
|
@ -3972,10 +3977,6 @@ msgstr "Unean instalatutako pluginak:"
|
|||
msgid "For bug testing only, the following command can be used:"
|
||||
msgstr "Akatsak probatzeko soilik, honako komandoa erabili daiteke:"
|
||||
|
||||
#: src/nautilus-window.c:2524
|
||||
msgid "The GNOME Project"
|
||||
msgstr "GNOME proiektua"
|
||||
|
||||
#. Translators should localize the following string
|
||||
#. * which will be displayed at the bottom of the about
|
||||
#. * box to give credit to the translator(s).
|
||||
|
@ -4072,11 +4073,6 @@ msgstr "Zerbitzariak konexioa ukatu du. Normalean horrek esan nahi du suebakia s
|
|||
msgid "Unhandled error message: %s"
|
||||
msgstr "Kudeatu gabeko errorea: %s"
|
||||
|
||||
#: src/nautilus-window-slot.c:1873
|
||||
#, c-format
|
||||
msgid "Unable to load location"
|
||||
msgstr "Ezin da kokalekua kargatu"
|
||||
|
||||
#: src/nautilus-x-content-bar.c:141
|
||||
msgid "Open with:"
|
||||
msgstr "Ireki honekin:"
|
||||
|
@ -4571,7 +4567,7 @@ msgstr "_Hautatu helburuaren izen berria"
|
|||
msgid "_Reset"
|
||||
msgstr "_Berrezarri"
|
||||
|
||||
#: src/resources/ui/nautilus-file-conflict-dialog.ui:145
|
||||
#: src/resources/ui/nautilus-file-conflict-dialog.ui:142
|
||||
msgid "Apply this action to all files and folders"
|
||||
msgstr "Aplikatu ekintza hau fitxategi eta karpeta guztiei"
|
||||
|
||||
|
@ -4584,7 +4580,7 @@ msgid "C_hange"
|
|||
msgstr "_Aldatu"
|
||||
|
||||
#: src/resources/ui/nautilus-file-properties-change-permissions.ui:147
|
||||
#: src/resources/ui/nautilus-properties-window.ui:877
|
||||
#: src/resources/ui/nautilus-properties-window.ui:876
|
||||
msgid "Others"
|
||||
msgstr "Bestelakoak"
|
||||
|
||||
|
@ -4891,7 +4887,7 @@ msgstr "Gehitu informazioa fitxategien eta karpeten izenen azpian bistaratzeko.
|
|||
|
||||
#: src/resources/ui/nautilus-preferences-window.ui:139
|
||||
msgid "Grid View Captions"
|
||||
msgstr "Sareta-ikuspegiaren epigrafeak"
|
||||
msgstr "Sareta-ikuspegiaren azalpenak"
|
||||
|
||||
#. Translators: This is an ordinal number
|
||||
#: src/resources/ui/nautilus-preferences-window.ui:144
|
||||
|
@ -4933,108 +4929,108 @@ msgstr "Kendu ikono pertsonalizatua"
|
|||
msgid "Unknown Filesystem"
|
||||
msgstr "Fitxategi-sistema ezezaguna"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:257
|
||||
#: src/resources/ui/nautilus-properties-window.ui:256
|
||||
msgid "total"
|
||||
msgstr "guztira"
|
||||
|
||||
#. Refers to the capacity of the filesystem
|
||||
#: src/resources/ui/nautilus-properties-window.ui:286
|
||||
#: src/resources/ui/nautilus-properties-window.ui:285
|
||||
msgid "used"
|
||||
msgstr "erabilita"
|
||||
|
||||
#. Refers to the capacity of the filesystem
|
||||
#: src/resources/ui/nautilus-properties-window.ui:316
|
||||
#: src/resources/ui/nautilus-properties-window.ui:315
|
||||
msgid "free"
|
||||
msgstr "libre"
|
||||
|
||||
#. Disks refers to GNOME Disks.
|
||||
#: src/resources/ui/nautilus-properties-window.ui:345
|
||||
#: src/resources/ui/nautilus-properties-window.ui:344
|
||||
msgid "Open in Disks"
|
||||
msgstr "Ireki Diskoak aplikazioan"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:379
|
||||
#: src/resources/ui/nautilus-properties-window.ui:378
|
||||
msgid "_Link Target"
|
||||
msgstr "Estekaren _helburua"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:403
|
||||
#: src/resources/ui/nautilus-properties-window.ui:402
|
||||
msgid "Open Link Target"
|
||||
msgstr "Ireki estekaren helburua"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:427
|
||||
#: src/resources/ui/nautilus-properties-window.ui:426
|
||||
msgid "Parent _Folder"
|
||||
msgstr "Karpeta _gurasoa"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:451
|
||||
#: src/resources/ui/nautilus-properties-window.ui:450
|
||||
msgid "Open Parent Folder"
|
||||
msgstr "Ireki karpeta gurasoa"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:483
|
||||
#: src/resources/ui/nautilus-properties-window.ui:482
|
||||
msgid "Original Folder"
|
||||
msgstr "Jatorrizko karpeta"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:517
|
||||
#: src/resources/ui/nautilus-properties-window.ui:516
|
||||
msgid "Trashed on"
|
||||
msgstr "Zakarrontzira botata"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:677
|
||||
#: src/resources/ui/nautilus-properties-window.ui:676
|
||||
msgid "_Permissions"
|
||||
msgstr "_Baimenak"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:699
|
||||
#: src/resources/ui/nautilus-properties-window.ui:698
|
||||
msgid "_Executable as Program"
|
||||
msgstr "Programa gisa _exekutagarria"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:729
|
||||
#: src/resources/ui/nautilus-properties-window.ui:728
|
||||
msgid "Set Custom Permissions"
|
||||
msgstr "Ezarri baimen pertsonalizatuak"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:753
|
||||
#: src/resources/ui/nautilus-properties-window.ui:752
|
||||
msgid "Unknown Permissions"
|
||||
msgstr "Baimen ezezagunak"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:754
|
||||
#: src/resources/ui/nautilus-properties-window.ui:753
|
||||
msgid "The permissions of the selected files could not be determined."
|
||||
msgstr "Ezin izan dira hautatutako fitxategien baimenak zehaztu."
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:769
|
||||
#: src/resources/ui/nautilus-properties-window.ui:768
|
||||
msgid "You are not the owner, so you cannot change these permissions."
|
||||
msgstr "Ez zara jabea, beraz ezin dituzu baimen hauek aldatu."
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:785
|
||||
#: src/resources/ui/nautilus-properties-window.ui:784
|
||||
msgid "The permissions of the selected file could not be determined."
|
||||
msgstr "Ezin izan dira hautatutako fitxategiaren baimenak zehaztu."
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:798
|
||||
#: src/resources/ui/nautilus-properties-window.ui:797
|
||||
msgid "_Owner"
|
||||
msgstr "_Jabea"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:809
|
||||
#: src/resources/ui/nautilus-properties-window.ui:849
|
||||
#: src/resources/ui/nautilus-properties-window.ui:884
|
||||
#: src/resources/ui/nautilus-properties-window.ui:808
|
||||
#: src/resources/ui/nautilus-properties-window.ui:848
|
||||
#: src/resources/ui/nautilus-properties-window.ui:883
|
||||
msgid "Access"
|
||||
msgstr "Atzitzea"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:816
|
||||
#: src/resources/ui/nautilus-properties-window.ui:856
|
||||
#: src/resources/ui/nautilus-properties-window.ui:891
|
||||
#: src/resources/ui/nautilus-properties-window.ui:815
|
||||
#: src/resources/ui/nautilus-properties-window.ui:855
|
||||
#: src/resources/ui/nautilus-properties-window.ui:890
|
||||
msgid "Folder Access"
|
||||
msgstr "Karpeta-atzitzea"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:823
|
||||
#: src/resources/ui/nautilus-properties-window.ui:863
|
||||
#: src/resources/ui/nautilus-properties-window.ui:898
|
||||
#: src/resources/ui/nautilus-properties-window.ui:822
|
||||
#: src/resources/ui/nautilus-properties-window.ui:862
|
||||
#: src/resources/ui/nautilus-properties-window.ui:897
|
||||
msgid "File Access"
|
||||
msgstr "Fitxategi-atzitzea"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:838
|
||||
#: src/resources/ui/nautilus-properties-window.ui:837
|
||||
msgid "_Group"
|
||||
msgstr "_Taldea"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:920
|
||||
#: src/resources/ui/nautilus-properties-window.ui:919
|
||||
msgid "Security Context"
|
||||
msgstr "Segurtasun-testuingurua"
|
||||
|
||||
#: src/resources/ui/nautilus-properties-window.ui:953
|
||||
#: src/resources/ui/nautilus-properties-window.ui:952
|
||||
msgid "Change Permissions for _Enclosed Files…"
|
||||
msgstr "Aldatu baimenak fitxategi i_nguratuei…"
|
||||
|
||||
|
@ -5236,7 +5232,7 @@ msgid "No network locations found"
|
|||
msgstr "Ez da sareko kokalekurik aurkitu"
|
||||
|
||||
#. Restore from Cancel to Connect
|
||||
#: src/gtk/nautilusgtkplacesview.c:1233 src/gtk/nautilusgtkplacesview.ui:241
|
||||
#: src/gtk/nautilusgtkplacesview.c:1233 src/gtk/nautilusgtkplacesview.ui:243
|
||||
msgid "Con_nect"
|
||||
msgstr "_Konektatu"
|
||||
|
||||
|
@ -5504,6 +5500,10 @@ msgstr "Alboko barra"
|
|||
msgid "List of common shortcuts, mountpoints, and bookmarks."
|
||||
msgstr "Lasterbide, muntatze-puntu eta laster-marka arrunten zerrenda."
|
||||
|
||||
#, c-format
|
||||
#~ msgid "Unable to load location"
|
||||
#~ msgstr "Ezin da kokalekua kargatu"
|
||||
|
||||
#~ msgid "No matches found in indexed locations"
|
||||
#~ msgstr "Ez da bat etortzerik aurkitu indexatutako kokalekuetan"
|
||||
|
||||
|
|
|
@ -1,646 +0,0 @@
|
|||
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* nautilusgtkbookmarksmanager.c: Utilities to manage and monitor ~/.gtk-bookmarks
|
||||
* Copyright (C) 2003, Red Hat, Inc.
|
||||
* Copyright (C) 2007-2008 Carlos Garnacho
|
||||
* Copyright (C) 2011 Suse
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Federico Mena Quintero <federico@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "nautilus-enum-types.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "nautilusgtkbookmarksmanagerprivate.h"
|
||||
|
||||
static void
|
||||
_gtk_bookmark_free (gpointer data)
|
||||
{
|
||||
GtkBookmark *bookmark = data;
|
||||
|
||||
g_object_unref (bookmark->file);
|
||||
g_free (bookmark->label);
|
||||
g_slice_free (GtkBookmark, bookmark);
|
||||
}
|
||||
|
||||
static void
|
||||
set_error_bookmark_doesnt_exist (GFile *file, GError **error)
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
|
||||
g_set_error (error,
|
||||
GTK_FILE_CHOOSER_ERROR,
|
||||
GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
|
||||
_("%s does not exist in the bookmarks list"),
|
||||
uri);
|
||||
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
static GFile *
|
||||
get_legacy_bookmarks_file (void)
|
||||
{
|
||||
GFile *file;
|
||||
char *filename;
|
||||
|
||||
filename = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL);
|
||||
file = g_file_new_for_path (filename);
|
||||
g_free (filename);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static GFile *
|
||||
get_bookmarks_file (void)
|
||||
{
|
||||
GFile *file;
|
||||
char *filename;
|
||||
|
||||
/* Use gtk-3.0's bookmarks file as the format didn't change.
|
||||
* Add the 3.0 file format to get_legacy_bookmarks_file() when
|
||||
* the format does change.
|
||||
*/
|
||||
filename = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "bookmarks", NULL);
|
||||
file = g_file_new_for_path (filename);
|
||||
g_free (filename);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static GSList *
|
||||
parse_bookmarks (const char *contents)
|
||||
{
|
||||
char **lines, *space;
|
||||
GSList *bookmarks = NULL;
|
||||
int i;
|
||||
|
||||
lines = g_strsplit (contents, "\n", -1);
|
||||
|
||||
for (i = 0; lines[i]; i++)
|
||||
{
|
||||
GtkBookmark *bookmark;
|
||||
|
||||
if (!*lines[i])
|
||||
continue;
|
||||
|
||||
if (!g_utf8_validate (lines[i], -1, NULL))
|
||||
continue;
|
||||
|
||||
bookmark = g_slice_new0 (GtkBookmark);
|
||||
|
||||
if ((space = strchr (lines[i], ' ')) != NULL)
|
||||
{
|
||||
space[0] = '\0';
|
||||
bookmark->label = g_strdup (space + 1);
|
||||
}
|
||||
|
||||
bookmark->file = g_file_new_for_uri (lines[i]);
|
||||
bookmarks = g_slist_prepend (bookmarks, bookmark);
|
||||
}
|
||||
|
||||
bookmarks = g_slist_reverse (bookmarks);
|
||||
g_strfreev (lines);
|
||||
|
||||
return bookmarks;
|
||||
}
|
||||
|
||||
static GSList *
|
||||
read_bookmarks (GFile *file)
|
||||
{
|
||||
char *contents;
|
||||
GSList *bookmarks = NULL;
|
||||
|
||||
if (!g_file_load_contents (file, NULL, &contents,
|
||||
NULL, NULL, NULL))
|
||||
return NULL;
|
||||
|
||||
bookmarks = parse_bookmarks (contents);
|
||||
|
||||
g_free (contents);
|
||||
|
||||
return bookmarks;
|
||||
}
|
||||
|
||||
static void
|
||||
notify_changed (NautilusGtkBookmarksManager *manager)
|
||||
{
|
||||
if (manager->changed_func)
|
||||
manager->changed_func (manager->changed_func_data);
|
||||
}
|
||||
|
||||
static void
|
||||
read_bookmarks_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GFile *file = G_FILE (source);
|
||||
NautilusGtkBookmarksManager *manager = data;
|
||||
char *contents = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_file_load_contents_finish (file, result, &contents, NULL, NULL, &error))
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_warning ("Failed to load '%s': %s", g_file_peek_path (file), error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_slist_free_full (manager->bookmarks, _gtk_bookmark_free);
|
||||
manager->bookmarks = parse_bookmarks (contents);
|
||||
|
||||
g_free (contents);
|
||||
|
||||
notify_changed (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
save_bookmarks (GFile *bookmarks_file,
|
||||
GSList *bookmarks)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GString *contents;
|
||||
GSList *l;
|
||||
GFile *parent = NULL;
|
||||
|
||||
contents = g_string_new ("");
|
||||
|
||||
for (l = bookmarks; l; l = l->next)
|
||||
{
|
||||
GtkBookmark *bookmark = l->data;
|
||||
char *uri;
|
||||
|
||||
uri = g_file_get_uri (bookmark->file);
|
||||
if (!uri)
|
||||
continue;
|
||||
|
||||
g_string_append (contents, uri);
|
||||
|
||||
if (bookmark->label && g_utf8_validate (bookmark->label, -1, NULL))
|
||||
g_string_append_printf (contents, " %s", bookmark->label);
|
||||
|
||||
g_string_append_c (contents, '\n');
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
parent = g_file_get_parent (bookmarks_file);
|
||||
if (!g_file_make_directory_with_parents (parent, NULL, &error))
|
||||
{
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
|
||||
g_clear_error (&error);
|
||||
else
|
||||
goto out;
|
||||
}
|
||||
if (!g_file_replace_contents (bookmarks_file,
|
||||
contents->str,
|
||||
contents->len,
|
||||
NULL, FALSE, 0, NULL,
|
||||
NULL, &error))
|
||||
goto out;
|
||||
|
||||
out:
|
||||
if (error)
|
||||
{
|
||||
g_critical ("%s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_clear_object (&parent);
|
||||
g_string_free (contents, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
bookmarks_file_changed (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
GFile *other_file,
|
||||
GFileMonitorEvent event,
|
||||
gpointer data)
|
||||
{
|
||||
NautilusGtkBookmarksManager *manager = data;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case G_FILE_MONITOR_EVENT_CHANGED:
|
||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
g_file_load_contents_async (file, manager->cancellable, read_bookmarks_finish, manager);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
|
||||
case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
|
||||
case G_FILE_MONITOR_EVENT_UNMOUNTED:
|
||||
case G_FILE_MONITOR_EVENT_MOVED:
|
||||
case G_FILE_MONITOR_EVENT_RENAMED:
|
||||
case G_FILE_MONITOR_EVENT_MOVED_IN:
|
||||
case G_FILE_MONITOR_EVENT_MOVED_OUT:
|
||||
default:
|
||||
/* ignore at the moment */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NautilusGtkBookmarksManager *
|
||||
_nautilus_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func, gpointer changed_func_data)
|
||||
{
|
||||
NautilusGtkBookmarksManager *manager;
|
||||
GFile *bookmarks_file;
|
||||
GError *error;
|
||||
|
||||
manager = g_new0 (NautilusGtkBookmarksManager, 1);
|
||||
|
||||
manager->changed_func = changed_func;
|
||||
manager->changed_func_data = changed_func_data;
|
||||
|
||||
manager->cancellable = g_cancellable_new ();
|
||||
|
||||
bookmarks_file = get_bookmarks_file ();
|
||||
if (!g_file_query_exists (bookmarks_file, NULL))
|
||||
{
|
||||
GFile *legacy_bookmarks_file;
|
||||
|
||||
/* Read the legacy one and write it to the new one */
|
||||
legacy_bookmarks_file = get_legacy_bookmarks_file ();
|
||||
manager->bookmarks = read_bookmarks (legacy_bookmarks_file);
|
||||
if (manager->bookmarks)
|
||||
save_bookmarks (bookmarks_file, manager->bookmarks);
|
||||
|
||||
g_object_unref (legacy_bookmarks_file);
|
||||
}
|
||||
else
|
||||
g_file_load_contents_async (bookmarks_file, manager->cancellable, read_bookmarks_finish, manager);
|
||||
|
||||
error = NULL;
|
||||
manager->bookmarks_monitor = g_file_monitor_file (bookmarks_file,
|
||||
G_FILE_MONITOR_NONE,
|
||||
NULL, &error);
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
manager->bookmarks_monitor_changed_id = g_signal_connect (manager->bookmarks_monitor, "changed",
|
||||
G_CALLBACK (bookmarks_file_changed), manager);
|
||||
|
||||
|
||||
g_object_unref (bookmarks_file);
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
void
|
||||
_nautilus_gtk_bookmarks_manager_free (NautilusGtkBookmarksManager *manager)
|
||||
{
|
||||
g_return_if_fail (manager != NULL);
|
||||
|
||||
g_cancellable_cancel (manager->cancellable);
|
||||
g_object_unref (manager->cancellable);
|
||||
|
||||
if (manager->bookmarks_monitor)
|
||||
{
|
||||
g_file_monitor_cancel (manager->bookmarks_monitor);
|
||||
g_signal_handler_disconnect (manager->bookmarks_monitor, manager->bookmarks_monitor_changed_id);
|
||||
manager->bookmarks_monitor_changed_id = 0;
|
||||
g_object_unref (manager->bookmarks_monitor);
|
||||
}
|
||||
|
||||
g_slist_free_full (manager->bookmarks, _gtk_bookmark_free);
|
||||
|
||||
g_free (manager);
|
||||
}
|
||||
|
||||
GSList *
|
||||
_nautilus_gtk_bookmarks_manager_list_bookmarks (NautilusGtkBookmarksManager *manager)
|
||||
{
|
||||
GSList *bookmarks, *files = NULL;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, NULL);
|
||||
|
||||
bookmarks = manager->bookmarks;
|
||||
|
||||
while (bookmarks)
|
||||
{
|
||||
GtkBookmark *bookmark;
|
||||
|
||||
bookmark = bookmarks->data;
|
||||
bookmarks = bookmarks->next;
|
||||
|
||||
files = g_slist_prepend (files, g_object_ref (bookmark->file));
|
||||
}
|
||||
|
||||
return g_slist_reverse (files);
|
||||
}
|
||||
|
||||
static GSList *
|
||||
find_bookmark_link_for_file (GSList *bookmarks, GFile *file, int *position_ret)
|
||||
{
|
||||
int pos;
|
||||
|
||||
pos = 0;
|
||||
for (; bookmarks; bookmarks = bookmarks->next)
|
||||
{
|
||||
GtkBookmark *bookmark = bookmarks->data;
|
||||
|
||||
if (g_file_equal (file, bookmark->file))
|
||||
{
|
||||
if (position_ret)
|
||||
*position_ret = pos;
|
||||
|
||||
return bookmarks;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (position_ret)
|
||||
*position_ret = -1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nautilus_gtk_bookmarks_manager_has_bookmark (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file)
|
||||
{
|
||||
GSList *link;
|
||||
|
||||
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
|
||||
return (link != NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nautilus_gtk_bookmarks_manager_insert_bookmark (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
int position,
|
||||
GError **error)
|
||||
{
|
||||
GSList *link;
|
||||
GtkBookmark *bookmark;
|
||||
GFile *bookmarks_file;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
|
||||
|
||||
if (link)
|
||||
{
|
||||
char *uri;
|
||||
bookmark = link->data;
|
||||
uri = g_file_get_uri (bookmark->file);
|
||||
|
||||
g_set_error (error,
|
||||
GTK_FILE_CHOOSER_ERROR,
|
||||
GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
|
||||
_("%s already exists in the bookmarks list"),
|
||||
uri);
|
||||
|
||||
g_free (uri);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bookmark = g_slice_new0 (GtkBookmark);
|
||||
bookmark->file = g_object_ref (file);
|
||||
|
||||
manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, position);
|
||||
|
||||
bookmarks_file = get_bookmarks_file ();
|
||||
save_bookmarks (bookmarks_file, manager->bookmarks);
|
||||
g_object_unref (bookmarks_file);
|
||||
|
||||
notify_changed (manager);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nautilus_gtk_bookmarks_manager_remove_bookmark (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
GError **error)
|
||||
{
|
||||
GSList *link;
|
||||
GFile *bookmarks_file;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (!manager->bookmarks)
|
||||
return FALSE;
|
||||
|
||||
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
|
||||
if (link)
|
||||
{
|
||||
GtkBookmark *bookmark = link->data;
|
||||
|
||||
manager->bookmarks = g_slist_remove_link (manager->bookmarks, link);
|
||||
_gtk_bookmark_free (bookmark);
|
||||
g_slist_free_1 (link);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_error_bookmark_doesnt_exist (file, error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bookmarks_file = get_bookmarks_file ();
|
||||
save_bookmarks (bookmarks_file, manager->bookmarks);
|
||||
g_object_unref (bookmarks_file);
|
||||
|
||||
notify_changed (manager);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nautilus_gtk_bookmarks_manager_reorder_bookmark (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
int new_position,
|
||||
GError **error)
|
||||
{
|
||||
GSList *link;
|
||||
GFile *bookmarks_file;
|
||||
int old_position;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
g_return_val_if_fail (new_position >= 0, FALSE);
|
||||
|
||||
if (!manager->bookmarks)
|
||||
return FALSE;
|
||||
|
||||
link = find_bookmark_link_for_file (manager->bookmarks, file, &old_position);
|
||||
if (new_position == old_position)
|
||||
return TRUE;
|
||||
|
||||
if (link)
|
||||
{
|
||||
GtkBookmark *bookmark = link->data;
|
||||
|
||||
manager->bookmarks = g_slist_remove_link (manager->bookmarks, link);
|
||||
g_slist_free_1 (link);
|
||||
|
||||
if (new_position > old_position)
|
||||
new_position--;
|
||||
|
||||
manager->bookmarks = g_slist_insert (manager->bookmarks, bookmark, new_position);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_error_bookmark_doesnt_exist (file, error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bookmarks_file = get_bookmarks_file ();
|
||||
save_bookmarks (bookmarks_file, manager->bookmarks);
|
||||
g_object_unref (bookmarks_file);
|
||||
|
||||
notify_changed (manager);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *
|
||||
_nautilus_gtk_bookmarks_manager_get_bookmark_label (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file)
|
||||
{
|
||||
GSList *bookmarks;
|
||||
char *label = NULL;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, NULL);
|
||||
g_return_val_if_fail (file != NULL, NULL);
|
||||
|
||||
bookmarks = manager->bookmarks;
|
||||
|
||||
while (bookmarks)
|
||||
{
|
||||
GtkBookmark *bookmark;
|
||||
|
||||
bookmark = bookmarks->data;
|
||||
bookmarks = bookmarks->next;
|
||||
|
||||
if (g_file_equal (file, bookmark->file))
|
||||
{
|
||||
label = g_strdup (bookmark->label);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nautilus_gtk_bookmarks_manager_set_bookmark_label (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
const char *label,
|
||||
GError **error)
|
||||
{
|
||||
GFile *bookmarks_file;
|
||||
GSList *link;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, FALSE);
|
||||
g_return_val_if_fail (file != NULL, FALSE);
|
||||
|
||||
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
|
||||
if (link)
|
||||
{
|
||||
GtkBookmark *bookmark = link->data;
|
||||
GString *inlined_label = g_string_new (label);
|
||||
|
||||
g_string_replace (inlined_label, "\n", " ", 0);
|
||||
|
||||
g_free (bookmark->label);
|
||||
bookmark->label = g_string_free_and_steal (inlined_label);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_error_bookmark_doesnt_exist (file, error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bookmarks_file = get_bookmarks_file ();
|
||||
save_bookmarks (bookmarks_file, manager->bookmarks);
|
||||
g_object_unref (bookmarks_file);
|
||||
|
||||
notify_changed (manager);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_nautilus_gtk_bookmarks_manager_get_xdg_type (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
GUserDirectory *directory)
|
||||
{
|
||||
GSList *link;
|
||||
gboolean match;
|
||||
GFile *location;
|
||||
const char *path;
|
||||
GUserDirectory dir;
|
||||
GtkBookmark *bookmark;
|
||||
|
||||
link = find_bookmark_link_for_file (manager->bookmarks, file, NULL);
|
||||
if (!link)
|
||||
return FALSE;
|
||||
|
||||
match = FALSE;
|
||||
bookmark = link->data;
|
||||
|
||||
for (dir = 0; dir < G_USER_N_DIRECTORIES; dir++)
|
||||
{
|
||||
path = g_get_user_special_dir (dir);
|
||||
if (!path)
|
||||
continue;
|
||||
|
||||
location = g_file_new_for_path (path);
|
||||
match = g_file_equal (location, bookmark->file);
|
||||
g_object_unref (location);
|
||||
|
||||
if (match)
|
||||
break;
|
||||
}
|
||||
|
||||
if (match && directory != NULL)
|
||||
*directory = dir;
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nautilus_gtk_bookmarks_manager_get_is_builtin (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file)
|
||||
{
|
||||
GUserDirectory xdg_type;
|
||||
|
||||
/* if this is not an XDG dir, it's never builtin */
|
||||
if (!_nautilus_gtk_bookmarks_manager_get_xdg_type (manager, file, &xdg_type))
|
||||
return FALSE;
|
||||
|
||||
/* exclude XDG locations we don't display by default */
|
||||
return _nautilus_gtk_bookmarks_manager_get_is_xdg_dir_builtin (xdg_type);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nautilus_gtk_bookmarks_manager_get_is_xdg_dir_builtin (GUserDirectory xdg_type)
|
||||
{
|
||||
return (xdg_type != G_USER_DIRECTORY_DESKTOP) &&
|
||||
(xdg_type != G_USER_DIRECTORY_TEMPLATES) &&
|
||||
(xdg_type != G_USER_DIRECTORY_PUBLIC_SHARE);
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* nautilusgtkbookmarksmanager.h: Utilities to manage and monitor ~/.gtk-bookmarks
|
||||
* Copyright (C) 2003, Red Hat, Inc.
|
||||
* Copyright (C) 2007-2008 Carlos Garnacho
|
||||
* Copyright (C) 2011 Suse
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Federico Mena Quintero <federico@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __NAUTILUS_GTK_BOOKMARKS_MANAGER_H__
|
||||
#define __NAUTILUS_GTK_BOOKMARKS_MANAGER_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
typedef void (* GtkBookmarksChangedFunc) (gpointer data);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* This list contains GtkBookmark structs */
|
||||
GSList *bookmarks;
|
||||
|
||||
GFileMonitor *bookmarks_monitor;
|
||||
gulong bookmarks_monitor_changed_id;
|
||||
|
||||
gpointer changed_func_data;
|
||||
GtkBookmarksChangedFunc changed_func;
|
||||
|
||||
GCancellable *cancellable;
|
||||
} NautilusGtkBookmarksManager;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GFile *file;
|
||||
char *label;
|
||||
} GtkBookmark;
|
||||
|
||||
NautilusGtkBookmarksManager *_nautilus_gtk_bookmarks_manager_new (GtkBookmarksChangedFunc changed_func,
|
||||
gpointer changed_func_data);
|
||||
|
||||
|
||||
void _nautilus_gtk_bookmarks_manager_free (NautilusGtkBookmarksManager *manager);
|
||||
|
||||
GSList *_nautilus_gtk_bookmarks_manager_list_bookmarks (NautilusGtkBookmarksManager *manager);
|
||||
|
||||
gboolean _nautilus_gtk_bookmarks_manager_insert_bookmark (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
int position,
|
||||
GError **error);
|
||||
|
||||
gboolean _nautilus_gtk_bookmarks_manager_remove_bookmark (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
|
||||
gboolean _nautilus_gtk_bookmarks_manager_reorder_bookmark (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
int new_position,
|
||||
GError **error);
|
||||
|
||||
gboolean _nautilus_gtk_bookmarks_manager_has_bookmark (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file);
|
||||
|
||||
char * _nautilus_gtk_bookmarks_manager_get_bookmark_label (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file);
|
||||
|
||||
gboolean _nautilus_gtk_bookmarks_manager_set_bookmark_label (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file,
|
||||
const char *label,
|
||||
GError **error);
|
||||
|
||||
gboolean _nautilus_gtk_bookmarks_manager_get_is_builtin (NautilusGtkBookmarksManager *manager,
|
||||
GFile *file);
|
||||
|
||||
gboolean _nautilus_gtk_bookmarks_manager_get_is_xdg_dir_builtin (GUserDirectory xdg_type);
|
||||
|
||||
#endif /* __NAUTILUS_GTK_BOOKMARKS_MANAGER_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -24,6 +24,8 @@
|
|||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "nautilus-enums.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_GTK_PLACES_SIDEBAR (nautilus_gtk_places_sidebar_get_type ())
|
||||
|
@ -36,108 +38,41 @@ G_BEGIN_DECLS
|
|||
typedef struct _NautilusGtkPlacesSidebar NautilusGtkPlacesSidebar;
|
||||
typedef struct _NautilusGtkPlacesSidebarClass NautilusGtkPlacesSidebarClass;
|
||||
|
||||
/*
|
||||
* NautilusGtkPlacesOpenFlags:
|
||||
* @NAUTILUS_GTK_PLACES_OPEN_NORMAL: This is the default mode that NautilusGtkPlacesSidebar uses if no other flags
|
||||
* are specified. It indicates that the calling application should open the selected location
|
||||
* in the normal way, for example, in the folder view beside the sidebar.
|
||||
* @NAUTILUS_GTK_PLACES_OPEN_NEW_TAB: When passed to nautilus_gtk_places_sidebar_set_open_flags(), this indicates
|
||||
* that the application can open folders selected from the sidebar in new tabs. This value
|
||||
* will be passed to the NautilusGtkPlacesSidebar::open-location signal when the user selects
|
||||
* that a location be opened in a new tab instead of in the standard fashion.
|
||||
* @NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW: Similar to @NAUTILUS_GTK_PLACES_OPEN_NEW_TAB, but indicates that the application
|
||||
* can open folders in new windows.
|
||||
*
|
||||
* These flags serve two purposes. First, the application can call nautilus_gtk_places_sidebar_set_open_flags()
|
||||
* using these flags as a bitmask. This tells the sidebar that the application is able to open
|
||||
* folders selected from the sidebar in various ways, for example, in new tabs or in new windows in
|
||||
* addition to the normal mode.
|
||||
*
|
||||
* Second, when one of these values gets passed back to the application in the
|
||||
* NautilusGtkPlacesSidebar::open-location signal, it means that the application should
|
||||
* open the selected location in the normal way, in a new tab, or in a new
|
||||
* window. The sidebar takes care of determining the desired way to open the location,
|
||||
* based on the modifier keys that the user is pressing at the time the selection is made.
|
||||
*
|
||||
* If the application never calls nautilus_gtk_places_sidebar_set_open_flags(), then the sidebar will only
|
||||
* use NAUTILUS_GTK_PLACES_OPEN_NORMAL in the NautilusGtkPlacesSidebar::open-location signal. This is the
|
||||
* default mode of operation.
|
||||
*/
|
||||
typedef enum {
|
||||
NAUTILUS_GTK_PLACES_OPEN_NORMAL = 1 << 0,
|
||||
NAUTILUS_GTK_PLACES_OPEN_NEW_TAB = 1 << 1,
|
||||
NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW = 1 << 2
|
||||
} NautilusGtkPlacesOpenFlags;
|
||||
|
||||
GType nautilus_gtk_places_sidebar_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget * nautilus_gtk_places_sidebar_new (void);
|
||||
|
||||
NautilusGtkPlacesOpenFlags nautilus_gtk_places_sidebar_get_open_flags (NautilusGtkPlacesSidebar *sidebar);
|
||||
NautilusOpenFlags nautilus_gtk_places_sidebar_get_open_flags (NautilusGtkPlacesSidebar *sidebar);
|
||||
void nautilus_gtk_places_sidebar_set_open_flags (NautilusGtkPlacesSidebar *sidebar,
|
||||
NautilusGtkPlacesOpenFlags flags);
|
||||
NautilusOpenFlags flags);
|
||||
|
||||
GFile * nautilus_gtk_places_sidebar_get_location (NautilusGtkPlacesSidebar *sidebar);
|
||||
void nautilus_gtk_places_sidebar_set_location (NautilusGtkPlacesSidebar *sidebar,
|
||||
GFile *location);
|
||||
|
||||
gboolean nautilus_gtk_places_sidebar_get_show_recent (NautilusGtkPlacesSidebar *sidebar);
|
||||
void nautilus_gtk_places_sidebar_set_show_recent (NautilusGtkPlacesSidebar *sidebar,
|
||||
gboolean show_recent);
|
||||
|
||||
gboolean nautilus_gtk_places_sidebar_get_show_desktop (NautilusGtkPlacesSidebar *sidebar);
|
||||
void nautilus_gtk_places_sidebar_set_show_desktop (NautilusGtkPlacesSidebar *sidebar,
|
||||
gboolean show_desktop);
|
||||
|
||||
gboolean nautilus_gtk_places_sidebar_get_show_enter_location (NautilusGtkPlacesSidebar *sidebar);
|
||||
void nautilus_gtk_places_sidebar_set_show_enter_location (NautilusGtkPlacesSidebar *sidebar,
|
||||
gboolean show_enter_location);
|
||||
|
||||
void nautilus_gtk_places_sidebar_add_shortcut (NautilusGtkPlacesSidebar *sidebar,
|
||||
GFile *location);
|
||||
void nautilus_gtk_places_sidebar_remove_shortcut (NautilusGtkPlacesSidebar *sidebar,
|
||||
GFile *location);
|
||||
GListModel * nautilus_gtk_places_sidebar_get_shortcuts (NautilusGtkPlacesSidebar *sidebar);
|
||||
|
||||
GFile * nautilus_gtk_places_sidebar_get_nth_bookmark (NautilusGtkPlacesSidebar *sidebar,
|
||||
int n);
|
||||
void nautilus_gtk_places_sidebar_set_drop_targets_visible (NautilusGtkPlacesSidebar *sidebar,
|
||||
gboolean visible);
|
||||
gboolean nautilus_gtk_places_sidebar_get_show_trash (NautilusGtkPlacesSidebar *sidebar);
|
||||
void nautilus_gtk_places_sidebar_set_show_trash (NautilusGtkPlacesSidebar *sidebar,
|
||||
gboolean show_trash);
|
||||
|
||||
void nautilus_gtk_places_sidebar_set_show_other_locations (NautilusGtkPlacesSidebar *sidebar,
|
||||
gboolean show_other_locations);
|
||||
gboolean nautilus_gtk_places_sidebar_get_show_other_locations (NautilusGtkPlacesSidebar *sidebar);
|
||||
|
||||
void nautilus_gtk_places_sidebar_set_show_starred_location (NautilusGtkPlacesSidebar *sidebar,
|
||||
gboolean show_starred_location);
|
||||
gboolean nautilus_gtk_places_sidebar_get_show_starred_location (NautilusGtkPlacesSidebar *sidebar);
|
||||
|
||||
/* Keep order, since it's used for the sort functions */
|
||||
typedef enum {
|
||||
NAUTILUS_GTK_PLACES_SECTION_INVALID,
|
||||
NAUTILUS_GTK_PLACES_SECTION_COMPUTER,
|
||||
NAUTILUS_GTK_PLACES_SECTION_MOUNTS,
|
||||
NAUTILUS_GTK_PLACES_SECTION_CLOUD,
|
||||
NAUTILUS_GTK_PLACES_SECTION_DEFAULT_LOCATIONS,
|
||||
NAUTILUS_GTK_PLACES_SECTION_BOOKMARKS,
|
||||
NAUTILUS_GTK_PLACES_SECTION_OTHER_LOCATIONS,
|
||||
NAUTILUS_GTK_PLACES_SECTION_CLOUD,
|
||||
NAUTILUS_GTK_PLACES_SECTION_MOUNTS,
|
||||
NAUTILUS_GTK_PLACES_N_SECTIONS
|
||||
} NautilusGtkPlacesSectionType;
|
||||
|
||||
typedef enum {
|
||||
NAUTILUS_GTK_PLACES_INVALID,
|
||||
NAUTILUS_GTK_PLACES_BUILT_IN,
|
||||
NAUTILUS_GTK_PLACES_XDG_DIR,
|
||||
NAUTILUS_GTK_PLACES_MOUNTED_VOLUME,
|
||||
NAUTILUS_GTK_PLACES_EXTERNAL_MOUNT,
|
||||
NAUTILUS_GTK_PLACES_INTERNAL_MOUNT,
|
||||
NAUTILUS_GTK_PLACES_BOOKMARK,
|
||||
NAUTILUS_GTK_PLACES_HEADING,
|
||||
NAUTILUS_GTK_PLACES_CONNECT_TO_SERVER,
|
||||
NAUTILUS_GTK_PLACES_ENTER_LOCATION,
|
||||
NAUTILUS_GTK_PLACES_DROP_FEEDBACK,
|
||||
NAUTILUS_GTK_PLACES_BOOKMARK_PLACEHOLDER,
|
||||
NAUTILUS_GTK_PLACES_OTHER_LOCATIONS,
|
||||
NAUTILUS_GTK_PLACES_STARRED_LOCATION,
|
||||
NAUTILUS_GTK_PLACES_N_PLACES
|
||||
} NautilusGtkPlacesPlaceType;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,254 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkListStore" id="completion_store">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkEntryCompletion" id="address_entry_completion">
|
||||
<property name="model">completion_store</property>
|
||||
<property name="text-column">1</property>
|
||||
<property name="inline-completion">1</property>
|
||||
<property name="popup-completion">0</property>
|
||||
</object>
|
||||
<object class="GtkPopover" id="server_adresses_popover">
|
||||
<property name="position">2</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">1</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="label" translatable="yes">Server Addresses</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="label" translatable="yes">Server addresses are made up of a protocol prefix and an address. Examples:</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="width-chars">40</property>
|
||||
<property name="max-width-chars">40</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="label">smb://gnome.org, ssh://192.168.0.1, ftp://[2001:db8::1]</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="width-chars">40</property>
|
||||
<property name="max-width-chars">40</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="available_protocols_grid">
|
||||
<property name="margin-top">12</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="label" translatable="yes">Available Protocols</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Prefix</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="recent_servers_popover">
|
||||
<child>
|
||||
<object class="GtkStack" id="recent_servers_stack">
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">empty</property>
|
||||
<property name="child">
|
||||
<object class="AdwStatusPage">
|
||||
<property name="icon-name">network-server-symbolic</property>
|
||||
<property name="title" translatable="yes" comments="Translators: Server as any successfully connected network address">No Recent Servers</property>
|
||||
<style>
|
||||
<class name="compact"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">list</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">1</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Recent Servers</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="vexpand">1</property>
|
||||
<property name="has-frame">1</property>
|
||||
<property name="min-content-width">250</property>
|
||||
<property name="min-content-height">200</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkListBox" id="recent_servers_listbox">
|
||||
<property name="selection-mode">0</property>
|
||||
<signal name="row-activated" handler="on_recent_servers_listbox_row_activated" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<template class="NautilusGtkPlacesView" parent="GtkBox">
|
||||
<accessibility>
|
||||
<property name="label" translatable="yes">Other Locations</property>
|
||||
<property name="description" translatable="yes">List of common local and remote mountpoints.</property>
|
||||
</accessibility>
|
||||
<property name="orientation">1</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="vhomogeneous">0</property>
|
||||
<property name="transition-type">1</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">browse</property>
|
||||
<property name="child">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<child>
|
||||
<object class="GtkListBox" id="listbox">
|
||||
<property name="selection-mode">0</property>
|
||||
<signal name="row-activated" handler="on_listbox_row_activated" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">empty-search</property>
|
||||
<property name="child">
|
||||
<object class="AdwStatusPage">
|
||||
<property name="icon-name">edit-find-symbolic</property>
|
||||
<property name="title" translatable="yes">No Results Found</property>
|
||||
<property name="description" translatable="yes">Try a different search.</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="actionbar">
|
||||
<property name="hexpand">1</property>
|
||||
<style>
|
||||
<class name="toolbar"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkEntry" id="address_entry">
|
||||
<property name="width-chars">10</property>
|
||||
<property name="max-width-chars">34</property>
|
||||
<property name="placeholder-text" translatable="yes">Enter server address…</property>
|
||||
<property name="secondary-icon-name">dialog-question-symbolic</property>
|
||||
<property name="completion">address_entry_completion</property>
|
||||
<property name="input-purpose">url</property>
|
||||
<property name="input-hints">no-spellcheck | no-emoji</property>
|
||||
<signal name="notify::text" handler="on_address_entry_text_changed" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
<signal name="activate" handler="on_connect_button_clicked" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
<signal name="icon-press" handler="on_address_entry_show_help_pressed" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="server_list_button">
|
||||
<property name="direction">0</property>
|
||||
<property name="popover">recent_servers_popover</property>
|
||||
<property name="icon-name">pan-down-symbolic</property>
|
||||
<style>
|
||||
<class name="server-list-button"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="connect_button">
|
||||
<property name="label" translatable="yes">Con_nect</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="can-shrink">true</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="valign">3</property>
|
||||
<signal name="clicked" handler="on_connect_button_clicked" object="NautilusGtkPlacesView" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
|
@ -1,55 +0,0 @@
|
|||
/* nautilusgtkplacesview.h
|
||||
*
|
||||
* Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NAUTILUS_GTK_PLACES_VIEW_H
|
||||
#define NAUTILUS_GTK_PLACES_VIEW_H
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#endif
|
||||
|
||||
#include "nautilusgtkplacessidebarprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_GTK_PLACES_VIEW (nautilus_gtk_places_view_get_type ())
|
||||
#define NAUTILUS_GTK_PLACES_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_GTK_PLACES_VIEW, NautilusGtkPlacesView))
|
||||
#define NAUTILUS_GTK_PLACES_VIEW_CLASS(klass)(G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_GTK_PLACES_VIEW, NautilusGtkPlacesViewClass))
|
||||
#define NAUTILUS_IS_GTK_PLACES_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_GTK_PLACES_VIEW))
|
||||
#define NAUTILUS_IS_GTK_PLACES_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_GTK_PLACES_VIEW))
|
||||
#define NAUTILUS_GTK_PLACES_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_GTK_PLACES_VIEW, NautilusGtkPlacesViewClass))
|
||||
|
||||
typedef struct _NautilusGtkPlacesView NautilusGtkPlacesView;
|
||||
typedef struct _NautilusGtkPlacesViewClass NautilusGtkPlacesViewClass;
|
||||
|
||||
GType nautilus_gtk_places_view_get_type (void) G_GNUC_CONST;
|
||||
|
||||
NautilusGtkPlacesOpenFlags nautilus_gtk_places_view_get_open_flags (NautilusGtkPlacesView *view);
|
||||
void nautilus_gtk_places_view_set_open_flags (NautilusGtkPlacesView *view,
|
||||
NautilusGtkPlacesOpenFlags flags);
|
||||
|
||||
const char * nautilus_gtk_places_view_get_search_query (NautilusGtkPlacesView *view);
|
||||
void nautilus_gtk_places_view_set_search_query (NautilusGtkPlacesView *view,
|
||||
const char *query_text);
|
||||
|
||||
gboolean nautilus_gtk_places_view_get_loading (NautilusGtkPlacesView *view);
|
||||
|
||||
GtkWidget * nautilus_gtk_places_view_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NAUTILUS_GTK_PLACES_VIEW_H */
|
|
@ -1,520 +0,0 @@
|
|||
/* nautilusgtkplacesviewrow.c
|
||||
*
|
||||
* Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "nautilus-application.h"
|
||||
#include "nautilus-enum-types.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "nautilusgtkplacesviewrowprivate.h"
|
||||
|
||||
/* As this widget is shared with Nautilus, we use this guard to
|
||||
* ensure that internally we only include the files that we need
|
||||
* instead of including gtk.h
|
||||
*/
|
||||
#ifdef GTK_COMPILATION
|
||||
#else
|
||||
#include <gtk/gtk.h>
|
||||
#endif
|
||||
|
||||
struct _NautilusGtkPlacesViewRow
|
||||
{
|
||||
GtkListBoxRow parent_instance;
|
||||
|
||||
GtkLabel *available_space_label;
|
||||
GtkStack *mount_stack;
|
||||
GtkSpinner *busy_spinner;
|
||||
GtkButton *eject_button;
|
||||
GtkImage *eject_icon;
|
||||
GtkImage *icon_image;
|
||||
GtkLabel *name_label;
|
||||
GtkLabel *path_label;
|
||||
|
||||
GVolume *volume;
|
||||
GMount *mount;
|
||||
GFile *file;
|
||||
|
||||
GCancellable *cancellable;
|
||||
|
||||
int is_network : 1;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NautilusGtkPlacesViewRow, nautilus_gtk_places_view_row, GTK_TYPE_LIST_BOX_ROW)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ICON,
|
||||
PROP_NAME,
|
||||
PROP_PATH,
|
||||
PROP_VOLUME,
|
||||
PROP_MOUNT,
|
||||
PROP_FILE,
|
||||
PROP_IS_NETWORK,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *properties [LAST_PROP];
|
||||
|
||||
static void
|
||||
measure_available_space_finished (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusGtkPlacesViewRow *row = user_data;
|
||||
GFileInfo *info;
|
||||
GError *error;
|
||||
guint64 free_space;
|
||||
guint64 total_space;
|
||||
char *formatted_free_size;
|
||||
char *formatted_total_size;
|
||||
char *label;
|
||||
guint plural_form;
|
||||
|
||||
error = NULL;
|
||||
|
||||
info = g_file_query_filesystem_info_finish (G_FILE (object),
|
||||
res,
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
|
||||
!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED))
|
||||
{
|
||||
g_warning ("Failed to measure available space: %s", error->message);
|
||||
}
|
||||
|
||||
g_clear_error (&error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE) ||
|
||||
!g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE))
|
||||
{
|
||||
g_object_unref (info);
|
||||
goto out;
|
||||
}
|
||||
|
||||
free_space = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
|
||||
total_space = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE);
|
||||
|
||||
formatted_free_size = g_format_size (free_space);
|
||||
formatted_total_size = g_format_size (total_space);
|
||||
|
||||
/* read g_format_size code in glib for further understanding */
|
||||
plural_form = free_space < 1000 ? free_space : free_space % 1000 + 1000;
|
||||
|
||||
/* Translators: respectively, free and total space of the drive. The plural form
|
||||
* should be based on the free space available.
|
||||
* i.e. 1 GB / 24 GB available.
|
||||
*/
|
||||
label = g_strdup_printf (dngettext (GETTEXT_PACKAGE, "%s / %s available", "%s / %s available", plural_form),
|
||||
formatted_free_size, formatted_total_size);
|
||||
|
||||
gtk_label_set_label (row->available_space_label, label);
|
||||
|
||||
g_object_unref (info);
|
||||
g_free (formatted_total_size);
|
||||
g_free (formatted_free_size);
|
||||
g_free (label);
|
||||
out:
|
||||
g_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
measure_available_space (NautilusGtkPlacesViewRow *row)
|
||||
{
|
||||
gboolean skip_measure;
|
||||
gboolean should_measure;
|
||||
g_autoptr (GFile) root = NULL;
|
||||
|
||||
skip_measure = FALSE;
|
||||
if (nautilus_application_is_sandboxed ())
|
||||
{
|
||||
root = g_file_new_for_uri ("file:///");
|
||||
if (row->file != NULL)
|
||||
skip_measure = g_file_equal (root, row->file);
|
||||
}
|
||||
|
||||
should_measure = ((row->volume || row->mount || row->file) &&
|
||||
!row->is_network && !skip_measure);
|
||||
|
||||
gtk_label_set_label (row->available_space_label, "");
|
||||
gtk_widget_set_visible (GTK_WIDGET (row->available_space_label), should_measure);
|
||||
|
||||
if (should_measure)
|
||||
{
|
||||
GFile *file = NULL;
|
||||
|
||||
if (row->file)
|
||||
{
|
||||
file = g_object_ref (row->file);
|
||||
}
|
||||
else if (row->mount)
|
||||
{
|
||||
file = g_mount_get_root (row->mount);
|
||||
}
|
||||
else if (row->volume)
|
||||
{
|
||||
GMount *mount;
|
||||
|
||||
mount = g_volume_get_mount (row->volume);
|
||||
|
||||
if (mount)
|
||||
file = g_mount_get_root (row->mount);
|
||||
|
||||
g_clear_object (&mount);
|
||||
}
|
||||
|
||||
if (file)
|
||||
{
|
||||
g_cancellable_cancel (row->cancellable);
|
||||
g_clear_object (&row->cancellable);
|
||||
row->cancellable = g_cancellable_new ();
|
||||
|
||||
g_file_query_filesystem_info_async (file,
|
||||
G_FILE_ATTRIBUTE_FILESYSTEM_FREE "," G_FILE_ATTRIBUTE_FILESYSTEM_SIZE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
row->cancellable,
|
||||
measure_available_space_finished,
|
||||
row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_row_dispose (GObject *object)
|
||||
{
|
||||
NautilusGtkPlacesViewRow *self = NAUTILUS_GTK_PLACES_VIEW_ROW (object);
|
||||
|
||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (self), NULL);
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), NAUTILUS_TYPE_GTK_PLACES_VIEW_ROW);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_gtk_places_view_row_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_row_finalize (GObject *object)
|
||||
{
|
||||
NautilusGtkPlacesViewRow *self = NAUTILUS_GTK_PLACES_VIEW_ROW (object);
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
|
||||
g_clear_object (&self->volume);
|
||||
g_clear_object (&self->mount);
|
||||
g_clear_object (&self->file);
|
||||
g_clear_object (&self->cancellable);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_gtk_places_view_row_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_row_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NautilusGtkPlacesViewRow *self;
|
||||
|
||||
self = NAUTILUS_GTK_PLACES_VIEW_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON:
|
||||
g_value_set_object (value, gtk_image_get_gicon (self->icon_image));
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, gtk_label_get_label (self->name_label));
|
||||
break;
|
||||
|
||||
case PROP_PATH:
|
||||
g_value_set_string (value, gtk_label_get_label (self->path_label));
|
||||
break;
|
||||
|
||||
case PROP_VOLUME:
|
||||
g_value_set_object (value, self->volume);
|
||||
break;
|
||||
|
||||
case PROP_MOUNT:
|
||||
g_value_set_object (value, self->mount);
|
||||
break;
|
||||
|
||||
case PROP_FILE:
|
||||
g_value_set_object (value, self->file);
|
||||
break;
|
||||
|
||||
case PROP_IS_NETWORK:
|
||||
g_value_set_boolean (value, self->is_network);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_row_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NautilusGtkPlacesViewRow *self = NAUTILUS_GTK_PLACES_VIEW_ROW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON:
|
||||
gtk_image_set_from_gicon (self->icon_image, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
gtk_label_set_label (self->name_label, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_PATH:
|
||||
gtk_label_set_label (self->path_label, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_VOLUME:
|
||||
g_set_object (&self->volume, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_MOUNT:
|
||||
g_set_object (&self->mount, g_value_get_object (value));
|
||||
if (self->mount != NULL)
|
||||
{
|
||||
gtk_stack_set_visible_child (self->mount_stack, GTK_WIDGET (self->eject_button));
|
||||
gtk_widget_set_child_visible (GTK_WIDGET (self->mount_stack), TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_child_visible (GTK_WIDGET (self->mount_stack), FALSE);
|
||||
}
|
||||
measure_available_space (self);
|
||||
break;
|
||||
|
||||
case PROP_FILE:
|
||||
g_set_object (&self->file, g_value_get_object (value));
|
||||
measure_available_space (self);
|
||||
break;
|
||||
|
||||
case PROP_IS_NETWORK:
|
||||
nautilus_gtk_places_view_row_set_is_network (self, g_value_get_boolean (value));
|
||||
measure_available_space (self);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_row_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkWidget *menu = GTK_WIDGET (g_object_get_data (G_OBJECT (widget), "menu"));
|
||||
|
||||
GTK_WIDGET_CLASS (nautilus_gtk_places_view_row_parent_class)->size_allocate (widget, width, height, baseline);
|
||||
if (menu)
|
||||
gtk_popover_present (GTK_POPOVER (menu));
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_row_class_init (NautilusGtkPlacesViewRowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = nautilus_gtk_places_view_row_dispose;
|
||||
object_class->finalize = nautilus_gtk_places_view_row_finalize;
|
||||
object_class->get_property = nautilus_gtk_places_view_row_get_property;
|
||||
object_class->set_property = nautilus_gtk_places_view_row_set_property;
|
||||
|
||||
widget_class->size_allocate = nautilus_gtk_places_view_row_size_allocate;
|
||||
|
||||
properties[PROP_ICON] =
|
||||
g_param_spec_object ("icon",
|
||||
"Icon of the row",
|
||||
"The icon representing the volume",
|
||||
G_TYPE_ICON,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_NAME] =
|
||||
g_param_spec_string ("name",
|
||||
"Name of the volume",
|
||||
"The name of the volume",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_PATH] =
|
||||
g_param_spec_string ("path",
|
||||
"Path of the volume",
|
||||
"The path of the volume",
|
||||
"",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_VOLUME] =
|
||||
g_param_spec_object ("volume",
|
||||
"Volume represented by the row",
|
||||
"The volume represented by the row",
|
||||
G_TYPE_VOLUME,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_MOUNT] =
|
||||
g_param_spec_object ("mount",
|
||||
"Mount represented by the row",
|
||||
"The mount point represented by the row, if any",
|
||||
G_TYPE_MOUNT,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_FILE] =
|
||||
g_param_spec_object ("file",
|
||||
"File represented by the row",
|
||||
"The file represented by the row, if any",
|
||||
G_TYPE_FILE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
properties[PROP_IS_NETWORK] =
|
||||
g_param_spec_boolean ("is-network",
|
||||
"Whether the row represents a network location",
|
||||
"Whether the row represents a network location",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/nautilus/gtk/ui/nautilusgtkplacesviewrow.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesViewRow, available_space_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesViewRow, mount_stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesViewRow, busy_spinner);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesViewRow, eject_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesViewRow, eject_icon);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesViewRow, icon_image);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesViewRow, name_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusGtkPlacesViewRow, path_label);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_gtk_places_view_row_init (NautilusGtkPlacesViewRow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
nautilus_gtk_places_view_row_new (GVolume *volume,
|
||||
GMount *mount)
|
||||
{
|
||||
return g_object_new (NAUTILUS_TYPE_GTK_PLACES_VIEW_ROW,
|
||||
"volume", volume,
|
||||
"mount", mount,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GMount*
|
||||
nautilus_gtk_places_view_row_get_mount (NautilusGtkPlacesViewRow *row)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_VIEW_ROW (row), NULL);
|
||||
|
||||
return row->mount;
|
||||
}
|
||||
|
||||
GVolume*
|
||||
nautilus_gtk_places_view_row_get_volume (NautilusGtkPlacesViewRow *row)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_VIEW_ROW (row), NULL);
|
||||
|
||||
return row->volume;
|
||||
}
|
||||
|
||||
GFile*
|
||||
nautilus_gtk_places_view_row_get_file (NautilusGtkPlacesViewRow *row)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_VIEW_ROW (row), NULL);
|
||||
|
||||
return row->file;
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
nautilus_gtk_places_view_row_get_eject_button (NautilusGtkPlacesViewRow *row)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_VIEW_ROW (row), NULL);
|
||||
|
||||
return GTK_WIDGET (row->eject_button);
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_gtk_places_view_row_set_busy (NautilusGtkPlacesViewRow *row,
|
||||
gboolean is_busy)
|
||||
{
|
||||
g_return_if_fail (NAUTILUS_IS_GTK_PLACES_VIEW_ROW (row));
|
||||
|
||||
if (is_busy)
|
||||
{
|
||||
gtk_stack_set_visible_child (row->mount_stack, GTK_WIDGET (row->busy_spinner));
|
||||
gtk_widget_set_child_visible (GTK_WIDGET (row->mount_stack), TRUE);
|
||||
gtk_spinner_start (row->busy_spinner);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_child_visible (GTK_WIDGET (row->mount_stack), FALSE);
|
||||
gtk_spinner_stop (row->busy_spinner);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nautilus_gtk_places_view_row_get_is_network (NautilusGtkPlacesViewRow *row)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_GTK_PLACES_VIEW_ROW (row), FALSE);
|
||||
|
||||
return row->is_network;
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_gtk_places_view_row_set_is_network (NautilusGtkPlacesViewRow *row,
|
||||
gboolean is_network)
|
||||
{
|
||||
if (row->is_network != is_network)
|
||||
{
|
||||
row->is_network = is_network;
|
||||
|
||||
gtk_image_set_from_icon_name (row->eject_icon, "media-eject-symbolic");
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (row->eject_button), is_network ? _("Disconnect") : _("Unmount"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_gtk_places_view_row_set_path_size_group (NautilusGtkPlacesViewRow *row,
|
||||
GtkSizeGroup *group)
|
||||
{
|
||||
if (group)
|
||||
gtk_size_group_add_widget (group, GTK_WIDGET (row->path_label));
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_gtk_places_view_row_set_space_size_group (NautilusGtkPlacesViewRow *row,
|
||||
GtkSizeGroup *group)
|
||||
{
|
||||
if (group)
|
||||
gtk_size_group_add_widget (group, GTK_WIDGET (row->available_space_label));
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="NautilusGtkPlacesViewRow" parent="GtkListBoxRow">
|
||||
<property name="width-request">100</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox" id="box">
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="icon_image">
|
||||
<property name="pixel-size">32</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="name_label">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="ellipsize">3</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="available_space_label">
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="path_label">
|
||||
<property name="justify">1</property>
|
||||
<property name="ellipsize">2</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="max-width-chars">15</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="mount_stack">
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">button</property>
|
||||
<property name="child">
|
||||
<object class="GtkButton" id="eject_button">
|
||||
<property name="visible">0</property>
|
||||
<property name="halign">3</property>
|
||||
<property name="valign">3</property>
|
||||
<property name="tooltip-text" translatable="yes">Unmount</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="eject_icon">
|
||||
<property name="icon-name">media-eject-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
<class name="sidebar-button"/>
|
||||
</style>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">spinner</property>
|
||||
<property name="child">
|
||||
<object class="GtkSpinner" id="busy_spinner">
|
||||
<property name="halign">3</property>
|
||||
<property name="valign">3</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
|
@ -1,59 +0,0 @@
|
|||
/* nautilusgtkplacesviewrow.h
|
||||
*
|
||||
* Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NAUTILUS_GTK_PLACES_VIEW_ROW_H
|
||||
#define NAUTILUS_GTK_PLACES_VIEW_ROW_H
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#endif
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_GTK_PLACES_VIEW_ROW (nautilus_gtk_places_view_row_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusGtkPlacesViewRow, nautilus_gtk_places_view_row, NAUTILUS, GTK_PLACES_VIEW_ROW, GtkListBoxRow)
|
||||
|
||||
GtkWidget* nautilus_gtk_places_view_row_new (GVolume *volume,
|
||||
GMount *mount);
|
||||
|
||||
GtkWidget* nautilus_gtk_places_view_row_get_eject_button (NautilusGtkPlacesViewRow *row);
|
||||
|
||||
GMount* nautilus_gtk_places_view_row_get_mount (NautilusGtkPlacesViewRow *row);
|
||||
|
||||
GVolume* nautilus_gtk_places_view_row_get_volume (NautilusGtkPlacesViewRow *row);
|
||||
|
||||
GFile* nautilus_gtk_places_view_row_get_file (NautilusGtkPlacesViewRow *row);
|
||||
|
||||
void nautilus_gtk_places_view_row_set_busy (NautilusGtkPlacesViewRow *row,
|
||||
gboolean is_busy);
|
||||
|
||||
gboolean nautilus_gtk_places_view_row_get_is_network (NautilusGtkPlacesViewRow *row);
|
||||
|
||||
void nautilus_gtk_places_view_row_set_is_network (NautilusGtkPlacesViewRow *row,
|
||||
gboolean is_network);
|
||||
|
||||
void nautilus_gtk_places_view_row_set_path_size_group (NautilusGtkPlacesViewRow *row,
|
||||
GtkSizeGroup *group);
|
||||
|
||||
void nautilus_gtk_places_view_row_set_space_size_group (NautilusGtkPlacesViewRow *row,
|
||||
GtkSizeGroup *group);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NAUTILUS_GTK_PLACES_VIEW_ROW_H */
|
|
@ -336,8 +336,7 @@ nautilus_gtk_sidebar_row_set_property (GObject *object,
|
|||
|
||||
case PROP_SECTION_TYPE:
|
||||
self->section_type = g_value_get_enum (value);
|
||||
if (self->section_type == NAUTILUS_GTK_PLACES_SECTION_COMPUTER ||
|
||||
self->section_type == NAUTILUS_GTK_PLACES_SECTION_OTHER_LOCATIONS)
|
||||
if (self->section_type == NAUTILUS_GTK_PLACES_SECTION_DEFAULT_LOCATIONS)
|
||||
gtk_label_set_ellipsize (GTK_LABEL (self->label_widget), PANGO_ELLIPSIZE_NONE);
|
||||
else
|
||||
gtk_label_set_ellipsize (GTK_LABEL (self->label_widget), PANGO_ELLIPSIZE_END);
|
||||
|
|
|
@ -55,16 +55,10 @@ libnautilus_sources = [
|
|||
interface_prefix: 'org.gnome',
|
||||
namespace: 'Nautilus'
|
||||
),
|
||||
'gtk/nautilusgtkbookmarksmanager.c',
|
||||
'gtk/nautilusgtkbookmarksmanagerprivate.h',
|
||||
'gtk/nautilusgtkplacessidebar.c',
|
||||
'gtk/nautilusgtkplacessidebarprivate.h',
|
||||
'gtk/nautilusgtksidebarrow.c',
|
||||
'gtk/nautilusgtksidebarrowprivate.h',
|
||||
'gtk/nautilusgtkplacesview.c',
|
||||
'gtk/nautilusgtkplacesviewprivate.h',
|
||||
'gtk/nautilusgtkplacesviewrow.c',
|
||||
'gtk/nautilusgtkplacesviewrowprivate.h',
|
||||
'nautilus-application.c',
|
||||
'nautilus-application.h',
|
||||
'nautilus-app-chooser.c',
|
||||
|
@ -108,8 +102,6 @@ libnautilus_sources = [
|
|||
'nautilus-name-cell.h',
|
||||
'nautilus-pathbar.c',
|
||||
'nautilus-pathbar.h',
|
||||
'nautilus-places-view.c',
|
||||
'nautilus-places-view.h',
|
||||
'nautilus-previewer.c',
|
||||
'nautilus-previewer.h',
|
||||
'nautilus-progress-indicator.c',
|
||||
|
@ -173,6 +165,14 @@ libnautilus_sources = [
|
|||
'nautilus-filename-validator.h',
|
||||
'nautilus-rename-file-popover.c',
|
||||
'nautilus-rename-file-popover.h',
|
||||
'nautilus-network-address-bar.c',
|
||||
'nautilus-network-address-bar.h',
|
||||
'nautilus-network-cell.c',
|
||||
'nautilus-network-cell.h',
|
||||
'nautilus-network-directory.c',
|
||||
'nautilus-network-directory.h',
|
||||
'nautilus-network-view.c',
|
||||
'nautilus-network-view.h',
|
||||
'nautilus-new-folder-dialog.c',
|
||||
'nautilus-new-folder-dialog.h',
|
||||
'nautilus-compress-dialog.c',
|
||||
|
@ -197,6 +197,8 @@ libnautilus_sources = [
|
|||
'nautilus-icon-info.c',
|
||||
'nautilus-icon-info.h',
|
||||
'nautilus-icon-names.h',
|
||||
'nautilus-internal-place-file.c',
|
||||
'nautilus-internal-place-file.h',
|
||||
'nautilus-keyfile-metadata.c',
|
||||
'nautilus-keyfile-metadata.h',
|
||||
'nautilus-metadata.h',
|
||||
|
@ -213,6 +215,8 @@ libnautilus_sources = [
|
|||
'nautilus-progress-paintable.h',
|
||||
'nautilus-program-choosing.c',
|
||||
'nautilus-program-choosing.h',
|
||||
'nautilus-recent-servers.c',
|
||||
'nautilus-recent-servers.h',
|
||||
'nautilus-search-directory.c',
|
||||
'nautilus-search-directory.h',
|
||||
'nautilus-search-directory-file.c',
|
||||
|
@ -229,6 +233,8 @@ libnautilus_sources = [
|
|||
'nautilus-search-engine-simple.h',
|
||||
'nautilus-search-hit.c',
|
||||
'nautilus-search-hit.h',
|
||||
'nautilus-shortcut-manager.c',
|
||||
'nautilus-shortcut-manager.h',
|
||||
'nautilus-signaller.h',
|
||||
'nautilus-signaller.c',
|
||||
'nautilus-query.c',
|
||||
|
|
|
@ -288,7 +288,6 @@ get_window_slot_for_location (NautilusApplication *self,
|
|||
|
||||
if (file != NULL &&
|
||||
!nautilus_file_is_directory (file) &&
|
||||
!nautilus_file_is_other_locations (file) &&
|
||||
g_file_has_parent (location, NULL))
|
||||
{
|
||||
searched_location = g_file_get_parent (location);
|
||||
|
@ -317,6 +316,13 @@ get_window_slot_for_location (NautilusApplication *self,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static NautilusWindow *
|
||||
get_nautilus_window_containing_slot (NautilusWindowSlot *slot)
|
||||
{
|
||||
return NAUTILUS_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (slot),
|
||||
NAUTILUS_TYPE_WINDOW));
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_application_open_location_full (NautilusApplication *self,
|
||||
GFile *location,
|
||||
|
@ -391,7 +397,7 @@ real_open_location_full (NautilusApplication *self,
|
|||
* slot we target at */
|
||||
if (target_slot != NULL)
|
||||
{
|
||||
target_window = nautilus_window_slot_get_window (target_slot);
|
||||
target_window = get_nautilus_window_containing_slot (target_slot);
|
||||
}
|
||||
|
||||
g_assert (!((flags & NAUTILUS_OPEN_FLAG_NEW_WINDOW) != 0 &&
|
||||
|
@ -414,7 +420,7 @@ real_open_location_full (NautilusApplication *self,
|
|||
}
|
||||
else
|
||||
{
|
||||
target_window = nautilus_window_slot_get_window (target_slot);
|
||||
target_window = get_nautilus_window_containing_slot (target_slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -483,7 +489,7 @@ nautilus_application_open_location (NautilusApplication *self,
|
|||
}
|
||||
else
|
||||
{
|
||||
window = nautilus_window_slot_get_window (slot);
|
||||
window = get_nautilus_window_containing_slot (slot);
|
||||
}
|
||||
|
||||
nautilus_application_open_location_full (self, location, 0, sel_list, window, slot);
|
||||
|
|
|
@ -36,7 +36,7 @@ struct _NautilusBatchRenameDialog
|
|||
GtkDialog parent;
|
||||
|
||||
GtkWidget *grid;
|
||||
NautilusWindow *window;
|
||||
GtkRoot *window;
|
||||
|
||||
GtkWidget *cancel_button;
|
||||
GtkWidget *original_name_listbox;
|
||||
|
@ -1824,7 +1824,7 @@ nautilus_batch_rename_dialog_class_init (NautilusBatchRenameDialogClass *klass)
|
|||
GtkWidget *
|
||||
nautilus_batch_rename_dialog_new (GList *selection,
|
||||
NautilusDirectory *directory,
|
||||
NautilusWindow *window)
|
||||
GtkRoot *window)
|
||||
{
|
||||
NautilusBatchRenameDialog *dialog;
|
||||
GString *dialog_title;
|
||||
|
|
|
@ -223,7 +223,7 @@ G_DECLARE_FINAL_TYPE (NautilusBatchRenameDialog, nautilus_batch_rename_dialog, N
|
|||
|
||||
GtkWidget* nautilus_batch_rename_dialog_new (GList *selection,
|
||||
NautilusDirectory *directory,
|
||||
NautilusWindow *window);
|
||||
GtkRoot *window);
|
||||
|
||||
void nautilus_batch_rename_dialog_query_finished (NautilusBatchRenameDialog *dialog,
|
||||
GHashTable *hash_table,
|
||||
|
|
|
@ -939,10 +939,7 @@ on_cursor_callback (GObject *object,
|
|||
break;
|
||||
}
|
||||
|
||||
/* TODO: Figure out how to inform the user of why the metadata is
|
||||
* unavailable when one or more contains the unallowed character "/"
|
||||
*/
|
||||
if (!current_metadata || g_strrstr (current_metadata, "/"))
|
||||
if (!current_metadata)
|
||||
{
|
||||
remove_metadata (query_data,
|
||||
metadata_type);
|
||||
|
@ -975,6 +972,7 @@ on_cursor_callback (GObject *object,
|
|||
else
|
||||
{
|
||||
file_metadata->metadata[metadata_type] = g_string_new (current_metadata);
|
||||
g_string_replace (file_metadata->metadata[metadata_type], "/", "_", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,18 +86,6 @@ new_bookmark_from_uri (const char *uri,
|
|||
return new_bookmark;
|
||||
}
|
||||
|
||||
static GFile *
|
||||
nautilus_bookmark_list_get_legacy_file (void)
|
||||
{
|
||||
g_autofree char *filename = NULL;
|
||||
|
||||
filename = g_build_filename (g_get_home_dir (),
|
||||
".gtk-bookmarks",
|
||||
NULL);
|
||||
|
||||
return g_file_new_for_path (filename);
|
||||
}
|
||||
|
||||
static GFile *
|
||||
nautilus_bookmark_list_get_file (void)
|
||||
{
|
||||
|
@ -125,14 +113,19 @@ bookmark_in_list_changed_callback (NautilusBookmark *bookmark,
|
|||
}
|
||||
|
||||
static void
|
||||
bookmark_in_list_notify (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
NautilusBookmarkList *bookmarks)
|
||||
bookmark_in_list_icon_changed (NautilusBookmarkList *bookmarks)
|
||||
{
|
||||
/* emit the changed signal without saving, as only appearance properties changed */
|
||||
g_signal_emit (bookmarks, signals[CHANGED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
bookmark_in_list_name_changed (NautilusBookmarkList *bookmarks)
|
||||
{
|
||||
nautilus_bookmark_list_save_file (bookmarks);
|
||||
g_signal_emit (bookmarks, signals[CHANGED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_monitoring_bookmark (NautilusBookmarkList *bookmarks,
|
||||
NautilusBookmark *bookmark)
|
||||
|
@ -238,9 +231,9 @@ insert_bookmark_internal (NautilusBookmarkList *bookmarks,
|
|||
g_signal_connect_object (bookmark, "contents-changed",
|
||||
G_CALLBACK (bookmark_in_list_changed_callback), bookmarks, 0);
|
||||
g_signal_connect_object (bookmark, "notify::icon",
|
||||
G_CALLBACK (bookmark_in_list_notify), bookmarks, 0);
|
||||
G_CALLBACK (bookmark_in_list_icon_changed), bookmarks, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (bookmark, "notify::name",
|
||||
G_CALLBACK (bookmark_in_list_notify), bookmarks, 0);
|
||||
G_CALLBACK (bookmark_in_list_name_changed), bookmarks, G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,6 +307,176 @@ nautilus_bookmark_list_append (NautilusBookmarkList *bookmarks,
|
|||
nautilus_bookmark_list_save_file (bookmarks);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_bookmark_list_contains:
|
||||
*
|
||||
* Check whether a bookmark with matching name and url is already in the list.
|
||||
* @bookmarks: NautilusBookmarkList to check contents of.
|
||||
* @bookmark: NautilusBookmark to match against.
|
||||
*
|
||||
* Return value: TRUE if matching bookmark is in list, FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
nautilus_bookmark_list_contains (NautilusBookmarkList *bookmarks,
|
||||
NautilusBookmark *bookmark)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks), FALSE);
|
||||
g_return_val_if_fail (NAUTILUS_IS_BOOKMARK (bookmark), FALSE);
|
||||
|
||||
return g_list_find_custom (bookmarks->list,
|
||||
(gpointer) bookmark,
|
||||
nautilus_bookmark_compare_with) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_bookmark_list_delete_item_at:
|
||||
*
|
||||
* Delete the bookmark at the specified position.
|
||||
* @bookmarks: the list of bookmarks.
|
||||
* @index: index, must be less than length of list.
|
||||
**/
|
||||
void
|
||||
nautilus_bookmark_list_delete_item_at (NautilusBookmarkList *bookmarks,
|
||||
guint index)
|
||||
{
|
||||
g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks));
|
||||
g_return_if_fail (index < g_list_length (bookmarks->list));
|
||||
|
||||
GList *doomed = g_list_nth (bookmarks->list, index);
|
||||
|
||||
g_assert (NAUTILUS_IS_BOOKMARK (doomed->data));
|
||||
stop_monitoring_bookmark (bookmarks, NAUTILUS_BOOKMARK (doomed->data));
|
||||
g_object_unref (doomed->data);
|
||||
|
||||
bookmarks->list = g_list_delete_link (bookmarks->list, doomed);
|
||||
|
||||
nautilus_bookmark_list_save_file (bookmarks);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_bookmark_list_move_item:
|
||||
*
|
||||
* Move the item from the given position to the destination.
|
||||
* @index: the index of the first bookmark.
|
||||
* @destination: the index of the second bookmark.
|
||||
**/
|
||||
void
|
||||
nautilus_bookmark_list_move_item (NautilusBookmarkList *bookmarks,
|
||||
guint index,
|
||||
guint destination)
|
||||
{
|
||||
if (index == destination)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GList *link_to_move = g_list_nth (bookmarks->list, index);
|
||||
|
||||
bookmarks->list = g_list_remove_link (bookmarks->list,
|
||||
link_to_move);
|
||||
|
||||
GList *link_at_destination = g_list_nth (bookmarks->list, destination);
|
||||
/* NULL link at destination means end of the list */
|
||||
bookmarks->list = g_list_insert_before_link (bookmarks->list,
|
||||
link_at_destination,
|
||||
link_to_move);
|
||||
|
||||
nautilus_bookmark_list_save_file (bookmarks);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_bookmark_list_delete_items_with_uri:
|
||||
*
|
||||
* Delete all bookmarks with the given uri.
|
||||
* @bookmarks: the list of bookmarks.
|
||||
* @uri: The uri to match.
|
||||
**/
|
||||
void
|
||||
nautilus_bookmark_list_delete_items_with_uri (NautilusBookmarkList *bookmarks,
|
||||
const char *uri)
|
||||
{
|
||||
g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks));
|
||||
g_return_if_fail (uri != NULL);
|
||||
|
||||
gboolean list_changed = FALSE;
|
||||
GList *next = NULL;
|
||||
|
||||
for (GList *node = bookmarks->list; node != NULL; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
|
||||
g_autofree char *bookmark_uri = nautilus_bookmark_get_uri (NAUTILUS_BOOKMARK (node->data));
|
||||
|
||||
if (g_strcmp0 (bookmark_uri, uri) == 0)
|
||||
{
|
||||
stop_monitoring_bookmark (bookmarks, NAUTILUS_BOOKMARK (node->data));
|
||||
g_object_unref (node->data);
|
||||
bookmarks->list = g_list_delete_link (bookmarks->list, node);
|
||||
list_changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (list_changed)
|
||||
{
|
||||
nautilus_bookmark_list_save_file (bookmarks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_bookmark_list_insert_item:
|
||||
*
|
||||
* Insert a bookmark at a specified position.
|
||||
* @bookmarks: the list of bookmarks.
|
||||
* @index: the position to insert the bookmark at.
|
||||
* @new_bookmark: the bookmark to insert a copy of.
|
||||
**/
|
||||
void
|
||||
nautilus_bookmark_list_insert_item (NautilusBookmarkList *bookmarks,
|
||||
NautilusBookmark *new_bookmark,
|
||||
guint index)
|
||||
{
|
||||
g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks));
|
||||
g_return_if_fail (index <= g_list_length (bookmarks->list));
|
||||
|
||||
insert_bookmark_internal (bookmarks, g_object_ref (new_bookmark), index);
|
||||
nautilus_bookmark_list_save_file (bookmarks);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_bookmark_list_item_at:
|
||||
*
|
||||
* Get the bookmark at the specified position.
|
||||
* @bookmarks: the list of bookmarks.
|
||||
* @index: index, must be less than length of list.
|
||||
*
|
||||
* Return value: the bookmark at position @index in @bookmarks.
|
||||
**/
|
||||
NautilusBookmark *
|
||||
nautilus_bookmark_list_item_at (NautilusBookmarkList *bookmarks,
|
||||
guint index)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks), NULL);
|
||||
g_return_val_if_fail (index < g_list_length (bookmarks->list), NULL);
|
||||
|
||||
return NAUTILUS_BOOKMARK (g_list_nth_data (bookmarks->list, index));
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_bookmark_list_length:
|
||||
*
|
||||
* Get the number of bookmarks in the list.
|
||||
* @bookmarks: the list of bookmarks.
|
||||
*
|
||||
* Return value: the length of the bookmark list.
|
||||
**/
|
||||
guint
|
||||
nautilus_bookmark_list_length (NautilusBookmarkList *bookmarks)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks), 0);
|
||||
|
||||
return g_list_length (bookmarks->list);
|
||||
}
|
||||
|
||||
static void
|
||||
process_next_op (NautilusBookmarkList *bookmarks);
|
||||
|
||||
|
@ -388,11 +551,6 @@ load_io_thread (GTask *task,
|
|||
GError *error = NULL;
|
||||
|
||||
file = nautilus_bookmark_list_get_file ();
|
||||
if (!g_file_query_exists (file, NULL))
|
||||
{
|
||||
g_object_unref (file);
|
||||
file = nautilus_bookmark_list_get_legacy_file ();
|
||||
}
|
||||
|
||||
g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
|
||||
g_object_unref (file);
|
||||
|
@ -612,8 +770,6 @@ gboolean
|
|||
nautilus_bookmark_list_can_bookmark_location (NautilusBookmarkList *list,
|
||||
GFile *location)
|
||||
{
|
||||
g_autoptr (NautilusBookmark) bookmark = NULL;
|
||||
|
||||
if (nautilus_bookmark_list_item_with_location (list, location, NULL))
|
||||
{
|
||||
/* Already bookmarked */
|
||||
|
@ -628,15 +784,13 @@ nautilus_bookmark_list_can_bookmark_location (NautilusBookmarkList *list,
|
|||
if (g_file_has_uri_scheme (location, SCHEME_RECENT) ||
|
||||
g_file_has_uri_scheme (location, SCHEME_STARRED) ||
|
||||
nautilus_is_home_directory (location) ||
|
||||
g_file_has_uri_scheme (location, SCHEME_TRASH) ||
|
||||
g_file_has_uri_scheme (location, SCHEME_OTHER_LOCATIONS))
|
||||
g_file_has_uri_scheme (location, SCHEME_TRASH))
|
||||
{
|
||||
/* Already in the sidebar */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bookmark = nautilus_bookmark_new (location, NULL);
|
||||
return !nautilus_bookmark_get_is_builtin (bookmark);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,5 +43,19 @@ NautilusBookmark * nautilus_bookmark_list_item_with_location (NautilusBook
|
|||
gboolean nautilus_bookmark_list_can_bookmark_location (NautilusBookmarkList *list,
|
||||
GFile *location);
|
||||
GList * nautilus_bookmark_list_get_all (NautilusBookmarkList *bookmarks);
|
||||
|
||||
gboolean nautilus_bookmark_list_contains (NautilusBookmarkList *bookmarks,
|
||||
NautilusBookmark *bookmark);
|
||||
void nautilus_bookmark_list_delete_item_at (NautilusBookmarkList *bookmarks,
|
||||
guint index);
|
||||
void nautilus_bookmark_list_delete_items_with_uri (NautilusBookmarkList *bookmarks,
|
||||
const char *uri);
|
||||
void nautilus_bookmark_list_insert_item (NautilusBookmarkList *bookmarks,
|
||||
NautilusBookmark *bookmark,
|
||||
guint index);
|
||||
guint nautilus_bookmark_list_length (NautilusBookmarkList *bookmarks);
|
||||
NautilusBookmark * nautilus_bookmark_list_item_at (NautilusBookmarkList *bookmarks,
|
||||
guint index);
|
||||
void nautilus_bookmark_list_move_item (NautilusBookmarkList *bookmarks,
|
||||
guint index,
|
||||
guint destination);
|
||||
G_END_DECLS
|
||||
|
|
|
@ -75,12 +75,19 @@ static void nautilus_bookmark_disconnect_file (NautilusBookmark *file);
|
|||
|
||||
G_DEFINE_TYPE (NautilusBookmark, nautilus_bookmark, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
nautilus_bookmark_set_name_internal (NautilusBookmark *bookmark,
|
||||
const char *new_name)
|
||||
void
|
||||
nautilus_bookmark_set_name (NautilusBookmark *bookmark,
|
||||
const char *new_name)
|
||||
{
|
||||
if (g_set_str (&bookmark->name, new_name))
|
||||
{
|
||||
if ((new_name == NULL && bookmark->has_custom_name) ||
|
||||
(new_name != NULL && !bookmark->has_custom_name))
|
||||
{
|
||||
bookmark->has_custom_name = !bookmark->has_custom_name;
|
||||
g_object_notify_by_pspec (G_OBJECT (bookmark), properties[PROP_CUSTOM_NAME]);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (bookmark), properties[PROP_NAME]);
|
||||
}
|
||||
}
|
||||
|
@ -98,17 +105,13 @@ bookmark_set_name_from_ready_file (NautilusBookmark *self,
|
|||
|
||||
display_name = nautilus_file_get_display_name (self->file);
|
||||
|
||||
if (nautilus_file_is_other_locations (self->file))
|
||||
if (nautilus_file_is_home (self->file))
|
||||
{
|
||||
nautilus_bookmark_set_name_internal (self, _("Other Locations"));
|
||||
}
|
||||
else if (nautilus_file_is_home (self->file))
|
||||
{
|
||||
nautilus_bookmark_set_name_internal (self, _("Home"));
|
||||
nautilus_bookmark_set_name (self, _("Home"));
|
||||
}
|
||||
else if (g_strcmp0 (self->name, display_name) != 0)
|
||||
{
|
||||
nautilus_bookmark_set_name_internal (self, display_name);
|
||||
nautilus_bookmark_set_name (self, display_name);
|
||||
g_debug ("%s: name changed to %s", nautilus_bookmark_get_name (self), display_name);
|
||||
}
|
||||
}
|
||||
|
@ -162,103 +165,59 @@ bookmark_file_changed_callback (NautilusFile *file,
|
|||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nautilus_bookmark_get_is_builtin (NautilusBookmark *bookmark)
|
||||
{
|
||||
GUserDirectory xdg_type;
|
||||
|
||||
/* if this is not an XDG dir, it's never builtin */
|
||||
if (!nautilus_bookmark_get_xdg_type (bookmark, &xdg_type))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* exclude XDG locations which are not in our builtin list */
|
||||
return (xdg_type != G_USER_DIRECTORY_DESKTOP) &&
|
||||
(xdg_type != G_USER_DIRECTORY_TEMPLATES) &&
|
||||
(xdg_type != G_USER_DIRECTORY_PUBLIC_SHARE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
static gboolean
|
||||
nautilus_bookmark_get_xdg_type (NautilusBookmark *bookmark,
|
||||
GUserDirectory *directory)
|
||||
{
|
||||
gboolean match;
|
||||
GFile *location;
|
||||
const gchar *path;
|
||||
GUserDirectory dir;
|
||||
|
||||
match = FALSE;
|
||||
|
||||
for (dir = 0; dir < G_USER_N_DIRECTORIES; dir++)
|
||||
for (GUserDirectory dir = 0; dir < G_USER_N_DIRECTORIES; dir++)
|
||||
{
|
||||
path = g_get_user_special_dir (dir);
|
||||
if (!path)
|
||||
const gchar *path = g_get_user_special_dir (dir);
|
||||
|
||||
if (path == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
location = g_file_new_for_path (path);
|
||||
match = g_file_equal (location, bookmark->location);
|
||||
g_object_unref (location);
|
||||
g_autoptr (GFile) location = g_file_new_for_path (path);
|
||||
|
||||
if (match)
|
||||
if (g_file_equal (location, bookmark->location))
|
||||
{
|
||||
break;
|
||||
if (directory != NULL)
|
||||
{
|
||||
*directory = dir;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (match && directory != NULL)
|
||||
{
|
||||
*directory = dir;
|
||||
}
|
||||
|
||||
return match;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GIcon *
|
||||
get_native_icon (NautilusBookmark *bookmark,
|
||||
gboolean symbolic)
|
||||
{
|
||||
if (!bookmark->exists)
|
||||
{
|
||||
g_debug ("%s: file does not exist, set warning icon", nautilus_bookmark_get_name (bookmark));
|
||||
return g_themed_icon_new (symbolic ? "dialog-warning-symbolic" : "dialog-warning");
|
||||
}
|
||||
|
||||
GUserDirectory xdg_type;
|
||||
GIcon *icon = NULL;
|
||||
|
||||
if (bookmark->file == NULL)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!nautilus_bookmark_get_xdg_type (bookmark, &xdg_type))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xdg_type < G_USER_N_DIRECTORIES)
|
||||
if (nautilus_bookmark_get_xdg_type (bookmark, &xdg_type))
|
||||
{
|
||||
if (symbolic)
|
||||
{
|
||||
icon = nautilus_special_directory_get_symbolic_icon (xdg_type);
|
||||
return nautilus_special_directory_get_symbolic_icon (xdg_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = nautilus_special_directory_get_icon (xdg_type);
|
||||
return nautilus_special_directory_get_icon (xdg_type);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (icon == NULL)
|
||||
{
|
||||
if (symbolic)
|
||||
{
|
||||
icon = g_themed_icon_new (NAUTILUS_ICON_FOLDER);
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = g_themed_icon_new (NAUTILUS_ICON_FULLCOLOR_FOLDER);
|
||||
}
|
||||
}
|
||||
|
||||
return icon;
|
||||
return g_themed_icon_new (symbolic ? NAUTILUS_ICON_FOLDER : NAUTILUS_ICON_FULLCOLOR_FOLDER);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -267,13 +226,7 @@ nautilus_bookmark_set_icon_to_default (NautilusBookmark *bookmark)
|
|||
g_autoptr (GIcon) icon = NULL;
|
||||
g_autoptr (GIcon) symbolic_icon = NULL;
|
||||
|
||||
if (!bookmark->exists)
|
||||
{
|
||||
g_debug ("%s: file does not exist, set warning icon", nautilus_bookmark_get_name (bookmark));
|
||||
symbolic_icon = g_themed_icon_new ("dialog-warning-symbolic");
|
||||
icon = g_themed_icon_new ("dialog-warning");
|
||||
}
|
||||
else if (g_file_is_native (bookmark->location))
|
||||
if (g_file_is_native (bookmark->location))
|
||||
{
|
||||
symbolic_icon = get_native_icon (bookmark, TRUE);
|
||||
icon = get_native_icon (bookmark, FALSE);
|
||||
|
@ -489,7 +442,7 @@ nautilus_bookmark_set_property (GObject *object,
|
|||
|
||||
case PROP_NAME:
|
||||
{
|
||||
nautilus_bookmark_set_name_internal (self, g_value_get_string (value));
|
||||
nautilus_bookmark_set_name (self, g_value_get_string (value));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -603,7 +556,7 @@ nautilus_bookmark_class_init (NautilusBookmarkClass *class)
|
|||
"Bookmark's name",
|
||||
"The name of this bookmark",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT);
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_CUSTOM_NAME] =
|
||||
g_param_spec_boolean ("custom-name",
|
||||
|
|
|
@ -40,9 +40,6 @@ GFile * nautilus_bookmark_get_location (NautilusBookmark
|
|||
char * nautilus_bookmark_get_uri (NautilusBookmark *bookmark);
|
||||
GIcon * nautilus_bookmark_get_icon (NautilusBookmark *bookmark);
|
||||
GIcon * nautilus_bookmark_get_symbolic_icon (NautilusBookmark *bookmark);
|
||||
gboolean nautilus_bookmark_get_xdg_type (NautilusBookmark *bookmark,
|
||||
GUserDirectory *directory);
|
||||
gboolean nautilus_bookmark_get_is_builtin (NautilusBookmark *bookmark);
|
||||
gboolean nautilus_bookmark_get_has_custom_name (NautilusBookmark *bookmark);
|
||||
int nautilus_bookmark_compare_with (gconstpointer a,
|
||||
gconstpointer b);
|
||||
|
@ -50,5 +47,7 @@ int nautilus_bookmark_compare_with (gconstpointer
|
|||
void nautilus_bookmark_take_selected_uris (NautilusBookmark *bookmark,
|
||||
GStrv selected_uris);
|
||||
GStrv nautilus_bookmark_get_selected_uris (NautilusBookmark *bookmark);
|
||||
void nautilus_bookmark_set_name (NautilusBookmark *bookmark,
|
||||
const char *new_name);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
#include "nautilus-hash-queue.h"
|
||||
#include "nautilus-metadata.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-search-directory-file.h"
|
||||
#include "nautilus-search-directory.h"
|
||||
#include "nautilus-starred-directory.h"
|
||||
#include "nautilus-vfs-directory.h"
|
||||
#include "nautilus-vfs-file.h"
|
||||
|
||||
|
@ -124,32 +121,9 @@ real_new_file_from_filename (NautilusDirectory *directory,
|
|||
const char *filename,
|
||||
gboolean self_owned)
|
||||
{
|
||||
NautilusFile *file;
|
||||
|
||||
g_assert (NAUTILUS_IS_DIRECTORY (directory));
|
||||
g_assert (filename != NULL);
|
||||
g_assert (filename[0] != '\0');
|
||||
|
||||
if (NAUTILUS_IS_SEARCH_DIRECTORY (directory))
|
||||
{
|
||||
if (self_owned)
|
||||
{
|
||||
file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_SEARCH_DIRECTORY_FILE, NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This doesn't normally happen, unless the user somehow types in a uri
|
||||
* that references a file like this. (See #349840) */
|
||||
file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_VFS_FILE, NULL));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_VFS_FILE, NULL));
|
||||
}
|
||||
nautilus_file_set_directory (file, directory);
|
||||
|
||||
return file;
|
||||
return NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_VFS_FILE,
|
||||
"directory", directory,
|
||||
NULL));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -687,6 +661,10 @@ nautilus_directory_new_file_from_filename (NautilusDirectory *directory,
|
|||
const char *filename,
|
||||
gboolean self_owned)
|
||||
{
|
||||
g_assert (NAUTILUS_IS_DIRECTORY (directory));
|
||||
g_assert (filename != NULL);
|
||||
g_assert (filename[0] != '\0');
|
||||
|
||||
return NAUTILUS_DIRECTORY_CLASS (G_OBJECT_GET_CLASS (directory))->new_file_from_filename (directory,
|
||||
filename,
|
||||
self_owned);
|
||||
|
|
|
@ -271,6 +271,11 @@ nautilus_fd_holders_release_for_mount (GMount *mount)
|
|||
GFile *location;
|
||||
GFileEnumerator *enumerator;
|
||||
|
||||
if (G_UNLIKELY (location_enumerator_map == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, location_enumerator_map);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &location, (gpointer *) &enumerator))
|
||||
{
|
||||
|
|
|
@ -116,7 +116,7 @@ typedef struct
|
|||
char *filename;
|
||||
gboolean make_dir;
|
||||
GFile *src;
|
||||
char *src_data;
|
||||
void *src_data;
|
||||
int length;
|
||||
gboolean new_mtime;
|
||||
GFile *created_file;
|
||||
|
@ -7118,7 +7118,7 @@ create_task_thread_func (GTask *task,
|
|||
gboolean filename_is_utf8;
|
||||
char *primary, *secondary, *details;
|
||||
int response;
|
||||
char *data;
|
||||
void *data;
|
||||
gsize length;
|
||||
GFileOutputStream *out;
|
||||
gboolean handled_invalid_filename;
|
||||
|
@ -7222,7 +7222,7 @@ retry:
|
|||
res = g_file_copy (job->src,
|
||||
dest,
|
||||
G_FILE_COPY_TARGET_DEFAULT_PERMS |
|
||||
job->new_mtime ? G_FILE_COPY_TARGET_DEFAULT_MODIFIED_TIME : 0,
|
||||
(job->new_mtime ? G_FILE_COPY_TARGET_DEFAULT_MODIFIED_TIME : 0),
|
||||
common->cancellable,
|
||||
NULL, NULL,
|
||||
&error);
|
||||
|
@ -7254,7 +7254,7 @@ retry:
|
|||
}
|
||||
else
|
||||
{
|
||||
data = "";
|
||||
data = NULL;
|
||||
length = 0;
|
||||
if (job->src_data)
|
||||
{
|
||||
|
@ -7694,7 +7694,7 @@ void
|
|||
nautilus_file_operations_new_file (GtkWidget *parent_view,
|
||||
const char *parent_dir,
|
||||
const char *target_filename,
|
||||
const char *initial_contents,
|
||||
const void *initial_contents,
|
||||
gsize length,
|
||||
NautilusCreateCallback done_callback,
|
||||
gpointer done_callback_data)
|
||||
|
|
|
@ -68,7 +68,7 @@ void nautilus_file_operations_new_folder (GtkWidget *paren
|
|||
void nautilus_file_operations_new_file (GtkWidget *parent_view,
|
||||
const char *parent_dir,
|
||||
const char *target_filename,
|
||||
const char *initial_contents,
|
||||
const void *initial_contents,
|
||||
gsize length,
|
||||
NautilusCreateCallback done_callback,
|
||||
gpointer data);
|
||||
|
|
|
@ -805,9 +805,13 @@ struct _NautilusFileUndoInfoCreate
|
|||
{
|
||||
NautilusFileUndoInfo parent_instance;
|
||||
|
||||
char *template;
|
||||
union
|
||||
{
|
||||
char *template;
|
||||
void *buffer;
|
||||
};
|
||||
GFile *target_file;
|
||||
gint length;
|
||||
gsize length;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NautilusFileUndoInfoCreate, nautilus_file_undo_info_create, NAUTILUS_TYPE_FILE_UNDO_INFO)
|
||||
|
@ -1011,12 +1015,23 @@ nautilus_file_undo_info_create_new (NautilusFileUndoOp op_type)
|
|||
void
|
||||
nautilus_file_undo_info_create_set_data (NautilusFileUndoInfoCreate *self,
|
||||
GFile *file,
|
||||
const char *template,
|
||||
const void *template,
|
||||
gsize length)
|
||||
{
|
||||
NautilusFileUndoOp op_type = nautilus_file_undo_info_get_op_type (NAUTILUS_FILE_UNDO_INFO (self));
|
||||
|
||||
self->target_file = g_object_ref (file);
|
||||
self->template = g_strdup (template);
|
||||
self->length = length;
|
||||
if (op_type == NAUTILUS_FILE_UNDO_OP_CREATE_EMPTY_FILE)
|
||||
{
|
||||
/* Operation name is a misnomer, it still can hold data to write to
|
||||
* the newly created file. */
|
||||
self->buffer = g_memdup2 (template, length);
|
||||
self->length = length;
|
||||
}
|
||||
else if (op_type == NAUTILUS_FILE_UNDO_OP_CREATE_FILE_FROM_TEMPLATE)
|
||||
{
|
||||
self->template = g_strdup (template);
|
||||
}
|
||||
}
|
||||
|
||||
/* rename */
|
||||
|
|
|
@ -119,7 +119,7 @@ G_DECLARE_FINAL_TYPE (NautilusFileUndoInfoCreate, nautilus_file_undo_info_create
|
|||
NautilusFileUndoInfo *nautilus_file_undo_info_create_new (NautilusFileUndoOp op_type);
|
||||
void nautilus_file_undo_info_create_set_data (NautilusFileUndoInfoCreate *self,
|
||||
GFile *file,
|
||||
const char *template,
|
||||
const void *template,
|
||||
gsize length);
|
||||
|
||||
/* rename */
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
#include "nautilus-file-utilities.h"
|
||||
|
||||
#include "nautilus-application.h"
|
||||
#include "nautilus-file.h"
|
||||
#include "nautilus-file-operations.h"
|
||||
#include "nautilus-filename-utilities.h"
|
||||
#include "nautilus-global-preferences.h"
|
||||
#include "nautilus-icon-names.h"
|
||||
#include "nautilus-metadata.h"
|
||||
#include "nautilus-file.h"
|
||||
#include "nautilus-file-operations.h"
|
||||
#include "nautilus-filename-utilities.h"
|
||||
#include "nautilus-network-directory.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-search-directory.h"
|
||||
#include "nautilus-starred-directory.h"
|
||||
|
@ -70,18 +70,8 @@ nautilus_compute_title_for_location (GFile *location)
|
|||
{
|
||||
file = nautilus_file_get (location);
|
||||
|
||||
if (nautilus_file_is_other_locations (file))
|
||||
{
|
||||
title = g_strdup (_("Other Locations"));
|
||||
}
|
||||
else if (nautilus_file_is_starred_location (file))
|
||||
{
|
||||
title = g_strdup (_("Starred"));
|
||||
}
|
||||
else
|
||||
{
|
||||
title = g_strdup (nautilus_file_get_display_name (file));
|
||||
}
|
||||
title = g_strdup (nautilus_file_get_display_name (file));
|
||||
|
||||
nautilus_file_unref (file);
|
||||
}
|
||||
|
||||
|
@ -989,6 +979,7 @@ nautilus_ensure_extension_builtins (void)
|
|||
* that they will be registered by the time the extension point
|
||||
* is iterating over its extensions.
|
||||
*/
|
||||
g_type_ensure (NAUTILUS_TYPE_NETWORK_DIRECTORY);
|
||||
g_type_ensure (NAUTILUS_TYPE_SEARCH_DIRECTORY);
|
||||
g_type_ensure (NAUTILUS_TYPE_STARRED_DIRECTORY);
|
||||
}
|
||||
|
|
|
@ -182,6 +182,7 @@ G_DEFINE_TYPE_WITH_CODE (NautilusFile, nautilus_file, G_TYPE_OBJECT,
|
|||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_DIRECTORY,
|
||||
PROP_DISPLAY_NAME,
|
||||
N_PROPS
|
||||
};
|
||||
|
@ -587,16 +588,17 @@ void
|
|||
nautilus_file_set_directory (NautilusFile *file,
|
||||
NautilusDirectory *directory)
|
||||
{
|
||||
char *parent_uri;
|
||||
if (!g_set_object (&file->details->directory, directory))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_autofree char *parent_uri = nautilus_file_get_parent_uri (file);
|
||||
|
||||
g_clear_object (&file->details->directory);
|
||||
g_free (file->details->directory_name_collation_key);
|
||||
|
||||
file->details->directory = nautilus_directory_ref (directory);
|
||||
|
||||
parent_uri = nautilus_file_get_parent_uri (file);
|
||||
file->details->directory_name_collation_key = g_utf8_collate_key_for_filename (parent_uri, -1);
|
||||
g_free (parent_uri);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (file), properties[PROP_DIRECTORY]);
|
||||
}
|
||||
|
||||
NautilusFile *
|
||||
|
@ -719,8 +721,9 @@ nautilus_file_new_from_info (NautilusDirectory *directory,
|
|||
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
|
||||
file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_VFS_FILE, NULL));
|
||||
nautilus_file_set_directory (file, directory);
|
||||
file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_VFS_FILE,
|
||||
"directory", directory,
|
||||
NULL));
|
||||
|
||||
update_info_and_name (file, info);
|
||||
|
||||
|
@ -987,7 +990,7 @@ nautilus_file_unref (NautilusFile *file)
|
|||
* and adding trailing slash).
|
||||
* If the parent is NULL, returns the empty string.
|
||||
*/
|
||||
char *
|
||||
static char *
|
||||
nautilus_file_get_parent_uri_for_display (NautilusFile *file)
|
||||
{
|
||||
g_autoptr (GFile) parent = NULL;
|
||||
|
@ -1652,7 +1655,10 @@ nautilus_file_can_trash (NautilusFile *file)
|
|||
gboolean
|
||||
nautilus_file_opens_in_view (NautilusFile *file)
|
||||
{
|
||||
return nautilus_file_is_directory (file);
|
||||
return (nautilus_file_is_directory (file) ||
|
||||
nautilus_file_get_file_type (file) == G_FILE_TYPE_MOUNTABLE ||
|
||||
(nautilus_file_get_file_type (file) == G_FILE_TYPE_SHORTCUT &&
|
||||
g_strcmp0 (nautilus_file_get_mime_type (file), "inode/directory") == 0));
|
||||
}
|
||||
|
||||
NautilusFileOperation *
|
||||
|
@ -2425,6 +2431,7 @@ update_info_internal (NautilusFile *file,
|
|||
|
||||
if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL) ||
|
||||
file_type == G_FILE_TYPE_SHORTCUT ||
|
||||
file_type == G_FILE_TYPE_MOUNTABLE ||
|
||||
nautilus_file_is_in_recent (file))
|
||||
{
|
||||
if (g_set_str (&file->details->activation_uri,
|
||||
|
@ -4225,18 +4232,7 @@ nautilus_file_peek_display_name (NautilusFile *file)
|
|||
const char *
|
||||
nautilus_file_get_display_name (NautilusFile *file)
|
||||
{
|
||||
if (nautilus_file_is_other_locations (file))
|
||||
{
|
||||
return _("Other Locations");
|
||||
}
|
||||
else if (nautilus_file_is_starred_location (file))
|
||||
{
|
||||
return _("Starred");
|
||||
}
|
||||
else
|
||||
{
|
||||
return nautilus_file_peek_display_name (file);
|
||||
}
|
||||
return nautilus_file_peek_display_name (file);
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -4398,7 +4394,8 @@ get_default_file_icon (void)
|
|||
static GIcon *fallback_icon = NULL;
|
||||
if (fallback_icon == NULL)
|
||||
{
|
||||
fallback_icon = g_themed_icon_new ("application-x-generic");
|
||||
fallback_icon = g_themed_icon_new_from_names ((char *[]){"application-x-generic",
|
||||
"text-x-generic"}, 2);
|
||||
}
|
||||
|
||||
return fallback_icon;
|
||||
|
@ -4914,13 +4911,6 @@ GDateTime *
|
|||
nautilus_file_get_date (NautilusFile *file,
|
||||
NautilusDateType date_type)
|
||||
{
|
||||
g_return_val_if_fail (date_type == NAUTILUS_DATE_TYPE_ACCESSED
|
||||
|| date_type == NAUTILUS_DATE_TYPE_MODIFIED
|
||||
|| date_type == NAUTILUS_DATE_TYPE_CREATED
|
||||
|| date_type == NAUTILUS_DATE_TYPE_TRASHED
|
||||
|| date_type == NAUTILUS_DATE_TYPE_RECENCY,
|
||||
FALSE);
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -4928,7 +4918,53 @@ nautilus_file_get_date (NautilusFile *file,
|
|||
|
||||
g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
|
||||
|
||||
return NAUTILUS_FILE_CLASS (G_OBJECT_GET_CLASS (file))->get_date (file, date_type);
|
||||
time_t file_time_raw = 0;
|
||||
|
||||
switch (date_type)
|
||||
{
|
||||
case NAUTILUS_DATE_TYPE_ACCESSED:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_atime (file);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_DATE_TYPE_MODIFIED:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_mtime (file);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_DATE_TYPE_CREATED:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_btime (file);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_DATE_TYPE_TRASHED:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_trash_time (file);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_DATE_TYPE_RECENCY:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_recency (file);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Before we have info on a file, the date is unknown. */
|
||||
if (file_time_raw == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_date_time_new_from_unix_local (file_time_raw);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -4941,7 +4977,20 @@ nautilus_file_get_where_string (NautilusFile *file)
|
|||
|
||||
g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
|
||||
|
||||
return NAUTILUS_FILE_CLASS (G_OBJECT_GET_CLASS (file))->get_where_string (file);
|
||||
g_autoptr (NautilusFile) real_file = NULL;
|
||||
|
||||
if (nautilus_file_is_in_recent (file))
|
||||
{
|
||||
g_autoptr (GFile) activation_location = nautilus_file_get_activation_location (file);
|
||||
|
||||
real_file = nautilus_file_get (activation_location);
|
||||
}
|
||||
else
|
||||
{
|
||||
real_file = g_object_ref (file);
|
||||
}
|
||||
|
||||
return nautilus_file_get_parent_uri_for_display (real_file);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -7378,27 +7427,6 @@ nautilus_file_is_remote (NautilusFile *file)
|
|||
return get_filesystem_remote (file, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_file_is_other_locations
|
||||
*
|
||||
* Check if this file is Other Locations.
|
||||
* @file: NautilusFile representing the file in question.
|
||||
*
|
||||
* Returns: TRUE if @file is Other Locations.
|
||||
*
|
||||
**/
|
||||
gboolean
|
||||
nautilus_file_is_other_locations (NautilusFile *file)
|
||||
{
|
||||
g_autoptr (GFile) location = NULL;
|
||||
|
||||
g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE);
|
||||
|
||||
location = nautilus_file_get_location (file);
|
||||
|
||||
return nautilus_is_root_for_scheme (location, SCHEME_OTHER_LOCATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_file_is_starred_location
|
||||
*
|
||||
|
@ -7420,6 +7448,16 @@ nautilus_file_is_starred_location (NautilusFile *file)
|
|||
return g_file_has_uri_scheme (location, SCHEME_STARRED);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nautilus_file_is_network_view (NautilusFile *file)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_FILE (file), FALSE);
|
||||
|
||||
g_autoptr (GFile) location = nautilus_file_get_location (file);
|
||||
|
||||
return nautilus_is_root_for_scheme (location, SCHEME_NETWORK_VIEW);
|
||||
}
|
||||
|
||||
/**
|
||||
* nautilus_file_is_in_admin
|
||||
*
|
||||
|
@ -8471,22 +8509,6 @@ real_get_deep_counts (NautilusFile *file,
|
|||
return NAUTILUS_REQUEST_DONE;
|
||||
}
|
||||
|
||||
static void
|
||||
real_set_metadata (NautilusFile *file,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
/* Dummy default impl */
|
||||
}
|
||||
|
||||
static void
|
||||
real_set_metadata_as_list (NautilusFile *file,
|
||||
const char *key,
|
||||
char **value)
|
||||
{
|
||||
/* Dummy default impl */
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_file_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
|
@ -8510,6 +8532,35 @@ nautilus_file_get_property (GObject *object,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_file_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NautilusFile *file = NAUTILUS_FILE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DIRECTORY:
|
||||
{
|
||||
nautilus_file_set_directory (file, g_value_get_object (value));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
default_no_op (NautilusFile *file)
|
||||
{
|
||||
/* Dummy default impl */
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_file_class_init (NautilusFileClass *class)
|
||||
{
|
||||
|
@ -8553,11 +8604,22 @@ nautilus_file_class_init (NautilusFileClass *class)
|
|||
G_OBJECT_CLASS (class)->finalize = finalize;
|
||||
G_OBJECT_CLASS (class)->constructor = nautilus_file_constructor;
|
||||
G_OBJECT_CLASS (class)->get_property = nautilus_file_get_property;
|
||||
G_OBJECT_CLASS (class)->set_property = nautilus_file_set_property;
|
||||
|
||||
class->get_item_count = real_get_item_count;
|
||||
class->get_deep_counts = real_get_deep_counts;
|
||||
class->set_metadata = real_set_metadata;
|
||||
class->set_metadata_as_list = real_set_metadata_as_list;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
|
||||
class->set_metadata = default_no_op;
|
||||
class->set_metadata_as_list = default_no_op;
|
||||
class->mount = default_no_op;
|
||||
class->unmount = default_no_op;
|
||||
class->eject = default_no_op;
|
||||
class->start = default_no_op;
|
||||
class->stop = default_no_op;
|
||||
class->poll_for_media = default_no_op;
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
signals[CHANGED] =
|
||||
g_signal_new ("changed",
|
||||
|
@ -8598,6 +8660,10 @@ nautilus_file_class_init (NautilusFileClass *class)
|
|||
G_CALLBACK (mime_type_data_changed_callback),
|
||||
NULL);
|
||||
|
||||
properties[PROP_DIRECTORY] = g_param_spec_object ("directory", NULL, NULL,
|
||||
NAUTILUS_TYPE_DIRECTORY,
|
||||
(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
||||
properties[PROP_DISPLAY_NAME] = g_param_spec_string ("display-name", NULL, NULL,
|
||||
"",
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
|
|
@ -163,7 +163,6 @@ char * nautilus_file_get_uri_scheme (Nautilu
|
|||
NautilusFile * nautilus_file_get_parent (NautilusFile *file);
|
||||
GFile * nautilus_file_get_parent_location (NautilusFile *file);
|
||||
char * nautilus_file_get_parent_uri (NautilusFile *file);
|
||||
char * nautilus_file_get_parent_uri_for_display (NautilusFile *file);
|
||||
const char * nautilus_file_get_thumbnail_path (NautilusFile *file);
|
||||
gboolean nautilus_file_can_get_size (NautilusFile *file);
|
||||
guint64 nautilus_file_get_size (NautilusFile *file);
|
||||
|
@ -197,8 +196,8 @@ gboolean nautilus_file_is_in_recent (Nautilu
|
|||
gboolean nautilus_file_is_in_starred (NautilusFile *file);
|
||||
gboolean nautilus_file_is_in_admin (NautilusFile *file);
|
||||
gboolean nautilus_file_is_remote (NautilusFile *file);
|
||||
gboolean nautilus_file_is_other_locations (NautilusFile *file);
|
||||
gboolean nautilus_file_is_starred_location (NautilusFile *file);
|
||||
gboolean nautilus_file_is_network_view (NautilusFile *file);
|
||||
gboolean nautilus_file_is_home (NautilusFile *file);
|
||||
GError * nautilus_file_get_file_info_error (NautilusFile *file);
|
||||
gboolean nautilus_file_get_directory_item_count (NautilusFile *file,
|
||||
|
@ -500,7 +499,7 @@ typedef struct {
|
|||
/* Called periodically while directory deep count is being computed. */
|
||||
void (* updated_deep_count_in_progress) (NautilusFile *file);
|
||||
|
||||
/* Virtual functions (mainly used for trash directory). */
|
||||
/* Virtual functions which MUST be implemented by subclasses */
|
||||
void (* monitor_add) (NautilusFile *file,
|
||||
gconstpointer client,
|
||||
NautilusFileAttributes attributes);
|
||||
|
@ -515,6 +514,8 @@ typedef struct {
|
|||
gpointer callback_data);
|
||||
gboolean (* check_if_ready) (NautilusFile *file,
|
||||
NautilusFileAttributes attributes);
|
||||
|
||||
/* Virtual functions which MAY be overridden by subclasses */
|
||||
gboolean (* get_item_count) (NautilusFile *file,
|
||||
guint *count,
|
||||
gboolean *count_unreadable);
|
||||
|
@ -523,10 +524,8 @@ typedef struct {
|
|||
guint *file_count,
|
||||
guint *unreadable_directory_count,
|
||||
goffset *total_size);
|
||||
GDateTime * (* get_date) (NautilusFile *file,
|
||||
NautilusDateType type);
|
||||
char * (* get_where_string) (NautilusFile *file);
|
||||
|
||||
/* Virtual functions which MAY be implemented by subclasses (default implementation does nothing) */
|
||||
void (* set_metadata) (NautilusFile *file,
|
||||
const char *key,
|
||||
const char *value);
|
||||
|
|
|
@ -67,11 +67,13 @@
|
|||
#include "nautilus-list-view.h"
|
||||
#include "nautilus-metadata.h"
|
||||
#include "nautilus-mime-actions.h"
|
||||
#include "nautilus-network-view.h"
|
||||
#include "nautilus-module.h"
|
||||
#include "nautilus-new-folder-dialog.h"
|
||||
#include "nautilus-previewer.h"
|
||||
#include "nautilus-program-choosing.h"
|
||||
#include "nautilus-properties-window.h"
|
||||
#include "nautilus-recent-servers.h"
|
||||
#include "nautilus-rename-file-popover.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-search-directory.h"
|
||||
|
@ -82,7 +84,6 @@
|
|||
#include "nautilus-ui-utilities.h"
|
||||
#include "nautilus-view.h"
|
||||
#include "nautilus-view-model.h"
|
||||
#include "nautilus-window.h"
|
||||
#include "nautilus-tracker-utilities.h"
|
||||
|
||||
/* Minimum starting update inverval */
|
||||
|
@ -232,6 +233,7 @@ typedef struct
|
|||
GtkWidget *background_menu;
|
||||
|
||||
GActionGroup *view_action_group;
|
||||
GtkShortcutController *shortcuts;
|
||||
|
||||
/* Empty states */
|
||||
GtkWidget *empty_view_page;
|
||||
|
@ -953,11 +955,14 @@ nautilus_files_view_invert_selection (NautilusFilesView *self)
|
|||
static NautilusToolbarMenuSections *
|
||||
nautilus_files_view_get_toolbar_menu_sections (NautilusView *view)
|
||||
{
|
||||
NautilusFilesViewPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL);
|
||||
|
||||
priv = nautilus_files_view_get_instance_private (NAUTILUS_FILES_VIEW (view));
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (NAUTILUS_FILES_VIEW (view));
|
||||
|
||||
if (NAUTILUS_IS_NETWORK_VIEW (priv->list_base))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return priv->toolbar_menu_sections;
|
||||
}
|
||||
|
@ -1222,16 +1227,6 @@ create_templates_parameters_free (CreateTemplateParameters *parameters)
|
|||
g_free (parameters);
|
||||
}
|
||||
|
||||
static NautilusWindow *
|
||||
nautilus_files_view_get_window (NautilusFilesView *view)
|
||||
{
|
||||
NautilusFilesViewPrivate *priv;
|
||||
|
||||
priv = nautilus_files_view_get_instance_private (view);
|
||||
|
||||
return nautilus_window_slot_get_window (priv->slot);
|
||||
}
|
||||
|
||||
/* Returns the GtkWindow that this directory view occupies, or NULL
|
||||
* if at the moment this directory view is not in a GtkWindow or the
|
||||
* GtkWindow cannot be determined. Primarily used for parenting dialogs.
|
||||
|
@ -1270,53 +1265,13 @@ get_view_directory (NautilusFilesView *view)
|
|||
return path;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *uri;
|
||||
gboolean is_update;
|
||||
} PreviewExportData;
|
||||
|
||||
static void
|
||||
preview_export_data_free (gpointer _data)
|
||||
{
|
||||
PreviewExportData *data = _data;
|
||||
g_free (data->uri);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PreviewExportData, preview_export_data_free)
|
||||
|
||||
static void
|
||||
on_window_handle_export (NautilusWindow *window,
|
||||
const char *handle,
|
||||
guint xid,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr (PreviewExportData) data = user_data;
|
||||
nautilus_previewer_call_show_file (data->uri, handle, xid, !data->is_update);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_files_view_preview (NautilusFilesView *view,
|
||||
PreviewExportData *data)
|
||||
{
|
||||
if (!nautilus_window_export_handle (nautilus_files_view_get_window (view),
|
||||
on_window_handle_export,
|
||||
data))
|
||||
{
|
||||
/* Let's use a fallback, so at least a preview will be displayed */
|
||||
nautilus_previewer_call_show_file (data->uri, "x11:0", 0, !data->is_update);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_files_view_preview_update (NautilusFilesView *view)
|
||||
{
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
|
||||
GtkApplication *app;
|
||||
GtkWindow *window;
|
||||
GtkRoot *window;
|
||||
g_autolist (NautilusFile) selection = NULL;
|
||||
PreviewExportData *data;
|
||||
|
||||
if (!priv->active ||
|
||||
!nautilus_previewer_is_visible ())
|
||||
|
@ -1325,8 +1280,8 @@ nautilus_files_view_preview_update (NautilusFilesView *view)
|
|||
}
|
||||
|
||||
app = GTK_APPLICATION (g_application_get_default ());
|
||||
window = GTK_WINDOW (nautilus_files_view_get_window (view));
|
||||
if (window == NULL || window != gtk_application_get_active_window (app))
|
||||
window = gtk_widget_get_root (GTK_WIDGET (view));
|
||||
if (window == NULL || GTK_WINDOW (window) != gtk_application_get_active_window (app))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1337,11 +1292,9 @@ nautilus_files_view_preview_update (NautilusFilesView *view)
|
|||
return;
|
||||
}
|
||||
|
||||
data = g_new0 (PreviewExportData, 1);
|
||||
data->uri = nautilus_file_get_uri (selection->data);
|
||||
data->is_update = TRUE;
|
||||
g_autofree gchar *uri = nautilus_file_get_uri (selection->data);
|
||||
|
||||
nautilus_files_view_preview (view, data);
|
||||
nautilus_previewer_call_show_file (uri, window, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1815,14 +1768,13 @@ action_preview_selection (GSimpleAction *action,
|
|||
{
|
||||
NautilusFilesView *view = NAUTILUS_FILES_VIEW (user_data);
|
||||
g_autolist (NautilusFile) selection = NULL;
|
||||
PreviewExportData *data = g_new0 (PreviewExportData, 1);
|
||||
GtkRoot *window = gtk_widget_get_root (GTK_WIDGET (view));
|
||||
|
||||
selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
|
||||
|
||||
data->uri = nautilus_file_get_uri (selection->data);
|
||||
data->is_update = FALSE;
|
||||
g_autofree gchar *uri = nautilus_file_get_uri (selection->data);
|
||||
|
||||
nautilus_files_view_preview (view, data);
|
||||
nautilus_previewer_call_show_file (uri, window, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1872,12 +1824,10 @@ select_pattern (NautilusFilesView *view)
|
|||
{
|
||||
g_autoptr (GtkBuilder) builder = NULL;
|
||||
GtkWidget *dialog;
|
||||
NautilusWindow *window;
|
||||
GtkWidget *example;
|
||||
GtkWidget *entry, *select_button;
|
||||
char *example_pattern;
|
||||
|
||||
window = nautilus_files_view_get_window (view);
|
||||
builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-files-view-select-items.ui");
|
||||
dialog = GTK_WIDGET (gtk_builder_get_object (builder, "select_items_dialog"));
|
||||
|
||||
|
@ -1887,7 +1837,8 @@ select_pattern (NautilusFilesView *view)
|
|||
"*.png, file\?\?.txt, pict*.\?\?\?");
|
||||
gtk_label_set_markup (GTK_LABEL (example), example_pattern);
|
||||
g_free (example_pattern);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
|
||||
gtk_window_set_transient_for (GTK_WINDOW (dialog),
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (view))));
|
||||
|
||||
entry = GTK_WIDGET (gtk_builder_get_object (builder, "pattern_entry"));
|
||||
select_button = GTK_WIDGET (gtk_builder_get_object (builder, "select_button"));
|
||||
|
@ -2423,7 +2374,7 @@ void
|
|||
nautilus_files_view_new_file_with_initial_contents (NautilusFilesView *view,
|
||||
const char *parent_uri,
|
||||
const char *filename,
|
||||
const char *initial_contents,
|
||||
const void *initial_contents,
|
||||
gsize length)
|
||||
{
|
||||
NewFolderData *data;
|
||||
|
@ -3201,14 +3152,14 @@ slot_active_changed (NautilusWindowSlot *slot,
|
|||
|
||||
schedule_update_context_menus (view);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (nautilus_files_view_get_window (view)),
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (view))),
|
||||
"view",
|
||||
G_ACTION_GROUP (priv->view_action_group));
|
||||
}
|
||||
else
|
||||
{
|
||||
remove_update_context_menus_timeout_callback (view);
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (nautilus_files_view_get_window (view)),
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (view))),
|
||||
"view",
|
||||
NULL);
|
||||
}
|
||||
|
@ -3530,6 +3481,15 @@ nautilus_files_view_display_selection_info (NautilusFilesView *view)
|
|||
|
||||
g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
|
||||
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
|
||||
|
||||
if (priv->list_base != NULL && NAUTILUS_IS_NETWORK_VIEW (priv->list_base))
|
||||
{
|
||||
/* Selection info is not relevant on this view and visually clashes with
|
||||
* the action bar. */
|
||||
return;
|
||||
}
|
||||
|
||||
selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
|
||||
|
||||
folder_item_count_known = TRUE;
|
||||
|
@ -3858,6 +3818,12 @@ real_check_empty_states (NautilusFilesView *view)
|
|||
adw_status_page_set_title (status_page, _("No Recent Files"));
|
||||
adw_status_page_set_description (status_page, NULL);
|
||||
}
|
||||
else if (g_file_has_uri_scheme (priv->location, SCHEME_NETWORK_VIEW))
|
||||
{
|
||||
adw_status_page_set_icon_name (status_page, "network-computer-symbolic");
|
||||
adw_status_page_set_title (status_page, _("No Known Connections"));
|
||||
adw_status_page_set_description (status_page, _("Enter an address to connect to a network location."));
|
||||
}
|
||||
else
|
||||
{
|
||||
adw_status_page_set_icon_name (status_page, "folder-symbolic");
|
||||
|
@ -4465,13 +4431,12 @@ static void
|
|||
display_pending_files (NautilusFilesView *view)
|
||||
{
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
|
||||
g_autoptr (GtkBitset) selection = NULL;
|
||||
gboolean no_selection = FALSE;
|
||||
|
||||
search_transition_emit_delayed_signals_if_pending (view);
|
||||
|
||||
selection = gtk_selection_model_get_selection (GTK_SELECTION_MODEL (priv->model));
|
||||
no_selection = gtk_bitset_is_empty (selection);
|
||||
/* Get selection after delayed signals are emitted. */
|
||||
g_autoptr (GtkBitset) selection = gtk_selection_model_get_selection (GTK_SELECTION_MODEL (priv->model));
|
||||
gboolean no_selection = gtk_bitset_is_empty (selection);
|
||||
|
||||
process_pending_files (view);
|
||||
|
||||
|
@ -5475,8 +5440,9 @@ add_script_to_scripts_menus (NautilusFilesView *view,
|
|||
|
||||
if ((shortcut = g_hash_table_lookup (script_accels, name)))
|
||||
{
|
||||
nautilus_application_set_accelerator (g_application_get_default (),
|
||||
detailed_action_name, shortcut);
|
||||
gtk_shortcut_controller_add_shortcut (priv->shortcuts,
|
||||
gtk_shortcut_new (gtk_shortcut_trigger_parse_string (shortcut),
|
||||
gtk_named_action_new (detailed_action_name)));
|
||||
}
|
||||
|
||||
g_free (action_name);
|
||||
|
@ -6102,7 +6068,7 @@ copy_or_move_selection (NautilusFilesView *view,
|
|||
gtk_file_dialog_set_initial_folder (dialog, location);
|
||||
|
||||
gtk_file_dialog_select_folder (dialog,
|
||||
GTK_WINDOW (nautilus_files_view_get_window (view)),
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (view))),
|
||||
NULL,
|
||||
(GAsyncReadyCallback) on_destination_dialog_response,
|
||||
copy_data);
|
||||
|
@ -6254,9 +6220,8 @@ real_action_rename (NautilusFilesView *view)
|
|||
/* If there is more than one file selected, invoke a batch renamer */
|
||||
if (selection->next != NULL)
|
||||
{
|
||||
NautilusWindow *window;
|
||||
GtkRoot *window = gtk_widget_get_root (GTK_WIDGET (view));
|
||||
|
||||
window = nautilus_files_view_get_window (view);
|
||||
gtk_widget_set_cursor_from_name (GTK_WIDGET (window), "progress");
|
||||
|
||||
dialog = nautilus_batch_rename_dialog_new (selection,
|
||||
|
@ -6489,7 +6454,7 @@ extract_files_to_chosen_location (NautilusFilesView *view,
|
|||
data->files = nautilus_file_list_copy (files);
|
||||
|
||||
gtk_file_dialog_select_folder (dialog,
|
||||
GTK_WINDOW (nautilus_files_view_get_window (view)),
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (view))),
|
||||
NULL,
|
||||
(GAsyncReadyCallback) on_extract_destination_dialog_response,
|
||||
data);
|
||||
|
@ -6815,9 +6780,12 @@ file_mount_callback (NautilusFile *file,
|
|||
GError *error,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusFilesView *view;
|
||||
g_autoptr (NautilusFilesView) self = NAUTILUS_FILES_VIEW (callback_data);
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (self);
|
||||
NautilusViewItem *item = nautilus_view_model_get_item_for_file (priv->model, file);
|
||||
|
||||
view = NAUTILUS_FILES_VIEW (callback_data);
|
||||
nautilus_file_invalidate_attributes (file, NAUTILUS_FILE_ATTRIBUTE_MOUNT);
|
||||
nautilus_view_item_set_loading (item, FALSE);
|
||||
|
||||
if (error != NULL &&
|
||||
(error->domain != G_IO_ERROR ||
|
||||
|
@ -6830,7 +6798,7 @@ file_mount_callback (NautilusFile *file,
|
|||
nautilus_file_get_display_name (file));
|
||||
show_dialog (text,
|
||||
error->message,
|
||||
GTK_WINDOW (nautilus_files_view_get_window (view)),
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
|
||||
GTK_MESSAGE_ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -6841,10 +6809,11 @@ file_unmount_callback (NautilusFile *file,
|
|||
GError *error,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusFilesView *view;
|
||||
g_autoptr (NautilusFilesView) self = NAUTILUS_FILES_VIEW (callback_data);
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (self);
|
||||
NautilusViewItem *item = nautilus_view_model_get_item_for_file (priv->model, file);
|
||||
|
||||
view = NAUTILUS_FILES_VIEW (callback_data);
|
||||
g_object_unref (view);
|
||||
nautilus_view_item_set_loading (item, FALSE);
|
||||
|
||||
if (error != NULL &&
|
||||
(error->domain != G_IO_ERROR ||
|
||||
|
@ -6856,7 +6825,7 @@ file_unmount_callback (NautilusFile *file,
|
|||
nautilus_file_get_display_name (file));
|
||||
show_dialog (text,
|
||||
error->message,
|
||||
GTK_WINDOW (nautilus_files_view_get_window (view)),
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
|
||||
GTK_MESSAGE_ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -6867,10 +6836,7 @@ file_eject_callback (NautilusFile *file,
|
|||
GError *error,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusFilesView *view;
|
||||
|
||||
view = NAUTILUS_FILES_VIEW (callback_data);
|
||||
g_object_unref (view);
|
||||
g_autoptr (NautilusFilesView) self = NAUTILUS_FILES_VIEW (callback_data);
|
||||
|
||||
if (error != NULL &&
|
||||
(error->domain != G_IO_ERROR ||
|
||||
|
@ -6882,7 +6848,7 @@ file_eject_callback (NautilusFile *file,
|
|||
nautilus_file_get_display_name (file));
|
||||
show_dialog (text,
|
||||
error->message,
|
||||
GTK_WINDOW (nautilus_files_view_get_window (view)),
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
|
||||
GTK_MESSAGE_ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -6893,9 +6859,7 @@ file_stop_callback (NautilusFile *file,
|
|||
GError *error,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusFilesView *view;
|
||||
|
||||
view = NAUTILUS_FILES_VIEW (callback_data);
|
||||
g_autoptr (NautilusFilesView) self = NAUTILUS_FILES_VIEW (callback_data);
|
||||
|
||||
if (error != NULL &&
|
||||
(error->domain != G_IO_ERROR ||
|
||||
|
@ -6904,7 +6868,7 @@ file_stop_callback (NautilusFile *file,
|
|||
{
|
||||
show_dialog (_("Unable to stop drive"),
|
||||
error->message,
|
||||
GTK_WINDOW (nautilus_files_view_get_window (view)),
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
|
||||
GTK_MESSAGE_ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -6914,13 +6878,12 @@ action_mount_volume (GSimpleAction *action,
|
|||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusFilesView *view = NAUTILUS_FILES_VIEW (user_data);
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
|
||||
NautilusFile *file;
|
||||
GList *selection, *l;
|
||||
NautilusFilesView *view;
|
||||
GMountOperation *mount_op;
|
||||
|
||||
view = NAUTILUS_FILES_VIEW (user_data);
|
||||
|
||||
selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
|
||||
for (l = selection; l != NULL; l = l->next)
|
||||
{
|
||||
|
@ -6928,11 +6891,14 @@ action_mount_volume (GSimpleAction *action,
|
|||
|
||||
if (nautilus_file_can_mount (file))
|
||||
{
|
||||
NautilusViewItem *item = nautilus_view_model_get_item_for_file (priv->model, file);
|
||||
|
||||
nautilus_view_item_set_loading (item, TRUE);
|
||||
mount_op = gtk_mount_operation_new (nautilus_files_view_get_containing_window (view));
|
||||
g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
|
||||
nautilus_file_mount (file, mount_op, NULL,
|
||||
file_mount_callback,
|
||||
view);
|
||||
g_object_ref (view));
|
||||
g_object_unref (mount_op);
|
||||
}
|
||||
}
|
||||
|
@ -6944,12 +6910,11 @@ action_unmount_volume (GSimpleAction *action,
|
|||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusFilesView *view = NAUTILUS_FILES_VIEW (user_data);
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
|
||||
NautilusFile *file;
|
||||
g_autolist (NautilusFile) selection = NULL;
|
||||
GList *l;
|
||||
NautilusFilesView *view;
|
||||
|
||||
view = NAUTILUS_FILES_VIEW (user_data);
|
||||
|
||||
selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
|
||||
|
||||
|
@ -6959,6 +6924,9 @@ action_unmount_volume (GSimpleAction *action,
|
|||
if (nautilus_file_can_unmount (file))
|
||||
{
|
||||
GMountOperation *mount_op;
|
||||
NautilusViewItem *item = nautilus_view_model_get_item_for_file (priv->model, file);
|
||||
|
||||
nautilus_view_item_set_loading (item, TRUE);
|
||||
mount_op = gtk_mount_operation_new (nautilus_files_view_get_containing_window (view));
|
||||
nautilus_file_unmount (file, mount_op, NULL,
|
||||
file_unmount_callback, g_object_ref (view));
|
||||
|
@ -7016,7 +6984,7 @@ file_start_callback (NautilusFile *file,
|
|||
g_autofree char *text = g_strdup_printf (_("Unable to start “%s”"), name);
|
||||
show_dialog (text,
|
||||
error->message,
|
||||
GTK_WINDOW (nautilus_files_view_get_window (view)),
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (view))),
|
||||
GTK_MESSAGE_ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -7071,7 +7039,7 @@ action_stop_volume (GSimpleAction *action,
|
|||
GMountOperation *mount_op;
|
||||
mount_op = gtk_mount_operation_new (nautilus_files_view_get_containing_window (view));
|
||||
nautilus_file_stop (file, mount_op, NULL,
|
||||
file_stop_callback, view);
|
||||
file_stop_callback, g_object_ref (view));
|
||||
g_object_unref (mount_op);
|
||||
}
|
||||
}
|
||||
|
@ -7101,6 +7069,37 @@ action_detect_media (GSimpleAction *action,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
action_copy_network_address (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusFilesView *self = NAUTILUS_FILES_VIEW (user_data);
|
||||
g_autolist (NautilusFile) selection = nautilus_view_get_selection (NAUTILUS_VIEW (self));
|
||||
|
||||
g_return_if_fail (selection != NULL && selection->next == NULL);
|
||||
|
||||
g_autofree char *address = nautilus_file_get_activation_uri (NAUTILUS_FILE (selection->data));
|
||||
|
||||
gdk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (self)), address);
|
||||
}
|
||||
|
||||
static void
|
||||
action_remove_recent_server (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusFilesView *self = NAUTILUS_FILES_VIEW (user_data);
|
||||
g_autolist (NautilusFile) selection = nautilus_view_get_selection (NAUTILUS_VIEW (self));
|
||||
|
||||
for (GList *l = selection; l != NULL; l = l->next)
|
||||
{
|
||||
g_autofree char *address = nautilus_file_get_activation_uri (NAUTILUS_FILE (selection->data));
|
||||
|
||||
nautilus_remove_recent_server (address);
|
||||
}
|
||||
}
|
||||
|
||||
const GActionEntry view_entries[] =
|
||||
{
|
||||
/* Toolbar menu */
|
||||
|
@ -7173,6 +7172,9 @@ const GActionEntry view_entries[] =
|
|||
{ .name = "start-volume", .activate = action_start_volume },
|
||||
{ .name = "stop-volume", .activate = action_stop_volume },
|
||||
{ .name = "detect-media", .activate = action_detect_media },
|
||||
/* Only in Network View */
|
||||
{ .name = "copy-network-address", .activate = action_copy_network_address },
|
||||
{ .name = "remove-recent-server", .activate = action_remove_recent_server },
|
||||
/* Only accesible by shorcuts */
|
||||
{ .name = "select-pattern", .activate = action_select_pattern },
|
||||
{ .name = "invert-selection", .activate = action_invert_selection },
|
||||
|
@ -7516,10 +7518,11 @@ nautilus_handles_all_files_to_extract (GList *files)
|
|||
static void
|
||||
real_update_actions_state (NautilusFilesView *view)
|
||||
{
|
||||
NautilusFilesViewPrivate *priv;
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
|
||||
g_autolist (NautilusFile) selection = NULL;
|
||||
GList *l;
|
||||
gint selection_count;
|
||||
gboolean is_network_view = NAUTILUS_IS_NETWORK_VIEW (priv->list_base);
|
||||
gboolean selection_contains_home_dir;
|
||||
gboolean selection_contains_recent;
|
||||
gboolean selection_contains_search;
|
||||
|
@ -7555,8 +7558,6 @@ real_update_actions_state (NautilusFilesView *view)
|
|||
gboolean show_unstar;
|
||||
g_autoptr (GAppInfo) app_info_mailto = NULL;
|
||||
|
||||
priv = nautilus_files_view_get_instance_private (view);
|
||||
|
||||
view_action_group = priv->view_action_group;
|
||||
|
||||
selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
|
||||
|
@ -7765,7 +7766,8 @@ real_update_actions_state (NautilusFilesView *view)
|
|||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
!selection_contains_recent &&
|
||||
!selection_contains_search &&
|
||||
!selection_contains_starred);
|
||||
!selection_contains_starred &&
|
||||
!is_network_view);
|
||||
|
||||
/* Drive menu */
|
||||
show_mount = (selection != NULL);
|
||||
|
@ -7837,7 +7839,8 @@ real_update_actions_state (NautilusFilesView *view)
|
|||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
!selection_contains_recent &&
|
||||
!selection_contains_search &&
|
||||
!selection_contains_starred);
|
||||
!selection_contains_starred &&
|
||||
!is_network_view);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
|
||||
"new-folder");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_create_files);
|
||||
|
@ -7879,16 +7882,20 @@ real_update_actions_state (NautilusFilesView *view)
|
|||
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
|
||||
"properties");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
selection_count != 0 ||
|
||||
(!selection_contains_recent &&
|
||||
!selection_contains_search &&
|
||||
!selection_contains_starred));
|
||||
(is_network_view ?
|
||||
(selection_count == 1 &&
|
||||
nautilus_file_can_unmount (selection->data)) :
|
||||
(selection_count != 0 ||
|
||||
(!selection_contains_recent &&
|
||||
!selection_contains_search &&
|
||||
!selection_contains_starred))));
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
|
||||
"current-directory-properties");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
!selection_contains_recent &&
|
||||
!selection_contains_search &&
|
||||
!selection_contains_starred);
|
||||
!selection_contains_starred &&
|
||||
!is_network_view);
|
||||
|
||||
/* Actions that are related to the clipboard need request, request the data
|
||||
* and update them once we have the data */
|
||||
|
@ -7950,6 +7957,32 @@ real_update_actions_state (NautilusFilesView *view)
|
|||
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
|
||||
"unstar");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), show_unstar && selection_contains_starred);
|
||||
|
||||
/* Network view actions */
|
||||
gboolean can_remove_recent_server = is_network_view;
|
||||
|
||||
for (l = selection; l != NULL && can_remove_recent_server; l = l->next)
|
||||
{
|
||||
NautilusFile *file = NAUTILUS_FILE (l->data);
|
||||
g_autoptr (GFile) location = nautilus_file_get_location (NAUTILUS_FILE (l->data));
|
||||
|
||||
/* Only recent servers have x-network-view: scheme */
|
||||
if (!g_file_has_uri_scheme (location, SCHEME_NETWORK_VIEW) || nautilus_file_can_unmount (file))
|
||||
{
|
||||
can_remove_recent_server = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
|
||||
"copy-network-address");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
(is_network_view &&
|
||||
selection_count == 1 &&
|
||||
nautilus_file_has_activation_uri (selection->data)));
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
|
||||
"remove-recent-server");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_remove_recent_server);
|
||||
}
|
||||
|
||||
/* Convenience function to be called when updating menus,
|
||||
|
@ -8247,6 +8280,20 @@ update_selection_menu (NautilusFilesView *view,
|
|||
nautilus_g_menu_replace_string_in_item (G_MENU (object), i,
|
||||
"hidden-when",
|
||||
(!show_scripts) ? "action-missing" : NULL);
|
||||
|
||||
if (NAUTILUS_IS_NETWORK_VIEW (priv->list_base))
|
||||
{
|
||||
object = gtk_builder_get_object (builder, "move-copy-section");
|
||||
g_menu_remove_all (G_MENU (object));
|
||||
|
||||
object = gtk_builder_get_object (builder, "file-actions-section");
|
||||
g_menu_remove_all (G_MENU (object));
|
||||
}
|
||||
else
|
||||
{
|
||||
object = gtk_builder_get_object (builder, "network-view-section");
|
||||
g_menu_remove_all (G_MENU (object));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -8370,12 +8417,9 @@ nautilus_files_view_reset_view_menu (NautilusFilesView *view)
|
|||
void
|
||||
nautilus_files_view_update_toolbar_menus (NautilusFilesView *view)
|
||||
{
|
||||
NautilusWindow *window;
|
||||
NautilusFilesViewPrivate *priv;
|
||||
|
||||
g_assert (NAUTILUS_IS_FILES_VIEW (view));
|
||||
|
||||
priv = nautilus_files_view_get_instance_private (view);
|
||||
NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
|
||||
|
||||
/* Don't update after destroy (#349551),
|
||||
* or if we are not active.
|
||||
|
@ -8385,8 +8429,6 @@ nautilus_files_view_update_toolbar_menus (NautilusFilesView *view)
|
|||
{
|
||||
return;
|
||||
}
|
||||
window = nautilus_files_view_get_window (view);
|
||||
nautilus_window_reset_menus (window);
|
||||
|
||||
nautilus_files_view_update_actions_state (view);
|
||||
nautilus_files_view_reset_view_menu (view);
|
||||
|
@ -8594,6 +8636,7 @@ nautilus_files_view_notify_selection_changed (NautilusFilesView *view)
|
|||
view);
|
||||
}
|
||||
|
||||
nautilus_files_view_update_actions_state (view);
|
||||
schedule_update_context_menus (view);
|
||||
}
|
||||
|
||||
|
@ -8715,15 +8758,17 @@ load_directory (NautilusFilesView *view,
|
|||
priv = nautilus_files_view_get_instance_private (view);
|
||||
|
||||
nautilus_files_view_stop_loading (view);
|
||||
if (NAUTILUS_IS_SEARCH_DIRECTORY (directory) || NAUTILUS_IS_SEARCH_DIRECTORY (priv->directory))
|
||||
|
||||
/* To make search feel fast and smooth as if it were filtering the current
|
||||
* view, avoid blanking the view temporarily in the following cases:
|
||||
* 1- Going from a search to a search
|
||||
* 2- Going from a location to local search
|
||||
*/
|
||||
if (NAUTILUS_IS_SEARCH_DIRECTORY (directory) &&
|
||||
(NAUTILUS_IS_SEARCH_DIRECTORY (priv->directory) ||
|
||||
(priv->search_query != NULL && !nautilus_query_is_global (priv->search_query))))
|
||||
{
|
||||
if (priv->search_query != NULL &&
|
||||
!nautilus_query_is_global (priv->search_query))
|
||||
{
|
||||
/* To make search feel fast and smooth as if it were filtering the
|
||||
* current view, avoid blanking the view temporarily. */
|
||||
search_transition_schedule_delayed_signals (view);
|
||||
}
|
||||
search_transition_schedule_delayed_signals (view);
|
||||
}
|
||||
|
||||
emit_clear (view);
|
||||
|
@ -9261,7 +9306,6 @@ on_parent_changed (GObject *object,
|
|||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
NautilusWindow *window;
|
||||
NautilusFilesView *view;
|
||||
NautilusFilesViewPrivate *priv;
|
||||
GtkWidget *parent;
|
||||
|
@ -9271,14 +9315,13 @@ on_parent_changed (GObject *object,
|
|||
priv = nautilus_files_view_get_instance_private (view);
|
||||
|
||||
parent = gtk_widget_get_parent (widget);
|
||||
window = nautilus_files_view_get_window (view);
|
||||
|
||||
if (parent != NULL)
|
||||
{
|
||||
if (priv->slot == nautilus_window_get_active_slot (window))
|
||||
if (nautilus_window_slot_get_active (priv->slot))
|
||||
{
|
||||
priv->active = TRUE;
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (nautilus_files_view_get_window (view)),
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (gtk_widget_get_root (widget)),
|
||||
"view",
|
||||
G_ACTION_GROUP (priv->view_action_group));
|
||||
}
|
||||
|
@ -9292,7 +9335,7 @@ on_parent_changed (GObject *object,
|
|||
*/
|
||||
if (priv->active)
|
||||
{
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (nautilus_files_view_get_window (view)),
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (priv->slot))),
|
||||
"view",
|
||||
NULL);
|
||||
}
|
||||
|
@ -9623,28 +9666,6 @@ nautilus_files_view_init (NautilusFilesView *view)
|
|||
GtkShortcut *shortcut;
|
||||
gchar *templates_uri;
|
||||
GdkClipboard *clipboard;
|
||||
GApplication *app;
|
||||
const gchar *zoom_in_accels[] =
|
||||
{
|
||||
"<control>equal",
|
||||
"<control>plus",
|
||||
"<control>KP_Add",
|
||||
"ZoomIn",
|
||||
NULL
|
||||
};
|
||||
const gchar *zoom_out_accels[] =
|
||||
{
|
||||
"<control>minus",
|
||||
"<control>KP_Subtract",
|
||||
"ZoomOut",
|
||||
NULL
|
||||
};
|
||||
const gchar *zoom_standard_accels[] =
|
||||
{
|
||||
"<control>0",
|
||||
"<control>KP_0",
|
||||
NULL
|
||||
};
|
||||
|
||||
priv = nautilus_files_view_get_instance_private (view);
|
||||
|
||||
|
@ -9753,30 +9774,39 @@ nautilus_files_view_init (NautilusFilesView *view)
|
|||
g_signal_connect_object (priv->view_action_group, "action-state-changed::sort",
|
||||
G_CALLBACK (on_sort_action_state_changed), view, 0);
|
||||
|
||||
app = g_application_get_default ();
|
||||
|
||||
/* NOTE: Please do not add any key here that could interfere with
|
||||
* the rest of the app's use of those keys. Some example of keys set here
|
||||
* that broke keynav include Enter/Return, Menu, F2 and Delete keys.
|
||||
* The accelerators below are set on the whole app level for the sole purpose
|
||||
* The accelerators below are set on the window level for the sole purpose
|
||||
* of making it more convenient when you don't have the focus exactly on the
|
||||
* files view, but some keys are used in a contextual way, and those should
|
||||
* should be added in nautilus_files_view_class_init() above instead of a
|
||||
* global accelerator, unless it really makes sense to have them globally
|
||||
* managed accelerator, unless it really makes sense to have them managed
|
||||
* (e.g. Zoom in/out shortcuts).
|
||||
*/
|
||||
nautilus_application_set_accelerators (app, "view.zoom-in", zoom_in_accels);
|
||||
nautilus_application_set_accelerators (app, "view.zoom-out", zoom_out_accels);
|
||||
nautilus_application_set_accelerator (app, "view.show-hidden-files", "<control>h");
|
||||
#define ADD_SHORTCUT_FOR_ACTION(controller, action, trigger) \
|
||||
(gtk_shortcut_controller_add_shortcut ((controller), \
|
||||
gtk_shortcut_new (gtk_shortcut_trigger_parse_string ((trigger)), \
|
||||
gtk_named_action_new ((action)))))
|
||||
|
||||
priv->shortcuts = GTK_SHORTCUT_CONTROLLER (gtk_shortcut_controller_new ());
|
||||
|
||||
gtk_shortcut_controller_set_scope (priv->shortcuts, GTK_SHORTCUT_SCOPE_MANAGED);
|
||||
gtk_widget_add_controller (GTK_WIDGET (view), GTK_EVENT_CONTROLLER (priv->shortcuts));
|
||||
|
||||
ADD_SHORTCUT_FOR_ACTION (priv->shortcuts, "view.zoom-in", "<control>equal|<control>plus|<control>KP_Add|ZoomIn");
|
||||
ADD_SHORTCUT_FOR_ACTION (priv->shortcuts, "view.zoom-out", "<control>minus|<control>KP_Subtract|ZoomOut");
|
||||
ADD_SHORTCUT_FOR_ACTION (priv->shortcuts, "view.show-hidden-files", "<control>h");
|
||||
/* Despite putting copy/cut at the widget scope instead of the global one,
|
||||
* we're putting paste globally so that it's easy to switch between apps
|
||||
* we're putting paste "managed" so that it's easy to switch between apps
|
||||
* with e.g. Alt+Tab and paste directly the copied file without having to
|
||||
* make sure the focus is on the files view.
|
||||
*/
|
||||
nautilus_application_set_accelerator (app, "view.paste_accel", "<control>v");
|
||||
nautilus_application_set_accelerator (app, "view.new-folder", "<control><shift>n");
|
||||
nautilus_application_set_accelerator (app, "view.select-pattern", "<control>s");
|
||||
nautilus_application_set_accelerators (app, "view.zoom-standard", zoom_standard_accels);
|
||||
ADD_SHORTCUT_FOR_ACTION (priv->shortcuts, "view.paste_accel", "<control>v");
|
||||
ADD_SHORTCUT_FOR_ACTION (priv->shortcuts, "view.new-folder", "<control><shift>n");
|
||||
ADD_SHORTCUT_FOR_ACTION (priv->shortcuts, "view.select-pattern", "<control>s");
|
||||
ADD_SHORTCUT_FOR_ACTION (priv->shortcuts, "view.zoom-standard", "<control>0|<control>KP_0");
|
||||
#undef ADD_SHORTCUT_FOR_ACTION
|
||||
|
||||
/* This one should have been a keybinding, because it should trigger only
|
||||
* when the view is focused. Unfortunately, children can override bindings,
|
||||
|
@ -9821,6 +9851,12 @@ create_inner_view (NautilusFilesView *self,
|
|||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_VIEW_NETWORK_ID:
|
||||
{
|
||||
priv->list_base = NAUTILUS_LIST_BASE (nautilus_network_view_new ());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
g_critical ("Unknown view type ID: %d. Falling back to list.", id);
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "nautilus-directory.h"
|
||||
#include "nautilus-file.h"
|
||||
|
||||
#include "nautilus-window.h"
|
||||
#include "nautilus-view.h"
|
||||
#include "nautilus-window-slot.h"
|
||||
|
||||
|
@ -149,7 +148,7 @@ void nautilus_file_view_save_image_from_texture (NautilusFilesVi
|
|||
void nautilus_files_view_new_file_with_initial_contents (NautilusFilesView *view,
|
||||
const char *parent_uri,
|
||||
const char *filename,
|
||||
const char *initial_contents,
|
||||
const void *initial_contents,
|
||||
gsize length);
|
||||
/* selection handling */
|
||||
void nautilus_files_view_activate_selection (NautilusFilesView *view,
|
||||
|
|
|
@ -109,15 +109,10 @@ navigation_button_press_cb (GtkGestureClick *gesture,
|
|||
gdouble y,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusHistoryControls *self;
|
||||
NautilusWindow *window;
|
||||
GtkWidget *widget;
|
||||
guint button;
|
||||
NautilusHistoryControls *self = NAUTILUS_HISTORY_CONTROLS (user_data);
|
||||
|
||||
self = NAUTILUS_HISTORY_CONTROLS (user_data);
|
||||
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
window = NAUTILUS_WINDOW (gtk_widget_get_root (GTK_WIDGET (self)));
|
||||
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
guint button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
if (button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
|
@ -128,11 +123,19 @@ navigation_button_press_cb (GtkGestureClick *gesture,
|
|||
else if (button == GDK_BUTTON_MIDDLE)
|
||||
{
|
||||
NautilusNavigationDirection direction;
|
||||
GtkRoot *window = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
|
||||
if (!NAUTILUS_IS_WINDOW (window))
|
||||
{
|
||||
/* Only NautilusWindow offers special behavior for this event. */
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
direction = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
|
||||
"nav-direction"));
|
||||
|
||||
nautilus_window_back_or_forward_in_new_tab (window, direction);
|
||||
nautilus_window_back_or_forward_in_new_tab (NAUTILUS_WINDOW (window), direction);
|
||||
}
|
||||
else if (button == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
|
|
205
src/nautilus-internal-place-file.c
Normal file
205
src/nautilus-internal-place-file.c
Normal file
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (C) 2024 GNOME Foundation Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Original Author: António Fernandes <antoniof@gnome.org>
|
||||
*/
|
||||
|
||||
#include "nautilus-internal-place-file.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "nautilus-file-private.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-network-directory.h"
|
||||
#include "nautilus-starred-directory.h"
|
||||
|
||||
struct _NautilusInternalPlaceFile
|
||||
{
|
||||
NautilusFile parent_instance;
|
||||
|
||||
GList *callbacks;
|
||||
GCancellable *network_mount_cancellable;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NautilusInternalPlaceFile, nautilus_internal_place_file, NAUTILUS_TYPE_FILE);
|
||||
|
||||
static void
|
||||
real_monitor_add (NautilusFile *file,
|
||||
gconstpointer client,
|
||||
NautilusFileAttributes attributes)
|
||||
{
|
||||
/* Internal place attributes are static, so there is nothing to monitor. */
|
||||
}
|
||||
|
||||
static void
|
||||
real_monitor_remove (NautilusFile *file,
|
||||
gconstpointer client)
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NautilusFileCallback callback;
|
||||
gpointer callback_data;
|
||||
} InternalPlaceFileCallback;
|
||||
|
||||
static void
|
||||
network_mount_callback (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!g_file_mount_enclosing_volume_finish (G_FILE (source_object), result, &error) &&
|
||||
!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED))
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
g_warning ("Could not mount '%s': %s", SCHEME_NETWORK ":///", error->message);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NautilusInternalPlaceFile *self = NAUTILUS_INTERNAL_PLACE_FILE (data);
|
||||
|
||||
/* Clear cancellable and steal callbacks list because call_when_ready() may
|
||||
* be called again inside the `for` loop. */
|
||||
g_clear_object (&self->network_mount_cancellable);
|
||||
|
||||
GList *callbacks = g_steal_pointer (&self->callbacks);
|
||||
for (GList *l = callbacks; l != NULL; l = l->next)
|
||||
{
|
||||
InternalPlaceFileCallback *callback = l->data;
|
||||
|
||||
(*callback->callback)(NAUTILUS_FILE (self), callback->callback_data);
|
||||
}
|
||||
g_list_free_full (callbacks, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
real_call_when_ready (NautilusFile *file,
|
||||
NautilusFileAttributes file_attributes,
|
||||
NautilusFileCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusInternalPlaceFile *self = NAUTILUS_INTERNAL_PLACE_FILE (file);
|
||||
|
||||
if (NAUTILUS_IS_NETWORK_DIRECTORY (file->details->directory))
|
||||
{
|
||||
/* WORKAROUND:
|
||||
* We must ensure network:/// is mounted before calling it "ready",
|
||||
* otherwise GDaemonFile makes sync D-Bus calls to mount network://
|
||||
* when the view tries do add a monitor, blocking the main thread and
|
||||
* freezing the UI.
|
||||
* See: https://gitlab.gnome.org/GNOME/gvfs/-/issues/455
|
||||
*/
|
||||
|
||||
if (callback != NULL)
|
||||
{
|
||||
InternalPlaceFileCallback data = {callback, callback_data};
|
||||
self->callbacks = g_list_prepend (self->callbacks,
|
||||
g_memdup2 (&data, sizeof (data)));
|
||||
}
|
||||
|
||||
/* If there is a cancellable, we are already mounting */
|
||||
if (self->network_mount_cancellable == NULL)
|
||||
{
|
||||
g_autoptr (GFile) network_backend = g_file_new_for_uri (SCHEME_NETWORK ":///");
|
||||
|
||||
self->network_mount_cancellable = g_cancellable_new ();
|
||||
g_file_mount_enclosing_volume (network_backend,
|
||||
G_MOUNT_MOUNT_NONE,
|
||||
NULL,
|
||||
self->network_mount_cancellable,
|
||||
network_mount_callback, self);
|
||||
}
|
||||
}
|
||||
else if (callback != NULL)
|
||||
{
|
||||
/* Internal place attributes are static, so its always ready. */
|
||||
(*callback)(file, callback_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
real_cancel_call_when_ready (NautilusFile *file,
|
||||
NautilusFileCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusInternalPlaceFile *self = NAUTILUS_INTERNAL_PLACE_FILE (file);
|
||||
|
||||
g_clear_list (&self->callbacks, g_free);
|
||||
g_cancellable_cancel (self->network_mount_cancellable);
|
||||
g_clear_object (&self->network_mount_cancellable);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_check_if_ready (NautilusFile *file,
|
||||
NautilusFileAttributes attributes)
|
||||
{
|
||||
/* Internal place attributes are static, so its always ready. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_internal_place_file_init (NautilusInternalPlaceFile *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_internal_place_file_constructed (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (nautilus_internal_place_file_parent_class)->constructed (object);
|
||||
|
||||
NautilusInternalPlaceFile *self = NAUTILUS_INTERNAL_PLACE_FILE (object);
|
||||
NautilusFile *file = NAUTILUS_FILE (self);
|
||||
|
||||
file->details->mime_type = g_ref_string_new_intern ("inode/directory");
|
||||
file->details->size = 0;
|
||||
|
||||
if (NAUTILUS_IS_NETWORK_DIRECTORY (file->details->directory))
|
||||
{
|
||||
nautilus_file_set_display_name (file, _("Network"), NULL, TRUE);
|
||||
}
|
||||
else if (NAUTILUS_IS_STARRED_DIRECTORY (file->details->directory))
|
||||
{
|
||||
nautilus_file_set_display_name (file, _("Starred"), NULL, TRUE);
|
||||
}
|
||||
|
||||
file->details->got_file_info = TRUE;
|
||||
file->details->file_info_is_up_to_date = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_internal_place_file_dispose (GObject *object)
|
||||
{
|
||||
NautilusInternalPlaceFile *self = NAUTILUS_INTERNAL_PLACE_FILE (object);
|
||||
|
||||
g_clear_list (&self->callbacks, g_free);
|
||||
g_cancellable_cancel (self->network_mount_cancellable);
|
||||
g_clear_object (&self->network_mount_cancellable);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_internal_place_file_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_internal_place_file_class_init (NautilusInternalPlaceFileClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
NautilusFileClass *file_class = NAUTILUS_FILE_CLASS (klass);
|
||||
|
||||
/* We need to know the parent directory, which is a construction property.*/
|
||||
object_class->constructed = nautilus_internal_place_file_constructed;
|
||||
object_class->dispose = nautilus_internal_place_file_dispose;
|
||||
|
||||
file_class->default_file_type = G_FILE_TYPE_DIRECTORY;
|
||||
|
||||
file_class->monitor_add = real_monitor_add;
|
||||
file_class->monitor_remove = real_monitor_remove;
|
||||
file_class->call_when_ready = real_call_when_ready;
|
||||
file_class->cancel_call_when_ready = real_cancel_call_when_ready;
|
||||
file_class->check_if_ready = real_check_if_ready;
|
||||
}
|
16
src/nautilus-internal-place-file.h
Normal file
16
src/nautilus-internal-place-file.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (C) 2024 GNOME Foundation Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Original Author: António Fernandes <antoniof@gnome.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nautilus-file.h"
|
||||
|
||||
#define NAUTILUS_TYPE_INTERNAL_PLACE_FILE nautilus_internal_place_file_get_type ()
|
||||
G_DECLARE_FINAL_TYPE (NautilusInternalPlaceFile, nautilus_internal_place_file,
|
||||
NAUTILUS, INTERNAL_PLACE_FILE,
|
||||
NautilusFile)
|
|
@ -1263,8 +1263,8 @@ nautilus_list_base_class_init (NautilusListBaseClass *klass)
|
|||
G_TYPE_VALUE, GDK_TYPE_DRAG_ACTION, G_TYPE_FILE);
|
||||
signals[POPUP_BACKGROUND_CONTEXT_MENU] = g_signal_new ("popup-background-context-menu",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NautilusListBaseClass, popup_background_context_menu),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 2,
|
||||
|
|
|
@ -38,6 +38,9 @@ struct _NautilusListBaseClass
|
|||
int new_zoom_level);
|
||||
|
||||
/* Subclasses may override base implementation. */
|
||||
void (*popup_background_context_menu) (NautilusListBase *self,
|
||||
double x,
|
||||
double y);
|
||||
NautilusViewItem *(*get_backing_item) (NautilusListBase *self);
|
||||
void (*preview_selection_event) (NautilusListBase *self,
|
||||
GtkDirectionType direction);
|
||||
|
|
|
@ -1056,7 +1056,7 @@ setup_view_columns (NautilusListView *self)
|
|||
static void
|
||||
nautilus_list_view_reload (NautilusListView *self)
|
||||
{
|
||||
gtk_widget_activate_action (GTK_WIDGET (self), "win.reload", NULL);
|
||||
gtk_widget_activate_action (GTK_WIDGET (self), "slot.reload", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "nautilus-application.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-window.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
@ -677,7 +676,7 @@ nautilus_location_entry_class_init (NautilusLocationEntryClass *class)
|
|||
G_SIGNAL_RUN_LAST, 0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_generic,
|
||||
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
||||
G_TYPE_NONE, 1, G_TYPE_FILE);
|
||||
|
||||
shortcut = gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_Escape, 0),
|
||||
gtk_signal_action_new ("cancel"));
|
||||
|
|
394
src/nautilus-network-address-bar.c
Normal file
394
src/nautilus-network-address-bar.c
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
* Copyright (C) 2022 António Fernandes <antoniof@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "nautilus-network-address-bar.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
#include "nautilus-recent-servers.h"
|
||||
|
||||
struct _NautilusNetworkAddressBar
|
||||
{
|
||||
GtkBox parent_instance;
|
||||
|
||||
GtkWidget *address_entry;
|
||||
GtkWidget *connect_button;
|
||||
GtkWidget *available_protocols_grid;
|
||||
|
||||
gboolean should_open_location;
|
||||
gboolean should_pulse_entry;
|
||||
gboolean connecting_to_server;
|
||||
guint entry_pulse_timeout_id;
|
||||
|
||||
GCancellable *cancellable;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NautilusNetworkAddressBar, nautilus_network_address_bar, GTK_TYPE_BOX)
|
||||
|
||||
const char *unsupported_protocols[] =
|
||||
{
|
||||
"afc", "archive", "burn", "computer", "file", "http", "localtest", "obex", "recent", "trash", NULL
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
show_error_message (NautilusNetworkAddressBar *self,
|
||||
const gchar *primary,
|
||||
const gchar *secondary)
|
||||
{
|
||||
GtkRoot *window = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
GtkWidget *dialog = adw_message_dialog_new (GTK_WINDOW (window), primary, secondary);
|
||||
adw_message_dialog_add_response (ADW_MESSAGE_DIALOG (dialog), "close", _("_Close"));
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
server_mount_ready_cb (GObject *source_file,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr (NautilusNetworkAddressBar) self = NAUTILUS_NETWORK_ADDRESS_BAR (user_data);
|
||||
gboolean should_show = TRUE;
|
||||
g_autoptr (GError) error = NULL;
|
||||
GFile *location = G_FILE (source_file);
|
||||
|
||||
g_file_mount_enclosing_volume_finish (location, res, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
should_show = FALSE;
|
||||
|
||||
if (error->code == G_IO_ERROR_ALREADY_MOUNTED)
|
||||
{
|
||||
/*
|
||||
* Already mounted volume is not a critical error
|
||||
* and we can still continue with the operation.
|
||||
*/
|
||||
should_show = TRUE;
|
||||
}
|
||||
else if (error->domain != G_IO_ERROR ||
|
||||
(error->code != G_IO_ERROR_CANCELLED &&
|
||||
error->code != G_IO_ERROR_FAILED_HANDLED))
|
||||
{
|
||||
/* if it wasn't cancelled show a dialog */
|
||||
show_error_message (self, _("Unable to access location"), error->message);
|
||||
}
|
||||
|
||||
/* The operation got cancelled by the user or dispose() and or the error
|
||||
* has been handled already. */
|
||||
}
|
||||
|
||||
self->should_pulse_entry = FALSE;
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->address_entry), 0);
|
||||
|
||||
/* Restore from Cancel to Connect */
|
||||
gtk_button_set_label (GTK_BUTTON (self->connect_button), _("Con_nect"));
|
||||
gtk_widget_set_sensitive (self->address_entry, TRUE);
|
||||
self->connecting_to_server = FALSE;
|
||||
|
||||
if (should_show)
|
||||
{
|
||||
nautilus_add_recent_server (location);
|
||||
|
||||
/*
|
||||
* Only clear the entry if it successfully connects to the server.
|
||||
* Otherwise, the user would lost the typed address even if it fails
|
||||
* to connect.
|
||||
*/
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->address_entry), "");
|
||||
|
||||
if (self->should_open_location)
|
||||
{
|
||||
g_autofree char *uri_to_open = NULL;
|
||||
g_autoptr (GMount) mount = g_file_find_enclosing_mount (location, self->cancellable, NULL);
|
||||
|
||||
/*
|
||||
* If the mount is not found at this point, it is probably user-
|
||||
* invisible, which happens e.g for smb-browse, but the location
|
||||
* should be opened anyway...
|
||||
*/
|
||||
if (mount != NULL)
|
||||
{
|
||||
g_autoptr (GFile) root = g_mount_get_default_location (mount);
|
||||
|
||||
uri_to_open = g_file_get_uri (root);
|
||||
}
|
||||
else
|
||||
{
|
||||
uri_to_open = g_file_get_uri (location);
|
||||
}
|
||||
|
||||
gtk_widget_activate_action (GTK_WIDGET (self),
|
||||
"win.open-location", "s", uri_to_open);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pulse_entry_cb (gpointer user_data)
|
||||
{
|
||||
NautilusNetworkAddressBar *self = NAUTILUS_NETWORK_ADDRESS_BAR (user_data);
|
||||
|
||||
if (self->should_pulse_entry)
|
||||
{
|
||||
gtk_entry_progress_pulse (GTK_ENTRY (self->address_entry));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->address_entry), 0);
|
||||
self->entry_pulse_timeout_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mount_server (NautilusNetworkAddressBar *self,
|
||||
GFile *location)
|
||||
{
|
||||
GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (self)));
|
||||
g_autoptr (GMountOperation) operation = gtk_mount_operation_new (GTK_WINDOW (toplevel));
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
/* User cliked when the operation was ongoing, so wanted to cancel it */
|
||||
if (self->connecting_to_server)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->cancellable = g_cancellable_new ();
|
||||
|
||||
self->should_pulse_entry = TRUE;
|
||||
gtk_entry_set_progress_pulse_step (GTK_ENTRY (self->address_entry), 0.1);
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (self->address_entry), 0.1);
|
||||
/* Allow to cancel the operation */
|
||||
gtk_button_set_label (GTK_BUTTON (self->connect_button), _("Cance_l"));
|
||||
gtk_widget_set_sensitive (self->address_entry, FALSE);
|
||||
self->connecting_to_server = TRUE;
|
||||
|
||||
if (self->entry_pulse_timeout_id == 0)
|
||||
{
|
||||
self->entry_pulse_timeout_id = g_timeout_add (100, (GSourceFunc) pulse_entry_cb, self);
|
||||
}
|
||||
|
||||
g_mount_operation_set_password_save (operation, G_PASSWORD_SAVE_FOR_SESSION);
|
||||
|
||||
/* make sure we keep the view around for as long as we are running */
|
||||
g_file_mount_enclosing_volume (location,
|
||||
0,
|
||||
operation,
|
||||
self->cancellable,
|
||||
server_mount_ready_cb,
|
||||
g_object_ref (self));
|
||||
}
|
||||
|
||||
static void
|
||||
on_connect_button_clicked (NautilusNetworkAddressBar *self)
|
||||
{
|
||||
/* Since the 'Connect' button is updated whenever the typed
|
||||
* address changes, it is sufficient to check if it's sensitive
|
||||
* or not, in order to determine if the given address is valid.
|
||||
*/
|
||||
if (!gtk_widget_get_sensitive (self->connect_button))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const char *uri = gtk_editable_get_text (GTK_EDITABLE (self->address_entry));
|
||||
|
||||
if (uri != NULL && uri[0] != '\0')
|
||||
{
|
||||
g_autoptr (GFile) file = g_file_new_for_commandline_arg (uri);
|
||||
|
||||
self->should_open_location = TRUE;
|
||||
|
||||
mount_server (self, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
show_error_message (self, _("Unable to get remote server location"), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_entry_icon_press (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (icon_pos == GTK_ENTRY_ICON_SECONDARY);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), "");
|
||||
}
|
||||
|
||||
static void
|
||||
on_address_entry_text_changed (NautilusNetworkAddressBar *self)
|
||||
{
|
||||
const char * const *supported_protocols = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
|
||||
const char *address = gtk_editable_get_text (GTK_EDITABLE (self->address_entry));
|
||||
g_autofree char *scheme = g_uri_parse_scheme (address);
|
||||
gboolean is_empty = (address == NULL || *address == '\0');
|
||||
gboolean supported = FALSE;
|
||||
|
||||
if (supported_protocols != NULL && scheme != NULL)
|
||||
{
|
||||
supported = g_strv_contains (supported_protocols, scheme) &&
|
||||
!g_strv_contains (unsupported_protocols, scheme);
|
||||
}
|
||||
|
||||
gtk_entry_set_icon_from_icon_name (GTK_ENTRY (self->address_entry),
|
||||
GTK_ENTRY_ICON_SECONDARY,
|
||||
is_empty ? NULL : "edit-clear-symbolic");
|
||||
|
||||
gtk_widget_set_sensitive (self->connect_button, supported);
|
||||
if (scheme != NULL && !supported)
|
||||
{
|
||||
gtk_widget_add_css_class (self->address_entry, "error");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_remove_css_class (self->address_entry, "error");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_map (GtkWidget *widget)
|
||||
{
|
||||
NautilusNetworkAddressBar *self = NAUTILUS_NETWORK_ADDRESS_BAR (widget);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (self->address_entry), "");
|
||||
|
||||
GTK_WIDGET_CLASS (nautilus_network_address_bar_parent_class)->map (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
attach_protocol_row_to_grid (GtkGrid *grid,
|
||||
const char *protocol_name,
|
||||
const char *protocol_prefix)
|
||||
{
|
||||
GtkWidget *name_label = gtk_label_new (protocol_name);
|
||||
GtkWidget *prefix_label = gtk_label_new (protocol_prefix);
|
||||
|
||||
gtk_widget_set_halign (name_label, GTK_ALIGN_START);
|
||||
gtk_grid_attach_next_to (grid, name_label, NULL, GTK_POS_BOTTOM, 1, 1);
|
||||
|
||||
gtk_widget_set_halign (prefix_label, GTK_ALIGN_START);
|
||||
gtk_grid_attach_next_to (grid, prefix_label, name_label, GTK_POS_RIGHT, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_available_protocols_grid (GtkGrid *grid)
|
||||
{
|
||||
const char * const *supported_protocols = g_vfs_get_supported_uri_schemes (g_vfs_get_default ());
|
||||
gboolean has_any = FALSE;
|
||||
|
||||
if (g_strv_contains (supported_protocols, "afp"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("AppleTalk"), "afp://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "ftp"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("File Transfer Protocol"),
|
||||
/* Translators: do not translate ftp:// and ftps:// */
|
||||
_("ftp:// or ftps://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "nfs"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("Network File System"), "nfs://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "smb"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("Samba"), "smb://");
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "ssh"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("SSH File Transfer Protocol"),
|
||||
/* Translators: do not translate sftp:// and ssh:// */
|
||||
_("sftp:// or ssh://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (g_strv_contains (supported_protocols, "dav"))
|
||||
{
|
||||
attach_protocol_row_to_grid (grid, _("WebDAV"),
|
||||
/* Translators: do not translate dav:// and davs:// */
|
||||
_("dav:// or davs://"));
|
||||
has_any = TRUE;
|
||||
}
|
||||
|
||||
if (!has_any)
|
||||
{
|
||||
gtk_widget_set_visible (GTK_WIDGET (grid), FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_dispose (GObject *object)
|
||||
{
|
||||
NautilusNetworkAddressBar *self = NAUTILUS_NETWORK_ADDRESS_BAR (object);
|
||||
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
g_clear_object (&self->cancellable);
|
||||
g_clear_handle_id (&self->entry_pulse_timeout_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_network_address_bar_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (nautilus_network_address_bar_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_init (NautilusNetworkAddressBar *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
g_signal_connect (self->address_entry, "icon-press", G_CALLBACK (on_entry_icon_press), NULL);
|
||||
|
||||
populate_available_protocols_grid (GTK_GRID (self->available_protocols_grid));
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_address_bar_class_init (NautilusNetworkAddressBarClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = nautilus_network_address_bar_finalize;
|
||||
object_class->dispose = nautilus_network_address_bar_dispose;
|
||||
|
||||
widget_class->map = nautilus_network_address_bar_map;
|
||||
|
||||
/* Bind class to template */
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/nautilus/ui/nautilus-network-address-bar.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkAddressBar, address_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkAddressBar, connect_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkAddressBar, available_protocols_grid);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_address_entry_text_changed);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_connect_button_clicked);
|
||||
}
|
||||
|
||||
NautilusNetworkAddressBar *
|
||||
nautilus_network_address_bar_new (void)
|
||||
{
|
||||
return g_object_new (NAUTILUS_TYPE_NETWORK_ADDRESS_BAR, NULL);
|
||||
}
|
19
src/nautilus-network-address-bar.h
Normal file
19
src/nautilus-network-address-bar.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2022 António Fernandes <antoniof@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_NETWORK_ADDRESS_BAR (nautilus_network_address_bar_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusNetworkAddressBar, nautilus_network_address_bar, NAUTILUS, NETWORK_ADDRESS_BAR, GtkBox)
|
||||
|
||||
NautilusNetworkAddressBar * nautilus_network_address_bar_new (void);
|
||||
|
||||
G_END_DECLS
|
145
src/nautilus-network-cell.c
Normal file
145
src/nautilus-network-cell.c
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The GNOME project contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "nautilus-network-cell.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "nautilus-directory.h"
|
||||
#include "nautilus-file-utilities.h"
|
||||
#include "nautilus-scheme.h"
|
||||
|
||||
struct _NautilusNetworkCell
|
||||
{
|
||||
NautilusViewCell parent_instance;
|
||||
|
||||
GSignalGroup *item_signal_group;
|
||||
|
||||
GtkWidget *icon;
|
||||
GtkWidget *target_uri;
|
||||
GtkWidget *unmount_button;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NautilusNetworkCell, nautilus_network_cell, NAUTILUS_TYPE_VIEW_CELL)
|
||||
|
||||
static void
|
||||
update_labels (NautilusNetworkCell *self)
|
||||
{
|
||||
g_autoptr (NautilusViewItem) item = nautilus_view_cell_get_item (NAUTILUS_VIEW_CELL (self));
|
||||
|
||||
g_return_if_fail (item != NULL);
|
||||
|
||||
NautilusFile *file = nautilus_view_item_get_file (item);
|
||||
g_autofree char *target_uri = nautilus_file_get_activation_uri (file);
|
||||
|
||||
if (g_str_has_prefix (target_uri, SCHEME_COMPUTER ":///"))
|
||||
{
|
||||
/* Online accounts do not currently have a target URI. */
|
||||
g_set_str (&target_uri, _("Online Account"));
|
||||
}
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (self->target_uri), target_uri);
|
||||
}
|
||||
|
||||
static void
|
||||
update_icon (NautilusNetworkCell *self)
|
||||
{
|
||||
g_autoptr (NautilusViewItem) item = nautilus_view_cell_get_item (NAUTILUS_VIEW_CELL (self));
|
||||
|
||||
g_return_if_fail (item != NULL);
|
||||
|
||||
g_autoptr (GIcon) icon = nautilus_file_get_gicon (nautilus_view_item_get_file (item),
|
||||
NAUTILUS_FILE_ICON_FLAGS_NONE);
|
||||
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (self->icon), icon);
|
||||
}
|
||||
|
||||
static void
|
||||
on_file_changed (NautilusNetworkCell *self)
|
||||
{
|
||||
g_autoptr (NautilusViewItem) item = nautilus_view_cell_get_item (NAUTILUS_VIEW_CELL (self));
|
||||
|
||||
g_return_if_fail (item != NULL);
|
||||
|
||||
update_icon (self);
|
||||
update_labels (self);
|
||||
|
||||
NautilusFile *file = nautilus_view_item_get_file (item);
|
||||
|
||||
gtk_widget_set_visible (self->unmount_button, nautilus_file_can_unmount (file));
|
||||
}
|
||||
|
||||
static void
|
||||
on_unmount_clicked (NautilusNetworkCell *self)
|
||||
{
|
||||
/* Select item first, because view.unmount-volume acts on selection. */
|
||||
gtk_widget_activate_action (GTK_WIDGET (self), "listitem.select", "(bb)", FALSE, FALSE);
|
||||
gtk_widget_activate_action (GTK_WIDGET (self), "view.unmount-volume", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_cell_init (NautilusNetworkCell *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
/* Connect automatically to an item. */
|
||||
self->item_signal_group = g_signal_group_new (NAUTILUS_TYPE_VIEW_ITEM);
|
||||
g_signal_group_connect_swapped (self->item_signal_group, "notify::loading",
|
||||
(GCallback) on_file_changed, self);
|
||||
g_signal_group_connect_swapped (self->item_signal_group, "file-changed",
|
||||
(GCallback) on_file_changed, self);
|
||||
g_signal_connect_object (self->item_signal_group, "bind",
|
||||
(GCallback) on_file_changed, self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
g_object_bind_property (self, "item",
|
||||
self->item_signal_group, "target",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_cell_dispose (GObject *object)
|
||||
{
|
||||
NautilusNetworkCell *self = (NautilusNetworkCell *) object;
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), NAUTILUS_TYPE_NETWORK_CELL);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_network_cell_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_cell_finalize (GObject *object)
|
||||
{
|
||||
NautilusNetworkCell *self = (NautilusNetworkCell *) object;
|
||||
|
||||
g_clear_object (&self->item_signal_group);
|
||||
G_OBJECT_CLASS (nautilus_network_cell_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_cell_class_init (NautilusNetworkCellClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = nautilus_network_cell_dispose;
|
||||
object_class->finalize = nautilus_network_cell_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/nautilus/ui/nautilus-network-cell.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkCell, icon);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkCell, target_uri);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusNetworkCell, unmount_button);
|
||||
gtk_widget_class_bind_template_callback (widget_class, on_unmount_clicked);
|
||||
}
|
||||
|
||||
NautilusViewCell *
|
||||
nautilus_network_cell_new (NautilusListBase *view)
|
||||
{
|
||||
return NAUTILUS_VIEW_CELL (g_object_new (NAUTILUS_TYPE_NETWORK_CELL,
|
||||
"view", view,
|
||||
NULL));
|
||||
}
|
19
src/nautilus-network-cell.h
Normal file
19
src/nautilus-network-cell.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 António Fernandes <antoniof@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nautilus-view-cell.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_NETWORK_CELL (nautilus_network_cell_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusNetworkCell, nautilus_network_cell, NAUTILUS, NETWORK_CELL, NautilusViewCell)
|
||||
|
||||
NautilusViewCell * nautilus_network_cell_new (NautilusListBase *view);
|
||||
|
||||
G_END_DECLS
|
627
src/nautilus-network-directory.c
Normal file
627
src/nautilus-network-directory.c
Normal file
|
@ -0,0 +1,627 @@
|
|||
/*
|
||||
* Copyright (C) 2024 António Fernandes <antoniof@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "nautilus-network-directory.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "nautilus-directory-private.h"
|
||||
#include "nautilus-file-private.h"
|
||||
#include "nautilus-file-utilities.h"
|
||||
#include "nautilus-internal-place-file.h"
|
||||
#include "nautilus-recent-servers.h"
|
||||
#include "nautilus-scheme.h"
|
||||
|
||||
|
||||
struct _NautilusNetworkDirectory
|
||||
{
|
||||
NautilusDirectory parent_slot;
|
||||
|
||||
NautilusDirectory *computer_backend_directory;
|
||||
gboolean computer_backend_done_loading;
|
||||
|
||||
NautilusDirectory *network_backend_directory;
|
||||
gboolean network_backend_done_loading;
|
||||
|
||||
NautilusRecentServers *recent_servers;
|
||||
GList *recent_server_files;
|
||||
gboolean recent_servers_done_loading;
|
||||
|
||||
GList /*<owned NetworkCallback>*/ *callback_list;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (NautilusNetworkDirectory, nautilus_network_directory, NAUTILUS_TYPE_DIRECTORY,
|
||||
nautilus_ensure_extension_points ();
|
||||
/* It looks like you’re implementing an extension point.
|
||||
* Did you modify nautilus_ensure_extension_builtins() accordingly?
|
||||
*
|
||||
* • Yes
|
||||
* • Doing it right now
|
||||
*/
|
||||
g_io_extension_point_implement (NAUTILUS_DIRECTORY_PROVIDER_EXTENSION_POINT_NAME,
|
||||
g_define_type_id,
|
||||
NAUTILUS_NETWORK_DIRECTORY_PROVIDER_NAME,
|
||||
0));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NautilusNetworkDirectory *self;
|
||||
|
||||
NautilusDirectoryCallback callback;
|
||||
gpointer callback_data;
|
||||
|
||||
gboolean computer_backend_ready;
|
||||
gboolean network_backend_ready;
|
||||
} NetworkCallback;
|
||||
|
||||
static gboolean
|
||||
mountable_file_is_remote (NautilusFile *file)
|
||||
{
|
||||
g_autoptr (GIcon) icon = nautilus_file_get_gicon (file, NAUTILUS_FILE_ICON_FLAGS_NONE);
|
||||
|
||||
/* HACK: It would be nice to have a "mountable::remote" attribute or
|
||||
* something like that. Until then, rely on icon name to guess. */
|
||||
if (G_IS_THEMED_ICON (icon))
|
||||
{
|
||||
const gchar * const *names = g_themed_icon_get_names (G_THEMED_ICON (icon));
|
||||
|
||||
for (gsize i = 0; names[i] != NULL; i++)
|
||||
{
|
||||
if (strstr (names[i], "network") || strstr (names[i], "remote"))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GList *
|
||||
get_remote_mountables (GList *mountable_files)
|
||||
{
|
||||
GList *remotes = NULL;
|
||||
|
||||
for (GList *l = mountable_files; l != NULL; l = l->next)
|
||||
{
|
||||
NautilusFile *file = NAUTILUS_FILE (l->data);
|
||||
|
||||
if (mountable_file_is_remote (file))
|
||||
{
|
||||
remotes = g_list_prepend (remotes, g_object_ref (file));
|
||||
}
|
||||
}
|
||||
|
||||
return remotes;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_are_all_files_seen (NautilusDirectory *directory)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
|
||||
return (nautilus_directory_are_all_files_seen (self->computer_backend_directory) &&
|
||||
nautilus_directory_are_all_files_seen (self->network_backend_directory) &&
|
||||
self->recent_servers_done_loading);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_contains_file (NautilusDirectory *directory,
|
||||
NautilusFile *file)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
|
||||
if (nautilus_file_get_directory (file) == directory)
|
||||
{
|
||||
/* Recent server files are directly owned by NautilusNetworkDirectory. */
|
||||
return TRUE;
|
||||
}
|
||||
if (nautilus_directory_contains_file (self->network_backend_directory, file))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (nautilus_directory_contains_file (self->computer_backend_directory, file))
|
||||
{
|
||||
return mountable_file_is_remote (file);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_backend_directory_done_loading (NautilusDirectory *backend_directory,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusNetworkDirectory *self = callback_data;
|
||||
|
||||
if (backend_directory == self->computer_backend_directory)
|
||||
{
|
||||
self->computer_backend_done_loading = TRUE;
|
||||
}
|
||||
else if (backend_directory == self->network_backend_directory)
|
||||
{
|
||||
self->network_backend_done_loading = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Called from on_recent_servers_loading_changed () */
|
||||
g_assert (backend_directory == (NautilusDirectory *) self &&
|
||||
self->recent_servers_done_loading);
|
||||
}
|
||||
|
||||
if (self->computer_backend_done_loading &&
|
||||
self->network_backend_done_loading &&
|
||||
self->recent_servers_done_loading)
|
||||
{
|
||||
nautilus_directory_emit_done_loading (NAUTILUS_DIRECTORY (self));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
real_force_reload (NautilusDirectory *directory)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
|
||||
self->computer_backend_done_loading = FALSE;
|
||||
nautilus_directory_force_reload (self->computer_backend_directory);
|
||||
|
||||
self->network_backend_done_loading = FALSE;
|
||||
nautilus_directory_force_reload (self->network_backend_directory);
|
||||
|
||||
self->recent_servers_done_loading = FALSE;
|
||||
nautilus_recent_servers_force_reload (self->recent_servers);
|
||||
}
|
||||
|
||||
static void
|
||||
on_backend_directory_ready (NautilusDirectory *backend_directory,
|
||||
GList *unused_parameter,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NetworkCallback *network_callback = callback_data;
|
||||
NautilusNetworkDirectory *self = network_callback->self;
|
||||
|
||||
if (backend_directory == self->computer_backend_directory)
|
||||
{
|
||||
network_callback->computer_backend_ready = TRUE;
|
||||
}
|
||||
else if (backend_directory == self->network_backend_directory)
|
||||
{
|
||||
network_callback->network_backend_ready = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (backend_directory == (NautilusDirectory *) self &&
|
||||
network_callback->self->recent_servers_done_loading);
|
||||
}
|
||||
|
||||
if (network_callback->computer_backend_ready &&
|
||||
network_callback->network_backend_ready &&
|
||||
network_callback->self->recent_servers_done_loading)
|
||||
{
|
||||
g_autolist (NautilusFile) files = nautilus_directory_get_file_list (NAUTILUS_DIRECTORY (self));
|
||||
|
||||
/* Invoke ready callback */
|
||||
(*network_callback->callback)(NAUTILUS_DIRECTORY (self), files, network_callback->callback_data);
|
||||
|
||||
/* Remove it from pending callbacks list and free it */
|
||||
self->callback_list = g_list_remove (self->callback_list, network_callback);
|
||||
g_free (network_callback);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_recent_servers_loading_changed (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (user_data);
|
||||
NautilusRecentServers *recent_servers = NAUTILUS_RECENT_SERVERS (object);
|
||||
gboolean is_loading = nautilus_recent_servers_get_loading (recent_servers);
|
||||
|
||||
self->recent_servers_done_loading = !is_loading;
|
||||
if (self->recent_servers_done_loading)
|
||||
{
|
||||
NautilusDirectory *self_as_directory = NAUTILUS_DIRECTORY (self);
|
||||
|
||||
on_backend_directory_done_loading (self_as_directory, self);
|
||||
|
||||
for (GList *l = self->callback_list; l != NULL; l = l->next)
|
||||
{
|
||||
on_backend_directory_ready (self_as_directory, NULL, l->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_computer_backend_directory_files_added (NautilusNetworkDirectory *self,
|
||||
GList *added_files)
|
||||
{
|
||||
g_autolist (NautilusFile) files = get_remote_mountables (added_files);
|
||||
|
||||
if (files == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nautilus_directory_emit_files_added (NAUTILUS_DIRECTORY (self), files);
|
||||
}
|
||||
|
||||
static void
|
||||
on_computer_backend_directory_files_changed (NautilusNetworkDirectory *self,
|
||||
GList *changed_files)
|
||||
{
|
||||
g_autolist (NautilusFile) files = get_remote_mountables (changed_files);
|
||||
|
||||
if (files == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nautilus_directory_emit_files_changed (NAUTILUS_DIRECTORY (self), files);
|
||||
}
|
||||
|
||||
static NautilusFile *
|
||||
get_recent_server_file (NautilusDirectory *directory,
|
||||
GFileInfo *server_info)
|
||||
{
|
||||
g_autofree char *uri = g_strconcat (SCHEME_NETWORK_VIEW ":///",
|
||||
g_file_info_get_name (server_info),
|
||||
NULL);
|
||||
g_autoptr (NautilusFile) file = nautilus_file_get_by_uri (uri);
|
||||
|
||||
nautilus_file_update_info (file, server_info);
|
||||
|
||||
return g_steal_pointer (&file);
|
||||
}
|
||||
|
||||
static void
|
||||
on_recent_servers_added (NautilusNetworkDirectory *self,
|
||||
GList *servers)
|
||||
{
|
||||
NautilusDirectory *dir = NAUTILUS_DIRECTORY (self);
|
||||
g_autolist (NautilusFile) added_files = NULL;
|
||||
|
||||
for (GList *l = servers; l != NULL; l = l->next)
|
||||
{
|
||||
GFileInfo *server_info = l->data;
|
||||
g_autoptr (NautilusFile) file = get_recent_server_file (dir, server_info);
|
||||
|
||||
self->recent_server_files = g_list_prepend (self->recent_server_files,
|
||||
g_object_ref (file));
|
||||
|
||||
added_files = g_list_prepend (added_files, g_steal_pointer (&file));
|
||||
}
|
||||
|
||||
nautilus_directory_emit_files_added (dir, added_files);
|
||||
}
|
||||
|
||||
static void
|
||||
on_recent_servers_changed (NautilusNetworkDirectory *self,
|
||||
GList *servers)
|
||||
{
|
||||
g_autolist (NautilusFile) changed_files = NULL;
|
||||
|
||||
for (GList *l = servers; l != NULL; l = l->next)
|
||||
{
|
||||
GFileInfo *server_info = l->data;
|
||||
NautilusFile *file = nautilus_directory_find_file_by_name (NAUTILUS_DIRECTORY (self),
|
||||
g_file_info_get_name (server_info));
|
||||
if (file == NULL)
|
||||
{
|
||||
g_critical ("Notified change on recent server whose random GUID name was not known yet");
|
||||
continue;
|
||||
}
|
||||
|
||||
nautilus_file_update_info (file, server_info);
|
||||
|
||||
changed_files = g_list_prepend (changed_files, g_object_ref (file));
|
||||
}
|
||||
|
||||
nautilus_directory_emit_files_changed (NAUTILUS_DIRECTORY (self), changed_files);
|
||||
}
|
||||
|
||||
static void
|
||||
on_recent_servers_removed (NautilusNetworkDirectory *self,
|
||||
GList *servers)
|
||||
{
|
||||
g_autolist (NautilusFile) removed_files = NULL;
|
||||
|
||||
for (GList *l = servers; l != NULL; l = l->next)
|
||||
{
|
||||
GFileInfo *server_info = l->data;
|
||||
NautilusFile *file = nautilus_directory_find_file_by_name (NAUTILUS_DIRECTORY (self),
|
||||
g_file_info_get_name (server_info));
|
||||
if (file == NULL)
|
||||
{
|
||||
g_critical ("Notified removal of recent server whose random GUID name was not known yet");
|
||||
continue;
|
||||
}
|
||||
|
||||
nautilus_file_mark_gone (file);
|
||||
|
||||
/* Steal file from self->recent_server_files */
|
||||
GList *link = g_list_find (self->recent_server_files, file);
|
||||
self->recent_server_files = g_list_remove_link (self->recent_server_files, link);
|
||||
removed_files = g_list_concat (link, removed_files);
|
||||
}
|
||||
|
||||
nautilus_directory_emit_files_changed (NAUTILUS_DIRECTORY (self), removed_files);
|
||||
}
|
||||
|
||||
static NetworkCallback *
|
||||
network_callback_find (NautilusNetworkDirectory *self,
|
||||
NautilusDirectoryCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
for (GList *l = self->callback_list; l != NULL; l = l->next)
|
||||
{
|
||||
NetworkCallback *network_callback = l->data;
|
||||
|
||||
if (network_callback->callback == callback &&
|
||||
network_callback->callback_data == callback_data)
|
||||
{
|
||||
return network_callback;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
real_call_when_ready (NautilusDirectory *directory,
|
||||
NautilusFileAttributes file_attributes,
|
||||
gboolean wait_for_file_list,
|
||||
NautilusDirectoryCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
NetworkCallback *network_callback;
|
||||
|
||||
network_callback = network_callback_find (self, callback, callback_data);
|
||||
if (network_callback != NULL)
|
||||
{
|
||||
g_warning ("tried to add a new callback while an old one was pending");
|
||||
return;
|
||||
}
|
||||
|
||||
network_callback = g_new0 (NetworkCallback, 1);
|
||||
network_callback->self = self;
|
||||
network_callback->callback = callback;
|
||||
network_callback->callback_data = callback_data;
|
||||
|
||||
self->callback_list = g_list_prepend (self->callback_list, network_callback);
|
||||
|
||||
nautilus_directory_call_when_ready (self->computer_backend_directory,
|
||||
file_attributes,
|
||||
wait_for_file_list,
|
||||
on_backend_directory_ready, network_callback);
|
||||
nautilus_directory_call_when_ready (self->network_backend_directory,
|
||||
file_attributes,
|
||||
wait_for_file_list,
|
||||
on_backend_directory_ready, network_callback);
|
||||
}
|
||||
|
||||
static void
|
||||
real_cancel_callback (NautilusDirectory *directory,
|
||||
NautilusDirectoryCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
NetworkCallback *network_callback;
|
||||
|
||||
network_callback = network_callback_find (self, callback, callback_data);
|
||||
if (network_callback == NULL)
|
||||
{
|
||||
/* No warning needed, because nautilus_directory_cancel_callback() is
|
||||
* meant to be used unconditionally as cleanup. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!network_callback->computer_backend_ready)
|
||||
{
|
||||
nautilus_directory_cancel_callback (self->computer_backend_directory, on_backend_directory_ready, network_callback);
|
||||
}
|
||||
if (!network_callback->network_backend_ready)
|
||||
{
|
||||
nautilus_directory_cancel_callback (self->network_backend_directory, on_backend_directory_ready, network_callback);
|
||||
}
|
||||
|
||||
self->callback_list = g_list_remove (self->callback_list, network_callback);
|
||||
g_free (network_callback);
|
||||
}
|
||||
|
||||
static void
|
||||
real_file_monitor_add (NautilusDirectory *directory,
|
||||
gconstpointer client,
|
||||
gboolean monitor_hidden_files,
|
||||
NautilusFileAttributes file_attributes,
|
||||
NautilusDirectoryCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
|
||||
nautilus_directory_file_monitor_add (self->computer_backend_directory,
|
||||
client,
|
||||
monitor_hidden_files,
|
||||
file_attributes,
|
||||
NULL, NULL);
|
||||
nautilus_directory_file_monitor_add (self->network_backend_directory,
|
||||
client,
|
||||
monitor_hidden_files,
|
||||
file_attributes,
|
||||
NULL, NULL);
|
||||
|
||||
if (callback != NULL)
|
||||
{
|
||||
g_autolist (NautilusFile) files = nautilus_directory_get_file_list (directory);
|
||||
|
||||
(*callback)(directory, files, callback_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
real_file_monitor_remove (NautilusDirectory *directory,
|
||||
gconstpointer client)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
|
||||
nautilus_directory_file_monitor_remove (self->computer_backend_directory, client);
|
||||
nautilus_directory_file_monitor_remove (self->network_backend_directory, client);
|
||||
}
|
||||
|
||||
static GList *
|
||||
real_get_file_list (NautilusDirectory *directory)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
g_autolist (NautilusFile) computer_list = nautilus_directory_get_file_list (self->computer_backend_directory);
|
||||
g_autolist (NautilusFile) network_list = nautilus_directory_get_file_list (self->network_backend_directory);
|
||||
g_autolist (NautilusFile) recent_servers = nautilus_file_list_copy (self->recent_server_files);
|
||||
|
||||
return g_list_concat (get_remote_mountables (computer_list),
|
||||
g_list_concat (g_steal_pointer (&recent_servers),
|
||||
g_steal_pointer (&network_list)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_is_not_empty (NautilusDirectory *directory)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (directory);
|
||||
|
||||
if (self->recent_server_files != NULL ||
|
||||
nautilus_directory_is_not_empty (self->network_backend_directory))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (nautilus_directory_is_not_empty (self->computer_backend_directory))
|
||||
{
|
||||
g_autolist (NautilusFile) computer_list = nautilus_directory_get_file_list (self->computer_backend_directory);
|
||||
g_autolist (NautilusFile) remote_mountables = get_remote_mountables (computer_list);
|
||||
|
||||
if (remote_mountables != NULL)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_is_editable (NautilusDirectory *directory)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_handles_location (GFile *location)
|
||||
{
|
||||
return g_file_has_uri_scheme (location, SCHEME_NETWORK_VIEW);
|
||||
}
|
||||
|
||||
static NautilusFile *
|
||||
real_new_file_from_filename (NautilusDirectory *directory,
|
||||
const char *filename,
|
||||
gboolean self_owned)
|
||||
{
|
||||
if (!self_owned)
|
||||
{
|
||||
/* Children are regular vfs locations. */
|
||||
return NAUTILUS_DIRECTORY_CLASS (nautilus_network_directory_parent_class)->new_file_from_filename (directory, filename, self_owned);
|
||||
}
|
||||
|
||||
return NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_INTERNAL_PLACE_FILE,
|
||||
"directory", directory,
|
||||
NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_directory_dispose (GObject *object)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (object);
|
||||
|
||||
g_clear_list (&self->recent_server_files, g_object_unref);
|
||||
g_clear_list (&self->callback_list, g_free);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_network_directory_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_directory_finalize (GObject *object)
|
||||
{
|
||||
NautilusNetworkDirectory *self = NAUTILUS_NETWORK_DIRECTORY (object);
|
||||
|
||||
g_clear_object (&self->computer_backend_directory);
|
||||
g_clear_object (&self->network_backend_directory);
|
||||
g_clear_object (&self->recent_servers);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_network_directory_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_directory_init (NautilusNetworkDirectory *self)
|
||||
{
|
||||
self->computer_backend_directory = nautilus_directory_get_by_uri (SCHEME_COMPUTER ":///");
|
||||
g_signal_connect_object (self->computer_backend_directory, "files-added",
|
||||
G_CALLBACK (on_computer_backend_directory_files_added), self, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (self->computer_backend_directory, "files-changed",
|
||||
G_CALLBACK (on_computer_backend_directory_files_changed), self, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (self->computer_backend_directory, "done-loading",
|
||||
G_CALLBACK (on_backend_directory_done_loading), self, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_object (self->computer_backend_directory, "load-error",
|
||||
G_CALLBACK (nautilus_directory_emit_load_error), self, G_CONNECT_SWAPPED);
|
||||
|
||||
self->network_backend_directory = nautilus_directory_get_by_uri (SCHEME_NETWORK ":///");
|
||||
g_signal_connect_object (self->network_backend_directory, "files-added",
|
||||
G_CALLBACK (nautilus_directory_emit_files_added), self, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (self->network_backend_directory, "files-changed",
|
||||
G_CALLBACK (nautilus_directory_emit_files_changed), self, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (self->network_backend_directory, "done-loading",
|
||||
G_CALLBACK (on_backend_directory_done_loading), self, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_object (self->network_backend_directory, "load-error",
|
||||
G_CALLBACK (nautilus_directory_emit_load_error), self, G_CONNECT_SWAPPED);
|
||||
|
||||
self->recent_servers = nautilus_recent_servers_new ();
|
||||
g_signal_connect_object (self->recent_servers, "notify::loading",
|
||||
G_CALLBACK (on_recent_servers_loading_changed), self, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_object (self->recent_servers, "added",
|
||||
G_CALLBACK (on_recent_servers_added), self, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (self->recent_servers, "changed",
|
||||
G_CALLBACK (on_recent_servers_changed), self, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (self->recent_servers, "removed",
|
||||
G_CALLBACK (on_recent_servers_removed), self, G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_directory_class_init (NautilusNetworkDirectoryClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
NautilusDirectoryClass *directory_class = NAUTILUS_DIRECTORY_CLASS (klass);
|
||||
|
||||
object_class->finalize = nautilus_network_directory_finalize;
|
||||
object_class->dispose = nautilus_network_directory_dispose;
|
||||
|
||||
directory_class->are_all_files_seen = real_are_all_files_seen;
|
||||
directory_class->contains_file = real_contains_file;
|
||||
directory_class->force_reload = real_force_reload;
|
||||
directory_class->call_when_ready = real_call_when_ready;
|
||||
directory_class->cancel_callback = real_cancel_callback;
|
||||
directory_class->file_monitor_add = real_file_monitor_add;
|
||||
directory_class->file_monitor_remove = real_file_monitor_remove;
|
||||
directory_class->get_file_list = real_get_file_list;
|
||||
directory_class->is_not_empty = real_is_not_empty;
|
||||
directory_class->is_editable = real_is_editable;
|
||||
directory_class->handles_location = real_handles_location;
|
||||
directory_class->new_file_from_filename = real_new_file_from_filename;
|
||||
}
|
||||
|
||||
NautilusNetworkDirectory *
|
||||
nautilus_network_directory_new (void)
|
||||
{
|
||||
g_autoptr (GFile) location = g_file_new_for_uri (SCHEME_NETWORK_VIEW ":///");
|
||||
|
||||
return g_object_new (NAUTILUS_TYPE_NETWORK_DIRECTORY,
|
||||
"location", location,
|
||||
NULL);
|
||||
}
|
22
src/nautilus-network-directory.h
Normal file
22
src/nautilus-network-directory.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2024 António Fernandes <antoniof@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nautilus-directory.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_NETWORK_DIRECTORY_PROVIDER_NAME "network-directory-provider"
|
||||
|
||||
#define NAUTILUS_TYPE_NETWORK_DIRECTORY (nautilus_network_directory_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusNetworkDirectory, nautilus_network_directory, NAUTILUS, NETWORK_DIRECTORY, NautilusDirectory);
|
||||
|
||||
NautilusNetworkDirectory* nautilus_network_directory_new (void);
|
||||
|
||||
G_END_DECLS
|
394
src/nautilus-network-view.c
Normal file
394
src/nautilus-network-view.c
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The GNOME project contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "nautilus-list-base-private.h"
|
||||
#include "nautilus-network-view.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "nautilus-global-preferences.h"
|
||||
#include "nautilus-network-cell.h"
|
||||
#include "nautilus-scheme.h"
|
||||
|
||||
struct _NautilusNetworkView
|
||||
{
|
||||
NautilusListBase parent_instance;
|
||||
|
||||
GtkListView *view_ui;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NautilusNetworkView, nautilus_network_view, NAUTILUS_TYPE_LIST_BASE)
|
||||
|
||||
#define get_view_item(li) \
|
||||
(NAUTILUS_VIEW_ITEM (gtk_tree_list_row_get_item (GTK_TREE_LIST_ROW (gtk_list_item_get_item (li)))))
|
||||
|
||||
static const NautilusViewInfo network_view_info =
|
||||
{
|
||||
.view_id = NAUTILUS_VIEW_NETWORK_ID,
|
||||
.zoom_level_min = NAUTILUS_LIST_ZOOM_LEVEL_SMALL,
|
||||
.zoom_level_max = NAUTILUS_LIST_ZOOM_LEVEL_SMALL,
|
||||
.zoom_level_standard = NAUTILUS_LIST_ZOOM_LEVEL_SMALL,
|
||||
};
|
||||
|
||||
static NautilusViewInfo
|
||||
real_get_view_info (NautilusListBase *list_base)
|
||||
{
|
||||
return network_view_info;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
SECTION_CONNECTED,
|
||||
SECTION_PREVIOUS,
|
||||
SECTION_AVAILABLE,
|
||||
};
|
||||
|
||||
static inline gint
|
||||
get_section (NautilusViewItem *item)
|
||||
{
|
||||
NautilusFile *file = nautilus_view_item_get_file (item);
|
||||
|
||||
if (nautilus_file_can_unmount (file))
|
||||
{
|
||||
return SECTION_CONNECTED;
|
||||
}
|
||||
|
||||
g_autoptr (GFile) location = nautilus_file_get_location (file);
|
||||
|
||||
if (g_file_has_uri_scheme (location, SCHEME_NETWORK))
|
||||
{
|
||||
return SECTION_AVAILABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SECTION_PREVIOUS;
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
sort_network_sections (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeListRow *row_a = GTK_TREE_LIST_ROW ((gpointer) a);
|
||||
GtkTreeListRow *row_b = GTK_TREE_LIST_ROW ((gpointer) b);
|
||||
g_autoptr (NautilusViewItem) item_a = NAUTILUS_VIEW_ITEM (gtk_tree_list_row_get_item (row_a));
|
||||
g_autoptr (NautilusViewItem) item_b = NAUTILUS_VIEW_ITEM (gtk_tree_list_row_get_item (row_b));
|
||||
|
||||
return get_section (item_a) - get_section (item_b);
|
||||
}
|
||||
|
||||
static gint
|
||||
sort_network_items (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusViewItem *item_a = NAUTILUS_VIEW_ITEM ((gpointer) a);
|
||||
NautilusViewItem *item_b = NAUTILUS_VIEW_ITEM ((gpointer) b);
|
||||
NautilusFile *file_a = nautilus_view_item_get_file (item_a);
|
||||
NautilusFile *file_b = nautilus_view_item_get_file (item_b);
|
||||
|
||||
if (get_section (item_a) == SECTION_PREVIOUS &&
|
||||
get_section (item_a) == SECTION_PREVIOUS)
|
||||
{
|
||||
return nautilus_file_compare_for_sort (file_a, file_b,
|
||||
NAUTILUS_FILE_SORT_BY_ATIME,
|
||||
FALSE, TRUE /* reversed */);
|
||||
}
|
||||
|
||||
return nautilus_file_compare_for_sort (file_a, file_b,
|
||||
NAUTILUS_FILE_SORT_BY_DISPLAY_NAME,
|
||||
FALSE, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
real_set_zoom_level (NautilusListBase *list_base,
|
||||
int new_level)
|
||||
{
|
||||
g_warn_if_fail (new_level == network_view_info.zoom_level_standard);
|
||||
}
|
||||
|
||||
/* We only care about the keyboard activation part that GtkListView provides,
|
||||
* but we don't need any special filtering here. Indeed, we ask GtkListView
|
||||
* to not activate on single click, and we get to handle double clicks before
|
||||
* GtkListView does (as one of widget subclassing's goal is to modify the parent
|
||||
* class's behavior), while claiming the click gestures, so it means GtkListView
|
||||
* will never react to a click event to emit this signal. So we should be pretty
|
||||
* safe here with regards to our custom item click handling.
|
||||
*/
|
||||
static void
|
||||
on_list_view_item_activated (GtkListView *list_view,
|
||||
guint position,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusNetworkView *self = NAUTILUS_NETWORK_VIEW (user_data);
|
||||
|
||||
nautilus_list_base_activate_selection (NAUTILUS_LIST_BASE (self), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
real_popup_background_context_menu (NautilusListBase *self,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
g_signal_stop_emission_by_name (G_OBJECT (self), "popup-background-context-menu");
|
||||
}
|
||||
|
||||
static guint
|
||||
real_get_icon_size (NautilusListBase *list_base_view)
|
||||
{
|
||||
return NAUTILUS_LIST_ICON_SIZE_SMALL;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
real_get_view_ui (NautilusListBase *list_base_view)
|
||||
{
|
||||
NautilusNetworkView *self = NAUTILUS_NETWORK_VIEW (list_base_view);
|
||||
|
||||
return GTK_WIDGET (self->view_ui);
|
||||
}
|
||||
|
||||
static int
|
||||
real_get_zoom_level (NautilusListBase *list_base_view)
|
||||
{
|
||||
return network_view_info.zoom_level_standard;
|
||||
}
|
||||
|
||||
static void
|
||||
real_scroll_to (NautilusListBase *list_base_view,
|
||||
guint position,
|
||||
GtkListScrollFlags flags,
|
||||
GtkScrollInfo *scroll)
|
||||
{
|
||||
NautilusNetworkView *self = NAUTILUS_NETWORK_VIEW (list_base_view);
|
||||
|
||||
gtk_list_view_scroll_to (self->view_ui, position, flags, scroll);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
real_get_sort_state (NautilusListBase *list_base)
|
||||
{
|
||||
return g_variant_take_ref (g_variant_new ("(sb)", "invalid", FALSE));
|
||||
}
|
||||
|
||||
static void
|
||||
real_set_sort_state (NautilusListBase *list_base,
|
||||
GVariant *value)
|
||||
{
|
||||
/* No op */
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_view_dispose (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (nautilus_network_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_view_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (nautilus_network_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_cell (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *listitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *cell = gtk_list_item_get_child (listitem);
|
||||
g_autoptr (NautilusViewItem) item = get_view_item (listitem);
|
||||
|
||||
nautilus_view_item_set_item_ui (item, cell);
|
||||
}
|
||||
|
||||
static void
|
||||
unbind_cell (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *listitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr (NautilusViewItem) item = get_view_item (listitem);
|
||||
|
||||
/* item may be NULL when row has just been destroyed. */
|
||||
if (item != NULL)
|
||||
{
|
||||
nautilus_view_item_set_item_ui (item, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_cell (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *listitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusNetworkView *self = NAUTILUS_NETWORK_VIEW (user_data);
|
||||
NautilusViewCell *cell;
|
||||
GtkExpression *expression;
|
||||
|
||||
cell = nautilus_network_cell_new (NAUTILUS_LIST_BASE (self));
|
||||
gtk_list_item_set_child (listitem, GTK_WIDGET (cell));
|
||||
setup_cell_common (G_OBJECT (listitem), cell);
|
||||
setup_cell_hover (cell);
|
||||
|
||||
g_object_bind_property (self, "icon-size",
|
||||
cell, "icon-size",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
|
||||
/* Use file display name as accessible label. Explaining in pseudo-code:
|
||||
* listitem:accessible-name :- listitem:item:item:file:display-name */
|
||||
expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, NULL, "item");
|
||||
expression = gtk_property_expression_new (GTK_TYPE_TREE_LIST_ROW, expression, "item");
|
||||
expression = gtk_property_expression_new (NAUTILUS_TYPE_VIEW_ITEM, expression, "file");
|
||||
expression = gtk_property_expression_new (NAUTILUS_TYPE_FILE, expression, "display-name");
|
||||
gtk_expression_bind (expression, listitem, "accessible-label", listitem);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_header (GtkSignalListItemFactory *factory,
|
||||
GtkListHeader *listheader,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = gtk_list_header_get_child (listheader);
|
||||
GtkTreeListRow *row = GTK_TREE_LIST_ROW (gtk_list_header_get_item (listheader));
|
||||
g_autoptr (NautilusViewItem) item = NAUTILUS_VIEW_ITEM (gtk_tree_list_row_get_item (row));
|
||||
|
||||
switch (get_section (item))
|
||||
{
|
||||
case SECTION_CONNECTED:
|
||||
{
|
||||
/* Translators: This refers to network places which are currently mounted */
|
||||
gtk_label_set_label (GTK_LABEL (label), _("Connected"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SECTION_PREVIOUS:
|
||||
{
|
||||
/* Translators: This refers to network servers the user has previously connected to */
|
||||
gtk_label_set_label (GTK_LABEL (label), _("Previous"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SECTION_AVAILABLE:
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (label), _("Available on Current Network"));
|
||||
/* TODO: Use network name from NMClient:primary-connection:id to
|
||||
* match design mockup: "Available on Network1234"
|
||||
*/
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup_header (GtkSignalListItemFactory *factory,
|
||||
GtkListHeader *listheader,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = gtk_label_new (NULL);
|
||||
|
||||
gtk_widget_add_css_class (label, "heading");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
|
||||
gtk_list_header_set_child (listheader, label);
|
||||
}
|
||||
|
||||
static void
|
||||
on_model_changed (NautilusNetworkView *self)
|
||||
{
|
||||
NautilusViewModel *model = nautilus_list_base_get_model (NAUTILUS_LIST_BASE (self));
|
||||
|
||||
if (model != NULL)
|
||||
{
|
||||
g_autoptr (GtkCustomSorter) sorter = gtk_custom_sorter_new (sort_network_items, self, NULL);
|
||||
g_autoptr (GtkCustomSorter) sections_sorter = gtk_custom_sorter_new (sort_network_sections, self, NULL);
|
||||
|
||||
nautilus_view_model_set_sorter (model, GTK_SORTER (sorter));
|
||||
nautilus_view_model_set_section_sorter (model, GTK_SORTER (sections_sorter));
|
||||
}
|
||||
|
||||
gtk_list_view_set_model (self->view_ui, GTK_SELECTION_MODEL (model));
|
||||
}
|
||||
|
||||
static GtkListView *
|
||||
create_view_ui (NautilusNetworkView *self)
|
||||
{
|
||||
g_autoptr (GtkListItemFactory) factory = gtk_signal_list_item_factory_new ();
|
||||
g_autoptr (GtkListItemFactory) header_factory = gtk_signal_list_item_factory_new ();
|
||||
GtkListView *list_view;
|
||||
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_cell), self);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_cell), self);
|
||||
g_signal_connect (factory, "unbind", G_CALLBACK (unbind_cell), self);
|
||||
|
||||
list_view = GTK_LIST_VIEW (gtk_list_view_new (NULL, g_steal_pointer (&factory)));
|
||||
|
||||
g_signal_connect (header_factory, "setup", G_CALLBACK (setup_header), self);
|
||||
g_signal_connect (header_factory, "bind", G_CALLBACK (bind_header), self);
|
||||
gtk_list_view_set_header_factory (list_view, header_factory);
|
||||
|
||||
/* We don't use the built-in child activation feature for clicks because it
|
||||
* doesn't fill all our needs nor does it match our expected behavior.
|
||||
* Instead, we roll our own event handling and double/single click mode.
|
||||
* However, GtkListView:single-click-activate has other effects besides
|
||||
* activation, as it affects the selection behavior as well (e.g. selects on
|
||||
* hover). Setting it to FALSE gives us the expected behavior. */
|
||||
gtk_list_view_set_single_click_activate (list_view, FALSE);
|
||||
gtk_list_view_set_enable_rubberband (list_view, FALSE);
|
||||
gtk_list_view_set_tab_behavior (list_view, GTK_LIST_TAB_ITEM);
|
||||
|
||||
/* While we don't want to use GTK's click activation, we'll let it handle
|
||||
* the key activation part (with Enter). */
|
||||
g_signal_connect (list_view, "activate", G_CALLBACK (on_list_view_item_activated), self);
|
||||
|
||||
return list_view;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_view_class_init (NautilusNetworkViewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
NautilusListBaseClass *list_base_view_class = NAUTILUS_LIST_BASE_CLASS (klass);
|
||||
|
||||
object_class->dispose = nautilus_network_view_dispose;
|
||||
object_class->finalize = nautilus_network_view_finalize;
|
||||
|
||||
list_base_view_class->get_icon_size = real_get_icon_size;
|
||||
list_base_view_class->get_sort_state = real_get_sort_state;
|
||||
list_base_view_class->get_view_info = real_get_view_info;
|
||||
list_base_view_class->get_view_ui = real_get_view_ui;
|
||||
list_base_view_class->get_zoom_level = real_get_zoom_level;
|
||||
list_base_view_class->popup_background_context_menu = real_popup_background_context_menu;
|
||||
list_base_view_class->scroll_to = real_scroll_to;
|
||||
list_base_view_class->set_sort_state = real_set_sort_state;
|
||||
list_base_view_class->set_zoom_level = real_set_zoom_level;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_network_view_init (NautilusNetworkView *self)
|
||||
{
|
||||
GtkWidget *scrolled_window = nautilus_list_base_get_scrolled_window (NAUTILUS_LIST_BASE (self));
|
||||
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "nautilus-network-view");
|
||||
|
||||
self->view_ui = create_view_ui (self);
|
||||
nautilus_list_base_setup_gestures (NAUTILUS_LIST_BASE (self));
|
||||
|
||||
g_signal_connect_swapped (self, "notify::model", G_CALLBACK (on_model_changed), self);
|
||||
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled_window),
|
||||
GTK_WIDGET (self->view_ui));
|
||||
nautilus_list_base_set_zoom_level (NAUTILUS_LIST_BASE (self), network_view_info.zoom_level_standard);
|
||||
}
|
||||
|
||||
NautilusNetworkView *
|
||||
nautilus_network_view_new (void)
|
||||
{
|
||||
return g_object_new (NAUTILUS_TYPE_NETWORK_VIEW, NULL);
|
||||
}
|
19
src/nautilus-network-view.h
Normal file
19
src/nautilus-network-view.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2024 The GNOME project contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "nautilus-list-base.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_NETWORK_VIEW (nautilus_network_view_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusNetworkView, nautilus_network_view, NAUTILUS, NETWORK_VIEW, NautilusListBase)
|
||||
|
||||
NautilusNetworkView *nautilus_network_view_new (void);
|
||||
|
||||
G_END_DECLS
|
|
@ -25,7 +25,6 @@
|
|||
#include "nautilus-pathbar.h"
|
||||
#include "nautilus-properties-window.h"
|
||||
|
||||
#include "nautilus-application.h"
|
||||
#include "nautilus-dnd.h"
|
||||
#include "nautilus-enums.h"
|
||||
#include "nautilus-enum-types.h"
|
||||
|
@ -36,7 +35,6 @@
|
|||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-trash-monitor.h"
|
||||
#include "nautilus-ui-utilities.h"
|
||||
#include "nautilus-window.h"
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
#include <gdk/x11/gdkx.h>
|
||||
|
@ -51,7 +49,6 @@ enum
|
|||
typedef enum
|
||||
{
|
||||
NORMAL_BUTTON,
|
||||
OTHER_LOCATIONS_BUTTON,
|
||||
ROOT_BUTTON,
|
||||
ADMIN_ROOT_BUTTON,
|
||||
HOME_BUTTON,
|
||||
|
@ -59,12 +56,22 @@ typedef enum
|
|||
RECENT_BUTTON,
|
||||
MOUNT_BUTTON,
|
||||
TRASH_BUTTON,
|
||||
NETWORK_BUTTON,
|
||||
} ButtonType;
|
||||
|
||||
#define BUTTON_DATA(x) ((ButtonData *) (x))
|
||||
|
||||
static guint path_bar_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_WINDOW_SLOT,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
#define NAUTILUS_PATH_BAR_BUTTON_ELLIPSIZE_MINIMUM_CHARS 7
|
||||
|
||||
typedef struct
|
||||
|
@ -115,6 +122,8 @@ struct _NautilusPathBar
|
|||
GMenu *button_menu;
|
||||
|
||||
gchar *os_name;
|
||||
|
||||
NautilusWindowSlot *slot;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NautilusPathBar, nautilus_path_bar, GTK_TYPE_BOX);
|
||||
|
@ -335,6 +344,8 @@ nautilus_path_bar_finalize (GObject *object)
|
|||
g_clear_object (&self->current_view_menu_popover);
|
||||
g_free (self->os_name);
|
||||
|
||||
g_clear_weak_pointer (&self->slot);
|
||||
|
||||
unschedule_pop_up_context_menu (NAUTILUS_PATH_BAR (object));
|
||||
|
||||
G_OBJECT_CLASS (nautilus_path_bar_parent_class)->finalize (object);
|
||||
|
@ -381,16 +392,6 @@ get_dir_name (ButtonData *button_data)
|
|||
return _("Home");
|
||||
}
|
||||
|
||||
case OTHER_LOCATIONS_BUTTON:
|
||||
{
|
||||
return _("Other Locations");
|
||||
}
|
||||
|
||||
case STARRED_BUTTON:
|
||||
{
|
||||
return _("Starred");
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return button_data->dir_name;
|
||||
|
@ -413,6 +414,29 @@ button_data_free (ButtonData *button_data)
|
|||
|
||||
g_free (button_data);
|
||||
}
|
||||
static void
|
||||
nautilus_path_bar_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NautilusPathBar *self = NAUTILUS_PATH_BAR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_WINDOW_SLOT:
|
||||
{
|
||||
g_set_weak_pointer (&self->slot, g_value_get_object (value));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_path_bar_class_init (NautilusPathBarClass *path_bar_class)
|
||||
|
@ -423,6 +447,7 @@ nautilus_path_bar_class_init (NautilusPathBarClass *path_bar_class)
|
|||
|
||||
gobject_class->finalize = nautilus_path_bar_finalize;
|
||||
gobject_class->dispose = nautilus_path_bar_dispose;
|
||||
gobject_class->set_property = nautilus_path_bar_set_property;
|
||||
|
||||
path_bar_signals [OPEN_LOCATION] =
|
||||
g_signal_new ("open-location",
|
||||
|
@ -433,6 +458,13 @@ nautilus_path_bar_class_init (NautilusPathBarClass *path_bar_class)
|
|||
G_TYPE_NONE, 2,
|
||||
G_TYPE_FILE,
|
||||
NAUTILUS_TYPE_OPEN_FLAGS);
|
||||
|
||||
properties [PROP_WINDOW_SLOT] =
|
||||
g_param_spec_object ("window-slot", NULL, NULL,
|
||||
NAUTILUS_TYPE_WINDOW_SLOT,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -698,22 +730,19 @@ on_click_gesture_pressed (GtkGestureClick *gesture,
|
|||
static void
|
||||
switch_location (ButtonData *button_data)
|
||||
{
|
||||
GFile *location;
|
||||
GtkRoot *window;
|
||||
|
||||
if (button_data->file == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
window = gtk_widget_get_root (button_data->button);
|
||||
g_assert (NAUTILUS_IS_WINDOW (window));
|
||||
NautilusPathBar *self = button_data->path_bar;
|
||||
g_autoptr (GFile) location = nautilus_file_get_location (button_data->file);
|
||||
|
||||
location = nautilus_file_get_location (button_data->file);
|
||||
nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()),
|
||||
g_return_if_fail (self->slot != NULL);
|
||||
|
||||
nautilus_window_slot_open_location_full (self->slot,
|
||||
location, NAUTILUS_OPEN_FLAG_DONT_MAKE_ACTIVE,
|
||||
NULL, NAUTILUS_WINDOW (window), NULL);
|
||||
g_object_unref (location);
|
||||
NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -807,23 +836,20 @@ on_drag_drop (GtkDropTarget *target,
|
|||
gdouble y,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkRoot *window;
|
||||
NautilusWindowSlot *target_slot;
|
||||
ButtonData *button_data = user_data;
|
||||
NautilusPathBar *self = button_data->path_bar;
|
||||
NautilusFilesView *target_view;
|
||||
g_autoptr (GFile) target_location = NULL;
|
||||
ButtonData *button_data = user_data;
|
||||
GdkDragAction action;
|
||||
|
||||
window = gtk_widget_get_root (button_data->button);
|
||||
g_assert (NAUTILUS_IS_WINDOW (window));
|
||||
g_return_if_fail (self->slot != NULL);
|
||||
|
||||
target_slot = nautilus_window_get_active_slot (NAUTILUS_WINDOW (window));
|
||||
target_location = nautilus_file_get_location (button_data->file);
|
||||
target_view = NAUTILUS_FILES_VIEW (nautilus_window_slot_get_current_view (target_slot));
|
||||
target_view = NAUTILUS_FILES_VIEW (nautilus_window_slot_get_current_view (self->slot));
|
||||
action = gdk_drop_get_actions (gtk_drop_target_get_current_drop (target));
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
|
||||
if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (self))))
|
||||
{
|
||||
/* Temporary workaround until the below GTK MR (or equivalent fix)
|
||||
* is merged. Without this fix, the preferred action isn't set correctly.
|
||||
|
@ -885,16 +911,16 @@ get_gicon (ButtonData *button_data)
|
|||
return g_themed_icon_new ("document-open-recent-symbolic");
|
||||
}
|
||||
|
||||
case OTHER_LOCATIONS_BUTTON:
|
||||
{
|
||||
return g_themed_icon_new ("list-add-symbolic");
|
||||
}
|
||||
|
||||
case TRASH_BUTTON:
|
||||
{
|
||||
return nautilus_trash_monitor_get_symbolic_icon ();
|
||||
}
|
||||
|
||||
case NETWORK_BUTTON:
|
||||
{
|
||||
return g_themed_icon_new ("folder-remote-symbolic");
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return NULL;
|
||||
|
@ -1005,11 +1031,6 @@ setup_button_type (ButtonData *button_data,
|
|||
button_data->type = MOUNT_BUTTON;
|
||||
button_data->is_root = TRUE;
|
||||
}
|
||||
else if (g_file_has_uri_scheme (location, SCHEME_OTHER_LOCATIONS))
|
||||
{
|
||||
button_data->type = OTHER_LOCATIONS_BUTTON;
|
||||
button_data->is_root = TRUE;
|
||||
}
|
||||
else if (nautilus_is_root_for_scheme (location, SCHEME_ADMIN))
|
||||
{
|
||||
button_data->type = ADMIN_ROOT_BUTTON;
|
||||
|
@ -1020,6 +1041,11 @@ setup_button_type (ButtonData *button_data,
|
|||
button_data->type = TRASH_BUTTON;
|
||||
button_data->is_root = TRUE;
|
||||
}
|
||||
else if (nautilus_is_root_for_scheme (location, SCHEME_NETWORK_VIEW))
|
||||
{
|
||||
button_data->type = NETWORK_BUTTON;
|
||||
button_data->is_root = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
button_data->type = NORMAL_BUTTON;
|
||||
|
@ -1157,7 +1183,7 @@ make_button_data (NautilusPathBar *self,
|
|||
case TRASH_BUTTON:
|
||||
case RECENT_BUTTON:
|
||||
case STARRED_BUTTON:
|
||||
case OTHER_LOCATIONS_BUTTON:
|
||||
case NETWORK_BUTTON:
|
||||
{
|
||||
button_data->label = gtk_label_new (NULL);
|
||||
child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
|
|
|
@ -1,406 +0,0 @@
|
|||
/* nautilus-places-view.c
|
||||
*
|
||||
* Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "nautilus-mime-actions.h"
|
||||
#include "nautilus-places-view.h"
|
||||
|
||||
#include "gtk/nautilusgtkplacesviewprivate.h"
|
||||
|
||||
#include "nautilus-application.h"
|
||||
#include "nautilus-file.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-toolbar-menu-sections.h"
|
||||
#include "nautilus-view.h"
|
||||
#include "nautilus-window-slot.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GFile *location;
|
||||
NautilusQuery *search_query;
|
||||
|
||||
GtkWidget *places_view;
|
||||
} NautilusPlacesViewPrivate;
|
||||
|
||||
struct _NautilusPlacesView
|
||||
{
|
||||
GtkFrameClass parent;
|
||||
};
|
||||
|
||||
static void nautilus_places_view_iface_init (NautilusViewInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (NautilusPlacesView, nautilus_places_view, GTK_TYPE_BOX,
|
||||
G_ADD_PRIVATE (NautilusPlacesView)
|
||||
G_IMPLEMENT_INTERFACE (NAUTILUS_TYPE_VIEW, nautilus_places_view_iface_init));
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_LOCATION,
|
||||
PROP_SEARCH_QUERY,
|
||||
PROP_LOADING,
|
||||
PROP_SEARCHING,
|
||||
PROP_SELECTION,
|
||||
PROP_EXTENSIONS_BACKGROUND_MENU,
|
||||
PROP_TEMPLATES_MENU,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static void
|
||||
open_location_cb (NautilusPlacesView *view,
|
||||
GFile *location,
|
||||
NautilusGtkPlacesOpenFlags open_flags)
|
||||
{
|
||||
NautilusOpenFlags flags;
|
||||
GtkWidget *slot;
|
||||
|
||||
slot = gtk_widget_get_ancestor (GTK_WIDGET (view), NAUTILUS_TYPE_WINDOW_SLOT);
|
||||
|
||||
switch (open_flags)
|
||||
{
|
||||
case NAUTILUS_GTK_PLACES_OPEN_NEW_TAB:
|
||||
{
|
||||
flags = NAUTILUS_OPEN_FLAG_NEW_TAB |
|
||||
NAUTILUS_OPEN_FLAG_DONT_MAKE_ACTIVE;
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_GTK_PLACES_OPEN_NEW_WINDOW:
|
||||
{
|
||||
flags = NAUTILUS_OPEN_FLAG_NEW_WINDOW;
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_GTK_PLACES_OPEN_NORMAL: /* fall-through */
|
||||
default:
|
||||
{
|
||||
flags = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (slot)
|
||||
{
|
||||
NautilusFile *file;
|
||||
GtkRoot *window;
|
||||
char *path;
|
||||
|
||||
path = SCHEME_OTHER_LOCATIONS ":///";
|
||||
file = nautilus_file_get (location);
|
||||
window = gtk_widget_get_root (GTK_WIDGET (view));
|
||||
|
||||
nautilus_mime_activate_file (GTK_WINDOW (window),
|
||||
NAUTILUS_WINDOW_SLOT (slot),
|
||||
file,
|
||||
path,
|
||||
flags);
|
||||
nautilus_file_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
loading_cb (NautilusView *view)
|
||||
{
|
||||
g_object_notify (G_OBJECT (view), "loading");
|
||||
}
|
||||
|
||||
static void
|
||||
show_error_message_cb (NautilusGtkPlacesView *view,
|
||||
const gchar *primary,
|
||||
const gchar *secondary)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkRoot *window;
|
||||
|
||||
window = gtk_widget_get_root (GTK_WIDGET (view));
|
||||
|
||||
dialog = adw_message_dialog_new (GTK_WINDOW (window), primary, secondary);
|
||||
adw_message_dialog_add_response (ADW_MESSAGE_DIALOG (dialog),
|
||||
"close", _("_Close"));
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_finalize (GObject *object)
|
||||
{
|
||||
NautilusPlacesView *self = (NautilusPlacesView *) object;
|
||||
NautilusPlacesViewPrivate *priv = nautilus_places_view_get_instance_private (self);
|
||||
|
||||
g_clear_object (&priv->location);
|
||||
g_clear_object (&priv->search_query);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_places_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NautilusView *view = NAUTILUS_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LOCATION:
|
||||
{
|
||||
g_value_set_object (value, nautilus_view_get_location (view));
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SEARCH_QUERY:
|
||||
{
|
||||
g_value_set_object (value, nautilus_view_get_search_query (view));
|
||||
}
|
||||
break;
|
||||
|
||||
/* Collect all unused properties and do nothing. Ideally, this wouldn’t
|
||||
* have to be done in the first place.
|
||||
*/
|
||||
case PROP_SEARCHING:
|
||||
case PROP_SELECTION:
|
||||
case PROP_EXTENSIONS_BACKGROUND_MENU:
|
||||
case PROP_TEMPLATES_MENU:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NautilusView *view = NAUTILUS_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LOCATION:
|
||||
{
|
||||
nautilus_view_set_location (view, g_value_get_object (value));
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SEARCH_QUERY:
|
||||
{
|
||||
nautilus_view_set_search_query (view, g_value_get_object (value));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GFile *
|
||||
nautilus_places_view_get_location (NautilusView *view)
|
||||
{
|
||||
NautilusPlacesViewPrivate *priv;
|
||||
|
||||
priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
|
||||
|
||||
return priv->location;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_set_location (NautilusView *view,
|
||||
GFile *location)
|
||||
{
|
||||
NautilusPlacesViewPrivate *priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
|
||||
|
||||
if (location != NULL &&
|
||||
!g_file_has_uri_scheme (location, SCHEME_OTHER_LOCATIONS))
|
||||
{
|
||||
/*
|
||||
* If it's not trying to open the places view itself, simply
|
||||
* delegates the location to application, which takes care of
|
||||
* selecting the appropriate view.
|
||||
*/
|
||||
nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()),
|
||||
location, 0, NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
g_set_object (&priv->location, location);
|
||||
}
|
||||
|
||||
static GList *
|
||||
nautilus_places_view_get_selection (NautilusView *view)
|
||||
{
|
||||
/* STUB */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_set_selection (NautilusView *view,
|
||||
GList *selection)
|
||||
{
|
||||
/* STUB */
|
||||
}
|
||||
|
||||
static NautilusQuery *
|
||||
nautilus_places_view_get_search_query (NautilusView *view)
|
||||
{
|
||||
NautilusPlacesViewPrivate *priv;
|
||||
|
||||
priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
|
||||
|
||||
return priv->search_query;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_set_search_query (NautilusView *view,
|
||||
NautilusQuery *query)
|
||||
{
|
||||
NautilusPlacesViewPrivate *priv;
|
||||
gchar *text;
|
||||
|
||||
priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
|
||||
|
||||
g_set_object (&priv->search_query, query);
|
||||
|
||||
text = query ? nautilus_query_get_text (query) : NULL;
|
||||
|
||||
nautilus_gtk_places_view_set_search_query (NAUTILUS_GTK_PLACES_VIEW (priv->places_view), text);
|
||||
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static NautilusToolbarMenuSections *
|
||||
nautilus_places_view_get_toolbar_menu_sections (NautilusView *view)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nautilus_places_view_is_loading (NautilusView *view)
|
||||
{
|
||||
NautilusPlacesViewPrivate *priv;
|
||||
|
||||
priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
|
||||
|
||||
return nautilus_gtk_places_view_get_loading (NAUTILUS_GTK_PLACES_VIEW (priv->places_view));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nautilus_places_view_is_searching (NautilusView *view)
|
||||
{
|
||||
NautilusPlacesViewPrivate *priv;
|
||||
|
||||
priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
|
||||
|
||||
return priv->search_query != NULL;
|
||||
}
|
||||
|
||||
static guint
|
||||
nautilus_places_view_get_view_id (NautilusView *view)
|
||||
{
|
||||
return NAUTILUS_VIEW_OTHER_LOCATIONS_ID;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_iface_init (NautilusViewInterface *iface)
|
||||
{
|
||||
iface->get_location = nautilus_places_view_get_location;
|
||||
iface->set_location = nautilus_places_view_set_location;
|
||||
iface->get_selection = nautilus_places_view_get_selection;
|
||||
iface->set_selection = nautilus_places_view_set_selection;
|
||||
iface->get_search_query = nautilus_places_view_get_search_query;
|
||||
iface->set_search_query = nautilus_places_view_set_search_query;
|
||||
iface->get_toolbar_menu_sections = nautilus_places_view_get_toolbar_menu_sections;
|
||||
iface->is_loading = nautilus_places_view_is_loading;
|
||||
iface->is_searching = nautilus_places_view_is_searching;
|
||||
iface->get_view_id = nautilus_places_view_get_view_id;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_class_init (NautilusPlacesViewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = nautilus_places_view_finalize;
|
||||
object_class->get_property = nautilus_places_view_get_property;
|
||||
object_class->set_property = nautilus_places_view_set_property;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_LOADING, "loading");
|
||||
g_object_class_override_property (object_class, PROP_SEARCHING, "searching");
|
||||
g_object_class_override_property (object_class, PROP_LOCATION, "location");
|
||||
g_object_class_override_property (object_class, PROP_SELECTION, "selection");
|
||||
g_object_class_override_property (object_class, PROP_SEARCH_QUERY, "search-query");
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_EXTENSIONS_BACKGROUND_MENU,
|
||||
"extensions-background-menu");
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_TEMPLATES_MENU,
|
||||
"templates-menu");
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_places_view_init (NautilusPlacesView *self)
|
||||
{
|
||||
NautilusPlacesViewPrivate *priv;
|
||||
|
||||
priv = nautilus_places_view_get_instance_private (self);
|
||||
|
||||
/* Location */
|
||||
priv->location = g_file_new_for_uri (SCHEME_OTHER_LOCATIONS ":///");
|
||||
|
||||
/* Places view */
|
||||
priv->places_view = nautilus_gtk_places_view_new ();
|
||||
nautilus_gtk_places_view_set_open_flags (NAUTILUS_GTK_PLACES_VIEW (priv->places_view),
|
||||
NAUTILUS_OPEN_FLAG_NEW_TAB | NAUTILUS_OPEN_FLAG_NEW_WINDOW | NAUTILUS_OPEN_FLAG_NORMAL);
|
||||
gtk_widget_set_hexpand (priv->places_view, TRUE);
|
||||
gtk_widget_set_vexpand (priv->places_view, TRUE);
|
||||
gtk_widget_set_visible (priv->places_view, TRUE);
|
||||
gtk_box_append (GTK_BOX (self), priv->places_view);
|
||||
|
||||
g_signal_connect_object (priv->places_view, "notify::loading",
|
||||
G_CALLBACK (loading_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (priv->places_view, "open-location",
|
||||
G_CALLBACK (open_location_cb), self, G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (priv->places_view, "show-error-message",
|
||||
G_CALLBACK (show_error_message_cb), self, G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
NautilusPlacesView *
|
||||
nautilus_places_view_new (void)
|
||||
{
|
||||
NautilusPlacesView *view;
|
||||
|
||||
view = g_object_new (NAUTILUS_TYPE_PLACES_VIEW, NULL);
|
||||
if (g_object_is_floating (view))
|
||||
{
|
||||
g_object_ref_sink (view);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* nautilus-places-view.h
|
||||
*
|
||||
* Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_PLACES_VIEW (nautilus_places_view_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusPlacesView, nautilus_places_view, NAUTILUS, PLACES_VIEW, GtkBox)
|
||||
|
||||
NautilusPlacesView* nautilus_places_view_new (void);
|
||||
|
||||
G_END_DECLS
|
|
@ -31,6 +31,13 @@
|
|||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
#include <gdk/x11/gdkx.h>
|
||||
#endif
|
||||
|
||||
#define PREVIEWER2_DBUS_IFACE "org.gnome.NautilusPreviewer2"
|
||||
|
||||
static const char *previewer_dbus_name = "org.gnome.NautilusPreviewer" PROFILE;
|
||||
|
@ -43,7 +50,12 @@ static guint subscription_id = 0;
|
|||
|
||||
static GCancellable *cancellable = NULL;
|
||||
|
||||
static GtkRoot *current_window = NULL; /* weak ref */
|
||||
static gchar *exported_window_handle = NULL;
|
||||
|
||||
static void real_call_show_file (const gchar *uri,
|
||||
const gchar *window_handle,
|
||||
gboolean close_if_already_visible);
|
||||
static void create_new_bus (void);
|
||||
static void previewer_selection_event (GDBusConnection *connection,
|
||||
const gchar *sender_name,
|
||||
|
@ -53,6 +65,61 @@ static void previewer_selection_event (GDBusConnection *connection,
|
|||
GVariant *parameters,
|
||||
gpointer user_data);
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
typedef struct
|
||||
{
|
||||
gchar *uri;
|
||||
gboolean close_if_already_visible;
|
||||
} PreviewExportData;
|
||||
|
||||
static void
|
||||
preview_export_data_free (gpointer _data)
|
||||
{
|
||||
PreviewExportData *data = _data;
|
||||
g_free (data->uri);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (PreviewExportData, preview_export_data_free)
|
||||
|
||||
static void
|
||||
wayland_window_handle_exported (GdkToplevel *toplevel,
|
||||
const char *wayland_handle_str,
|
||||
gpointer user_data)
|
||||
{
|
||||
PreviewExportData *data = user_data;
|
||||
g_autofree char *wayland_handle = g_strdup_printf ("wayland:%s", wayland_handle_str);
|
||||
|
||||
real_call_show_file (data->uri, wayland_handle, data->close_if_already_visible);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
clear_exported_window_handle (void)
|
||||
{
|
||||
if (exported_window_handle == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (current_window != NULL &&
|
||||
GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (current_window))))
|
||||
{
|
||||
GdkSurface *gdk_surface = gtk_native_get_surface (GTK_NATIVE (current_window));
|
||||
if (GDK_IS_WAYLAND_TOPLEVEL (gdk_surface) &&
|
||||
g_str_has_prefix (exported_window_handle, "wayland:"))
|
||||
{
|
||||
gdk_wayland_toplevel_drop_exported_handle (GDK_WAYLAND_TOPLEVEL (gdk_surface),
|
||||
exported_window_handle + strlen ("wayland:"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_free (exported_window_handle);
|
||||
exported_window_handle = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
on_ping_finished (GObject *object,
|
||||
GAsyncResult *res,
|
||||
|
@ -173,10 +240,65 @@ previewer2_method_ready_cb (GObject *source,
|
|||
|
||||
void
|
||||
nautilus_previewer_call_show_file (const gchar *uri,
|
||||
const gchar *window_handle,
|
||||
guint xid,
|
||||
GtkRoot *window,
|
||||
gboolean close_if_already_visible)
|
||||
{
|
||||
/* Reuse existing handle if called again for the same window. */
|
||||
if (current_window == window &&
|
||||
exported_window_handle != NULL)
|
||||
{
|
||||
real_call_show_file (uri, exported_window_handle, close_if_already_visible);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, obtain a new window handle. */
|
||||
clear_exported_window_handle ();
|
||||
g_set_weak_pointer (¤t_window, window);
|
||||
|
||||
GdkSurface *gdk_surface = gtk_native_get_surface (GTK_NATIVE (window));
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
|
||||
{
|
||||
guint xid = (guint) gdk_x11_surface_get_xid (gdk_surface);
|
||||
g_autofree char *window_handle = g_strdup_printf ("x11:%x", xid);
|
||||
|
||||
real_call_show_file (uri, window_handle, close_if_already_visible);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
|
||||
{
|
||||
g_autoptr (PreviewExportData) data = g_new0 (PreviewExportData, 1);
|
||||
|
||||
data->uri = g_strdup (uri);
|
||||
data->close_if_already_visible = close_if_already_visible;
|
||||
|
||||
if (gdk_wayland_toplevel_export_handle (GDK_WAYLAND_TOPLEVEL (gdk_surface),
|
||||
wayland_window_handle_exported,
|
||||
data,
|
||||
preview_export_data_free))
|
||||
{
|
||||
/* Don't let autoptr free data successfully taken by the call. */
|
||||
(void) g_steal_pointer (&data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_warning ("Couldn't export handle, unsupported windowing system");
|
||||
|
||||
/* Let's use a fallback, so at least a preview will be displayed */
|
||||
real_call_show_file (uri, "x11:0", close_if_already_visible);
|
||||
}
|
||||
|
||||
static void
|
||||
real_call_show_file (const gchar *uri,
|
||||
const gchar *window_handle,
|
||||
gboolean close_if_already_visible)
|
||||
{
|
||||
g_set_str (&exported_window_handle, window_handle);
|
||||
|
||||
if (!ensure_previewer_proxy ())
|
||||
{
|
||||
return;
|
||||
|
@ -271,6 +393,8 @@ nautilus_previewer_teardown (GDBusConnection *connection)
|
|||
g_cancellable_cancel (cancellable);
|
||||
g_clear_object (&cancellable);
|
||||
g_clear_object (&previewer_proxy);
|
||||
clear_exported_window_handle ();
|
||||
g_clear_weak_pointer (¤t_window);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
|
||||
#include <gio/gio.h>
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void nautilus_previewer_call_show_file (const gchar *uri,
|
||||
const gchar *window_handle,
|
||||
guint xid,
|
||||
gboolean close_if_already_visible);
|
||||
GtkRoot *window,
|
||||
gboolean close_if_already_visible);
|
||||
void nautilus_previewer_call_close (void);
|
||||
|
||||
gboolean nautilus_previewer_is_visible (void);
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "nautilus-icon-info.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-ui-utilities.h"
|
||||
#include "nautilus-window.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
|
|
@ -372,7 +372,7 @@ on_canceled (GCancellable *cancellable,
|
|||
NautilusProgressInfo *info)
|
||||
{
|
||||
G_LOCK (progress_info);
|
||||
set_details (info, _("Canceled"));
|
||||
set_details (info, _("Cancelled"));
|
||||
info->cancel_at_idle = TRUE;
|
||||
g_timer_stop (info->progress_timer);
|
||||
queue_idle (info, TRUE);
|
||||
|
|
|
@ -137,6 +137,7 @@ struct _NautilusPropertiesWindow
|
|||
GtkWidget *permissions_navigation_row;
|
||||
GtkWidget *permissions_value_label;
|
||||
|
||||
GtkWidget *extension_models_group;
|
||||
GtkWidget *extension_models_list_box;
|
||||
|
||||
/* Permissions page */
|
||||
|
@ -172,7 +173,7 @@ struct _NautilusPropertiesWindow
|
|||
OwnerChange *owner_change;
|
||||
|
||||
GList *permission_rows;
|
||||
GList *change_permission_drop_downs;
|
||||
GList *change_permission_combo_rows;
|
||||
GHashTable *initial_permissions;
|
||||
gboolean has_recursive_apply;
|
||||
|
||||
|
@ -544,7 +545,8 @@ get_image_for_properties_window (NautilusPropertiesWindow *self,
|
|||
|
||||
if (!icon)
|
||||
{
|
||||
g_autoptr (GIcon) gicon = g_themed_icon_new ("application-x-generic");
|
||||
g_autoptr (GIcon) gicon = g_themed_icon_new_from_names ((char *[]){"application-x-generic",
|
||||
"text-x-generic"}, 2);
|
||||
|
||||
icon = nautilus_icon_info_lookup (gicon, NAUTILUS_GRID_ICON_SIZE_MEDIUM, icon_scale);
|
||||
}
|
||||
|
@ -3039,7 +3041,7 @@ update_permission_row (AdwComboRow *row,
|
|||
}
|
||||
|
||||
static void
|
||||
setup_permissions_drop_down (GtkDropDown *drop_down,
|
||||
setup_permissions_combo_row (AdwComboRow *combo_row,
|
||||
PermissionType type,
|
||||
FilterType filter_type)
|
||||
{
|
||||
|
@ -3047,13 +3049,13 @@ setup_permissions_drop_down (GtkDropDown *drop_down,
|
|||
g_autoptr (GtkExpression) expression = NULL;
|
||||
|
||||
store = g_list_store_new (NAUTILUS_TYPE_PERMISSION_ENTRY);
|
||||
gtk_drop_down_set_model (drop_down, G_LIST_MODEL (store));
|
||||
adw_combo_row_set_model (combo_row, G_LIST_MODEL (store));
|
||||
expression = gtk_property_expression_new (NAUTILUS_TYPE_PERMISSION_ENTRY, NULL, "name");
|
||||
gtk_drop_down_set_expression (drop_down, expression);
|
||||
adw_combo_row_set_expression (combo_row, expression);
|
||||
|
||||
|
||||
g_object_set_data (G_OBJECT (drop_down), "filter-type", GINT_TO_POINTER (filter_type));
|
||||
g_object_set_data (G_OBJECT (drop_down), "permission-type", GINT_TO_POINTER (type));
|
||||
g_object_set_data (G_OBJECT (combo_row), "filter-type", GINT_TO_POINTER (filter_type));
|
||||
g_object_set_data (G_OBJECT (combo_row), "permission-type", GINT_TO_POINTER (type));
|
||||
|
||||
if (filter_type == FOLDERS_ONLY)
|
||||
{
|
||||
|
@ -3246,7 +3248,7 @@ on_change_permissions_response_cancel (AdwWindow *dialog,
|
|||
NautilusPropertiesWindow *self =
|
||||
NAUTILUS_PROPERTIES_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog)));
|
||||
|
||||
g_clear_pointer (&self->change_permission_drop_downs, g_list_free);
|
||||
g_clear_pointer (&self->change_permission_combo_rows, g_list_free);
|
||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||
}
|
||||
|
||||
|
@ -3266,18 +3268,18 @@ on_change_permissions_response_change (AdwWindow *dialog,
|
|||
int mask;
|
||||
|
||||
/* Simple mode, minus exec checkbox */
|
||||
for (l = self->change_permission_drop_downs; l != NULL; l = l->next)
|
||||
for (l = self->change_permission_combo_rows; l != NULL; l = l->next)
|
||||
{
|
||||
GtkDropDown *drop_down = l->data;
|
||||
NautilusPermissionEntry *selected = gtk_drop_down_get_selected_item (drop_down);
|
||||
AdwComboRow *combo_row = l->data;
|
||||
NautilusPermissionEntry *selected = adw_combo_row_get_selected_item (combo_row);
|
||||
|
||||
if (selected == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drop_down), "permission-type"));
|
||||
filter_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drop_down), "filter-type"));
|
||||
type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo_row), "permission-type"));
|
||||
filter_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo_row), "filter-type"));
|
||||
|
||||
vfs_new_perm = permission_to_vfs (type, selected->permission_value);
|
||||
|
||||
|
@ -3323,16 +3325,16 @@ on_change_permissions_response_change (AdwWindow *dialog,
|
|||
self);
|
||||
}
|
||||
}
|
||||
g_clear_pointer (&self->change_permission_drop_downs, g_list_free);
|
||||
g_clear_pointer (&self->change_permission_combo_rows, g_list_free);
|
||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
set_active_from_umask (GtkDropDown *drop_down,
|
||||
set_active_from_umask (AdwComboRow *combo_row,
|
||||
PermissionType type,
|
||||
FilterType filter_type)
|
||||
{
|
||||
GListModel *model = gtk_drop_down_get_model (drop_down);
|
||||
GListModel *model = adw_combo_row_get_model (combo_row);
|
||||
mode_t initial;
|
||||
mode_t mask;
|
||||
mode_t p;
|
||||
|
@ -3430,7 +3432,7 @@ set_active_from_umask (GtkDropDown *drop_down,
|
|||
|
||||
if (entry->permission_value == perm)
|
||||
{
|
||||
gtk_drop_down_set_selected (drop_down, i);
|
||||
adw_combo_row_set_selected (combo_row, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3450,7 +3452,7 @@ static void
|
|||
on_change_permissions_clicked (NautilusPropertiesWindow *self)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkDropDown *drop_down;
|
||||
AdwComboRow *combo_row;
|
||||
GtkButton *cancel_button, *change_button;
|
||||
GtkShortcut *esc_shortcut;
|
||||
GtkShortcutAction *cb_action;
|
||||
|
@ -3462,43 +3464,43 @@ on_change_permissions_clicked (NautilusPropertiesWindow *self)
|
|||
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (self));
|
||||
|
||||
/* Owner Permissions */
|
||||
drop_down = GTK_DROP_DOWN (gtk_builder_get_object (change_permissions_builder, "file_owner_drop_down"));
|
||||
setup_permissions_drop_down (drop_down, PERMISSION_USER, FILES_ONLY);
|
||||
self->change_permission_drop_downs = g_list_prepend (self->change_permission_drop_downs,
|
||||
drop_down);
|
||||
set_active_from_umask (drop_down, PERMISSION_USER, FILES_ONLY);
|
||||
combo_row = ADW_COMBO_ROW (gtk_builder_get_object (change_permissions_builder, "file_owner_combo_row"));
|
||||
setup_permissions_combo_row (combo_row, PERMISSION_USER, FILES_ONLY);
|
||||
self->change_permission_combo_rows = g_list_prepend (self->change_permission_combo_rows,
|
||||
combo_row);
|
||||
set_active_from_umask (combo_row, PERMISSION_USER, FILES_ONLY);
|
||||
|
||||
drop_down = GTK_DROP_DOWN (gtk_builder_get_object (change_permissions_builder, "folder_owner_drop_down"));
|
||||
setup_permissions_drop_down (drop_down, PERMISSION_USER, FOLDERS_ONLY);
|
||||
self->change_permission_drop_downs = g_list_prepend (self->change_permission_drop_downs,
|
||||
drop_down);
|
||||
set_active_from_umask (drop_down, PERMISSION_USER, FOLDERS_ONLY);
|
||||
combo_row = ADW_COMBO_ROW (gtk_builder_get_object (change_permissions_builder, "folder_owner_combo_row"));
|
||||
setup_permissions_combo_row (combo_row, PERMISSION_USER, FOLDERS_ONLY);
|
||||
self->change_permission_combo_rows = g_list_prepend (self->change_permission_combo_rows,
|
||||
combo_row);
|
||||
set_active_from_umask (combo_row, PERMISSION_USER, FOLDERS_ONLY);
|
||||
|
||||
/* Group Permissions */
|
||||
drop_down = GTK_DROP_DOWN (gtk_builder_get_object (change_permissions_builder, "file_group_drop_down"));
|
||||
setup_permissions_drop_down (drop_down, PERMISSION_GROUP, FILES_ONLY);
|
||||
self->change_permission_drop_downs = g_list_prepend (self->change_permission_drop_downs,
|
||||
drop_down);
|
||||
set_active_from_umask (drop_down, PERMISSION_GROUP, FILES_ONLY);
|
||||
combo_row = ADW_COMBO_ROW (gtk_builder_get_object (change_permissions_builder, "file_group_combo_row"));
|
||||
setup_permissions_combo_row (combo_row, PERMISSION_GROUP, FILES_ONLY);
|
||||
self->change_permission_combo_rows = g_list_prepend (self->change_permission_combo_rows,
|
||||
combo_row);
|
||||
set_active_from_umask (combo_row, PERMISSION_GROUP, FILES_ONLY);
|
||||
|
||||
drop_down = GTK_DROP_DOWN (gtk_builder_get_object (change_permissions_builder, "folder_group_drop_down"));
|
||||
setup_permissions_drop_down (drop_down, PERMISSION_GROUP, FOLDERS_ONLY);
|
||||
self->change_permission_drop_downs = g_list_prepend (self->change_permission_drop_downs,
|
||||
drop_down);
|
||||
set_active_from_umask (drop_down, PERMISSION_GROUP, FOLDERS_ONLY);
|
||||
combo_row = ADW_COMBO_ROW (gtk_builder_get_object (change_permissions_builder, "folder_group_combo_row"));
|
||||
setup_permissions_combo_row (combo_row, PERMISSION_GROUP, FOLDERS_ONLY);
|
||||
self->change_permission_combo_rows = g_list_prepend (self->change_permission_combo_rows,
|
||||
combo_row);
|
||||
set_active_from_umask (combo_row, PERMISSION_GROUP, FOLDERS_ONLY);
|
||||
|
||||
/* Others Permissions */
|
||||
drop_down = GTK_DROP_DOWN (gtk_builder_get_object (change_permissions_builder, "file_other_drop_down"));
|
||||
setup_permissions_drop_down (drop_down, PERMISSION_OTHER, FILES_ONLY);
|
||||
self->change_permission_drop_downs = g_list_prepend (self->change_permission_drop_downs,
|
||||
drop_down);
|
||||
set_active_from_umask (drop_down, PERMISSION_OTHER, FILES_ONLY);
|
||||
combo_row = ADW_COMBO_ROW (gtk_builder_get_object (change_permissions_builder, "file_other_combo_row"));
|
||||
setup_permissions_combo_row (combo_row, PERMISSION_OTHER, FILES_ONLY);
|
||||
self->change_permission_combo_rows = g_list_prepend (self->change_permission_combo_rows,
|
||||
combo_row);
|
||||
set_active_from_umask (combo_row, PERMISSION_OTHER, FILES_ONLY);
|
||||
|
||||
drop_down = GTK_DROP_DOWN (gtk_builder_get_object (change_permissions_builder, "folder_other_drop_down"));
|
||||
setup_permissions_drop_down (drop_down, PERMISSION_OTHER, FOLDERS_ONLY);
|
||||
self->change_permission_drop_downs = g_list_prepend (self->change_permission_drop_downs,
|
||||
drop_down);
|
||||
set_active_from_umask (drop_down, PERMISSION_OTHER, FOLDERS_ONLY);
|
||||
combo_row = ADW_COMBO_ROW (gtk_builder_get_object (change_permissions_builder, "folder_other_combo_row"));
|
||||
setup_permissions_combo_row (combo_row, PERMISSION_OTHER, FOLDERS_ONLY);
|
||||
self->change_permission_combo_rows = g_list_prepend (self->change_permission_combo_rows,
|
||||
combo_row);
|
||||
set_active_from_umask (combo_row, PERMISSION_OTHER, FOLDERS_ONLY);
|
||||
|
||||
cancel_button = GTK_BUTTON (gtk_builder_get_object (change_permissions_builder, "cancel_button"));
|
||||
change_button = GTK_BUTTON (gtk_builder_get_object (change_permissions_builder, "change_button"));
|
||||
|
@ -3587,7 +3589,7 @@ refresh_extension_model_pages (NautilusPropertiesWindow *self)
|
|||
g_list_store_append (extensions_list, NAUTILUS_PROPERTIES_MODEL (l->data));
|
||||
}
|
||||
|
||||
gtk_widget_set_visible (self->extension_models_list_box,
|
||||
gtk_widget_set_visible (self->extension_models_group,
|
||||
g_list_model_get_n_items (G_LIST_MODEL (extensions_list)) > 0);
|
||||
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (self->extension_models_list_box),
|
||||
|
@ -3995,7 +3997,7 @@ real_dispose (GObject *object)
|
|||
|
||||
g_clear_list (&self->permission_rows, NULL);
|
||||
|
||||
g_clear_list (&self->change_permission_drop_downs, NULL);
|
||||
g_clear_list (&self->change_permission_combo_rows, NULL);
|
||||
|
||||
g_clear_pointer (&self->initial_permissions, g_hash_table_destroy);
|
||||
|
||||
|
@ -4163,6 +4165,7 @@ nautilus_properties_window_class_init (NautilusPropertiesWindowClass *klass)
|
|||
gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, accessed_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, permissions_navigation_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, permissions_value_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, extension_models_group);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, extension_models_list_box);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, free_space_value_label);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusPropertiesWindow, permissions_stack);
|
||||
|
|
|
@ -91,8 +91,7 @@ update_fts_sensitivity (NautilusQueryEditor *editor)
|
|||
{
|
||||
g_autoptr (NautilusFile) file = nautilus_file_get (editor->location);
|
||||
|
||||
fts_sensitive = !nautilus_file_is_other_locations (file) &&
|
||||
!g_file_has_uri_scheme (editor->location, SCHEME_NETWORK) &&
|
||||
fts_sensitive = !g_file_has_uri_scheme (editor->location, SCHEME_NETWORK) &&
|
||||
!(nautilus_file_is_remote (file) &&
|
||||
location_settings_search_get_recursive_for_location (editor->location) == NAUTILUS_QUERY_RECURSIVE_NEVER);
|
||||
nautilus_search_popover_set_fts_sensitive (NAUTILUS_SEARCH_POPOVER (editor->popover),
|
||||
|
|
449
src/nautilus-recent-servers.c
Normal file
449
src/nautilus-recent-servers.c
Normal file
|
@ -0,0 +1,449 @@
|
|||
/* nautilusgtkplacesview.c
|
||||
*
|
||||
* Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "nautilus-recent-servers.h"
|
||||
|
||||
struct _NautilusRecentServers
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GHashTable *server_infos;
|
||||
|
||||
GFileMonitor *server_list_monitor;
|
||||
|
||||
guint idle_reload_id;
|
||||
|
||||
guint loading : 1;
|
||||
};
|
||||
|
||||
static void nautilus_recent_servers_set_loading (NautilusRecentServers *self,
|
||||
gboolean loading);
|
||||
|
||||
G_DEFINE_TYPE (NautilusRecentServers, nautilus_recent_servers, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_LOADING,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ADDED,
|
||||
CHANGED,
|
||||
REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static GParamSpec *properties[LAST_PROP];
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void
|
||||
ensure_monitor (NautilusRecentServers *self)
|
||||
{
|
||||
if (self->server_list_monitor != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_autofree char *filename = g_build_filename (g_get_user_config_dir (), "gtk-4.0", "servers", NULL);
|
||||
g_autoptr (GFile) server_list_file = g_file_new_for_path (filename);
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
self->server_list_monitor = g_file_monitor_file (server_list_file,
|
||||
G_FILE_MONITOR_NONE,
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
g_warning ("Cannot monitor server file: %s", error->message);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_signal_connect_object (self->server_list_monitor, "changed",
|
||||
G_CALLBACK (nautilus_recent_servers_force_reload), self,
|
||||
G_CONNECT_SWAPPED);
|
||||
}
|
||||
}
|
||||
|
||||
static GBookmarkFile *
|
||||
server_list_load (void)
|
||||
{
|
||||
GBookmarkFile *bookmarks;
|
||||
GError *error = NULL;
|
||||
char *datadir;
|
||||
char *filename;
|
||||
|
||||
bookmarks = g_bookmark_file_new ();
|
||||
datadir = g_build_filename (g_get_user_config_dir (), "gtk-4.0", NULL);
|
||||
filename = g_build_filename (datadir, "servers", NULL);
|
||||
|
||||
g_mkdir_with_parents (datadir, 0700);
|
||||
g_bookmark_file_load_from_file (bookmarks, filename, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
|
||||
{
|
||||
/* only warn if the file exists */
|
||||
g_warning ("Unable to open server bookmarks: %s", error->message);
|
||||
g_clear_pointer (&bookmarks, g_bookmark_file_free);
|
||||
}
|
||||
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
g_free (datadir);
|
||||
g_free (filename);
|
||||
|
||||
return bookmarks;
|
||||
}
|
||||
|
||||
static void
|
||||
server_list_save (GBookmarkFile *bookmarks)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = g_build_filename (g_get_user_config_dir (), "gtk-4.0", "servers", NULL);
|
||||
g_bookmark_file_to_file (bookmarks, filename, NULL);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_add_recent_server (GFile *file)
|
||||
{
|
||||
GBookmarkFile *bookmarks;
|
||||
GFileInfo *info;
|
||||
GError *error;
|
||||
char *title;
|
||||
char *uri;
|
||||
|
||||
GDateTime *now;
|
||||
|
||||
error = NULL;
|
||||
bookmarks = server_list_load ();
|
||||
|
||||
if (!bookmarks)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
|
||||
info = g_file_query_info (file,
|
||||
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL,
|
||||
&error);
|
||||
title = g_file_info_get_attribute_as_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
|
||||
|
||||
g_bookmark_file_set_title (bookmarks, uri, title);
|
||||
now = g_date_time_new_now_utc ();
|
||||
g_bookmark_file_set_visited_date_time (bookmarks, uri, now);
|
||||
g_date_time_unref (now);
|
||||
g_bookmark_file_add_application (bookmarks, uri, NULL, NULL);
|
||||
|
||||
server_list_save (bookmarks);
|
||||
|
||||
g_bookmark_file_free (bookmarks);
|
||||
g_clear_object (&info);
|
||||
g_free (title);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_remove_recent_server (const char *uri)
|
||||
{
|
||||
GBookmarkFile *bookmarks;
|
||||
|
||||
bookmarks = server_list_load ();
|
||||
|
||||
if (!bookmarks)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_bookmark_file_remove_item (bookmarks, uri, NULL);
|
||||
server_list_save (bookmarks);
|
||||
|
||||
g_bookmark_file_free (bookmarks);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_recent_servers_finalize (GObject *object)
|
||||
{
|
||||
NautilusRecentServers *self = (NautilusRecentServers *) object;
|
||||
|
||||
g_clear_object (&self->server_list_monitor);
|
||||
g_clear_pointer (&self->server_infos, g_hash_table_destroy);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_recent_servers_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_recent_servers_dispose (GObject *object)
|
||||
{
|
||||
NautilusRecentServers *self = (NautilusRecentServers *) object;
|
||||
|
||||
g_clear_handle_id (&self->idle_reload_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (nautilus_recent_servers_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_recent_servers_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
NautilusRecentServers *self = NAUTILUS_RECENT_SERVERS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LOADING:
|
||||
{
|
||||
g_value_set_boolean (value, nautilus_recent_servers_get_loading (self));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GFileInfo *
|
||||
server_file_info_new (const char *uri)
|
||||
{
|
||||
GFileInfo *info = g_file_info_new ();
|
||||
g_autofree char *random_name = g_dbus_generate_guid ();
|
||||
g_autoptr (GIcon) icon = g_themed_icon_new ("folder-remote");
|
||||
g_autoptr (GIcon) symbolic_icon = g_themed_icon_new ("folder-remote-symbolic");
|
||||
|
||||
g_file_info_set_name (info, random_name);
|
||||
g_file_info_set_icon (info, icon);
|
||||
g_file_info_set_symbolic_icon (info, symbolic_icon);
|
||||
g_file_info_set_content_type (info, "inode/directory");
|
||||
g_file_info_set_file_type (info, G_FILE_TYPE_SHORTCUT);
|
||||
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL, TRUE);
|
||||
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE);
|
||||
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, FALSE);
|
||||
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE);
|
||||
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE);
|
||||
|
||||
g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, uri);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static int
|
||||
_date_time_equal_steal_1st (GDateTime *date_time1__to_be_stolen,
|
||||
GDateTime *date_time2)
|
||||
{
|
||||
g_autoptr (GDateTime) date_time1 = date_time1__to_be_stolen;
|
||||
|
||||
return ((date_time1 == NULL && date_time2 == NULL) ||
|
||||
g_date_time_equal (date_time1, date_time2));
|
||||
}
|
||||
|
||||
static void
|
||||
populate_servers_on_idle (gpointer user_data)
|
||||
{
|
||||
NautilusRecentServers *self = NAUTILUS_RECENT_SERVERS (user_data);
|
||||
GBookmarkFile *server_list;
|
||||
char **uris;
|
||||
gsize num_uris;
|
||||
|
||||
self->idle_reload_id = 0;
|
||||
|
||||
server_list = server_list_load ();
|
||||
|
||||
if (!server_list)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Monitor the file in case it's modified outside this code */
|
||||
ensure_monitor (self);
|
||||
|
||||
uris = g_bookmark_file_get_uris (server_list, &num_uris);
|
||||
|
||||
if (!uris)
|
||||
{
|
||||
g_bookmark_file_free (server_list);
|
||||
nautilus_recent_servers_set_loading (self, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
g_autoptr (GList) old_infos = g_hash_table_get_values (self->server_infos);
|
||||
g_autoptr (GList) new_infos = NULL;
|
||||
g_autoptr (GList) changed_infos = NULL;
|
||||
|
||||
for (gsize i = 0; i < num_uris; i++)
|
||||
{
|
||||
const gchar *uri = uris[i];
|
||||
GFileInfo *info = g_hash_table_lookup (self->server_infos, uri);
|
||||
gboolean new = FALSE;
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
old_infos = g_list_remove (old_infos, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
new = TRUE;
|
||||
info = server_file_info_new (uri);
|
||||
g_hash_table_insert (self->server_infos, g_strdup (uri), info);
|
||||
new_infos = g_list_prepend (new_infos, info);
|
||||
}
|
||||
|
||||
g_autofree char *name = g_bookmark_file_get_title (server_list, uri, NULL);
|
||||
GDateTime *added = g_bookmark_file_get_added_date_time (server_list, uri, NULL);
|
||||
GDateTime *visited = g_bookmark_file_get_visited_date_time (server_list, uri, NULL);
|
||||
GDateTime *modified = g_bookmark_file_get_modified_date_time (server_list, uri, NULL);
|
||||
|
||||
if (new ||
|
||||
g_strcmp0 (g_file_info_get_display_name (info), name) != 0 ||
|
||||
!_date_time_equal_steal_1st (g_file_info_get_creation_date_time (info), added) ||
|
||||
!_date_time_equal_steal_1st (g_file_info_get_access_date_time (info), visited) ||
|
||||
!_date_time_equal_steal_1st (g_file_info_get_modification_date_time (info), modified))
|
||||
{
|
||||
g_file_info_set_display_name (info, name);
|
||||
g_file_info_set_creation_date_time (info, added);
|
||||
g_file_info_set_access_date_time (info, visited);
|
||||
g_file_info_set_modification_date_time (info, modified);
|
||||
|
||||
if (!new)
|
||||
{
|
||||
changed_infos = g_list_prepend (changed_infos, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (old_infos != NULL)
|
||||
{
|
||||
g_signal_emit (self, signals[REMOVED], 0, old_infos);
|
||||
}
|
||||
if (changed_infos != NULL)
|
||||
{
|
||||
g_signal_emit (self, signals[CHANGED], 0, changed_infos);
|
||||
}
|
||||
if (new_infos != NULL)
|
||||
{
|
||||
g_signal_emit (self, signals[ADDED], 0, new_infos);
|
||||
}
|
||||
|
||||
for (GList *l = old_infos; l != NULL; l = l->next)
|
||||
{
|
||||
const char *old_uri = g_file_info_get_attribute_string (l->data, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
|
||||
|
||||
g_hash_table_remove (self->server_infos, old_uri);
|
||||
}
|
||||
|
||||
nautilus_recent_servers_set_loading (self, FALSE);
|
||||
|
||||
g_strfreev (uris);
|
||||
g_bookmark_file_free (server_list);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_recent_servers_class_init (NautilusRecentServersClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = nautilus_recent_servers_finalize;
|
||||
object_class->dispose = nautilus_recent_servers_dispose;
|
||||
object_class->get_property = nautilus_recent_servers_get_property;
|
||||
|
||||
properties[PROP_LOADING] =
|
||||
g_param_spec_boolean ("loading",
|
||||
"Loading",
|
||||
"Whether the view is loading locations",
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
|
||||
signals[ADDED] = g_signal_new ("added",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
signals[CHANGED] = g_signal_new ("changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
signals[REMOVED] = g_signal_new ("removed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_recent_servers_init (NautilusRecentServers *self)
|
||||
{
|
||||
self->server_infos = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
}
|
||||
|
||||
NautilusRecentServers *
|
||||
nautilus_recent_servers_new (void)
|
||||
{
|
||||
return g_object_new (NAUTILUS_TYPE_RECENT_SERVERS, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_recent_servers_force_reload (NautilusRecentServers *self)
|
||||
{
|
||||
if (self->idle_reload_id == 0)
|
||||
{
|
||||
self->idle_reload_id = g_idle_add_once (populate_servers_on_idle, self);
|
||||
nautilus_recent_servers_set_loading (self, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns: (transfer full): List of server infos. */
|
||||
GList *
|
||||
nautilus_recent_servers_get_infos (NautilusRecentServers *self)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_RECENT_SERVERS (self), FALSE);
|
||||
|
||||
GList *server_infos = g_hash_table_get_values (self->server_infos);
|
||||
|
||||
g_list_foreach (server_infos, (GFunc) g_object_ref, NULL);
|
||||
return server_infos;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nautilus_recent_servers_get_loading (NautilusRecentServers *self)
|
||||
{
|
||||
g_return_val_if_fail (NAUTILUS_IS_RECENT_SERVERS (self), FALSE);
|
||||
|
||||
return self->loading;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_recent_servers_set_loading (NautilusRecentServers *self,
|
||||
gboolean loading)
|
||||
{
|
||||
g_return_if_fail (NAUTILUS_IS_RECENT_SERVERS (self));
|
||||
|
||||
if (self->loading != loading)
|
||||
{
|
||||
self->loading = loading;
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_LOADING]);
|
||||
}
|
||||
}
|
27
src/nautilus-recent-servers.h
Normal file
27
src/nautilus-recent-servers.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2024 António Fernandes <antoniof@gnome.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_RECENT_SERVERS (nautilus_recent_servers_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusRecentServers, nautilus_recent_servers, NAUTILUS, RECENT_SERVERS, GObject);
|
||||
|
||||
NautilusRecentServers* nautilus_recent_servers_new (void);
|
||||
|
||||
void nautilus_recent_servers_force_reload (NautilusRecentServers *self);
|
||||
GList * nautilus_recent_servers_get_infos (NautilusRecentServers *self);
|
||||
gboolean nautilus_recent_servers_get_loading (NautilusRecentServers *self);
|
||||
|
||||
void nautilus_add_recent_server (GFile *file);
|
||||
|
||||
void nautilus_remove_recent_server (const char *uri);
|
||||
|
||||
G_END_DECLS
|
|
@ -12,8 +12,8 @@ gboolean
|
|||
nautilus_scheme_is_internal (const char *scheme)
|
||||
{
|
||||
return g_str_equal (scheme, SCHEME_BURN) ||
|
||||
g_str_equal (scheme, SCHEME_OTHER_LOCATIONS) ||
|
||||
g_str_equal (scheme, SCHEME_NETWORK) ||
|
||||
g_str_equal (scheme, SCHEME_NETWORK_VIEW) ||
|
||||
g_str_equal (scheme, SCHEME_RECENT) ||
|
||||
g_str_equal (scheme, SCHEME_SEARCH) ||
|
||||
g_str_equal (scheme, SCHEME_STARRED) ||
|
||||
|
|
|
@ -10,9 +10,10 @@
|
|||
|
||||
#define SCHEME_ADMIN "admin"
|
||||
#define SCHEME_BURN "burn"
|
||||
#define SCHEME_COMPUTER "computer"
|
||||
#define SCHEME_SEARCH "x-nautilus-search"
|
||||
#define SCHEME_OTHER_LOCATIONS "other-locations"
|
||||
#define SCHEME_NETWORK "network"
|
||||
#define SCHEME_NETWORK_VIEW "x-network-view"
|
||||
#define SCHEME_RECENT "recent"
|
||||
#define SCHEME_STARRED "starred"
|
||||
#define SCHEME_TRASH "trash"
|
||||
|
|
|
@ -171,12 +171,6 @@ search_directory_file_get_deep_counts (NautilusFile *file,
|
|||
return NAUTILUS_REQUEST_DONE;
|
||||
}
|
||||
|
||||
static char *
|
||||
search_directory_file_get_where_string (NautilusFile *file)
|
||||
{
|
||||
return g_strdup (_("Search"));
|
||||
}
|
||||
|
||||
static void
|
||||
search_directory_file_set_metadata (NautilusFile *file,
|
||||
const char *key,
|
||||
|
@ -303,7 +297,6 @@ nautilus_search_directory_file_class_init (NautilusSearchDirectoryFileClass *kla
|
|||
file_class->check_if_ready = search_directory_file_check_if_ready;
|
||||
file_class->get_item_count = search_directory_file_get_item_count;
|
||||
file_class->get_deep_counts = search_directory_file_get_deep_counts;
|
||||
file_class->get_where_string = search_directory_file_get_where_string;
|
||||
file_class->set_metadata = search_directory_file_set_metadata;
|
||||
file_class->set_metadata_as_list = search_directory_file_set_metadata_as_list;
|
||||
}
|
||||
|
|
|
@ -691,6 +691,24 @@ search_engine_finished (NautilusSearchEngine *engine,
|
|||
}
|
||||
}
|
||||
|
||||
static NautilusFile *
|
||||
search_new_file_from_filename (NautilusDirectory *directory,
|
||||
const char *filename,
|
||||
gboolean self_owned)
|
||||
{
|
||||
if (!self_owned)
|
||||
{
|
||||
/* This doesn't normally happen, unless the user somehow types in a uri
|
||||
* that references a file like this.
|
||||
* See https://bugzilla.gnome.org/show_bug.cgi?id=349840 */
|
||||
return NAUTILUS_DIRECTORY_CLASS (nautilus_search_directory_parent_class)->new_file_from_filename (directory, filename, self_owned);
|
||||
}
|
||||
|
||||
return NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_SEARCH_DIRECTORY_FILE,
|
||||
"directory", directory,
|
||||
NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
search_force_reload (NautilusDirectory *directory)
|
||||
{
|
||||
|
@ -929,6 +947,8 @@ nautilus_search_directory_class_init (NautilusSearchDirectoryClass *class)
|
|||
oclass->get_property = search_get_property;
|
||||
oclass->set_property = search_set_property;
|
||||
|
||||
directory_class->new_file_from_filename = search_new_file_from_filename;
|
||||
|
||||
directory_class->are_all_files_seen = search_are_all_files_seen;
|
||||
directory_class->contains_file = search_contains_file;
|
||||
directory_class->force_reload = search_force_reload;
|
||||
|
|
52
src/nautilus-shortcut-manager.c
Normal file
52
src/nautilus-shortcut-manager.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2024 GNOME Foundation Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#include "nautilus-shortcut-manager.h"
|
||||
|
||||
|
||||
/**
|
||||
* NautilusShortcutManager:
|
||||
*
|
||||
* A bin container to limit the scope of GTK_SHORTCUT_SCOPE_MANAGED shortcuts.
|
||||
*
|
||||
* The primary use case is to prevent keyboard shortcuts from being triggered
|
||||
* while `AdwDialog`s are presented. This assumes an implementation detail: that
|
||||
* `AdwDialog`s are internally children of `AdwWindow`/`AdwApplicationWindow`,
|
||||
* but not children of `AdwWindow:child`/`AdwApplicationWindow:child`.
|
||||
*
|
||||
* This is simply an AdwBin augmented with the GtkShortcutManager interface. The
|
||||
* default implementation of the interface is sufficient for the purpose.
|
||||
*/
|
||||
struct _NautilusShortcutManager
|
||||
{
|
||||
AdwBin parent_instance;
|
||||
};
|
||||
|
||||
static void
|
||||
nautilus_shortcut_manager_interface_init (GtkShortcutManagerInterface *iface)
|
||||
{
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (NautilusShortcutManager, nautilus_shortcut_manager, ADW_TYPE_BIN,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_SHORTCUT_MANAGER,
|
||||
nautilus_shortcut_manager_interface_init))
|
||||
|
||||
static void
|
||||
nautilus_shortcut_manager_class_init (NautilusShortcutManagerClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_shortcut_manager_init (NautilusShortcutManager *self)
|
||||
{
|
||||
}
|
||||
|
||||
NautilusShortcutManager *
|
||||
nautilus_shortcut_manager_new (void)
|
||||
{
|
||||
return g_object_new (NAUTILUS_TYPE_SHORTCUT_MANAGER, NULL);
|
||||
}
|
20
src/nautilus-shortcut-manager.h
Normal file
20
src/nautilus-shortcut-manager.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (C) 2024 GNOME Foundation Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NAUTILUS_TYPE_SHORTCUT_MANAGER (nautilus_shortcut_manager_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (NautilusShortcutManager, nautilus_shortcut_manager, NAUTILUS, SHORTCUT_MANAGER, AdwBin)
|
||||
|
||||
NautilusShortcutManager * nautilus_shortcut_manager_new (void);
|
||||
|
||||
G_END_DECLS
|
|
@ -17,9 +17,12 @@
|
|||
*/
|
||||
|
||||
#include "nautilus-starred-directory.h"
|
||||
#include "nautilus-tag-manager.h"
|
||||
#include "nautilus-file-utilities.h"
|
||||
|
||||
#include "nautilus-directory-private.h"
|
||||
#include "nautilus-file-private.h"
|
||||
#include "nautilus-file-utilities.h"
|
||||
#include "nautilus-internal-place-file.h"
|
||||
#include "nautilus-tag-manager.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
|
@ -176,6 +179,22 @@ on_starred_files_changed (NautilusTagManager *tag_manager,
|
|||
nautilus_starred_directory_update_files (self, changed_files);
|
||||
}
|
||||
|
||||
static NautilusFile *
|
||||
real_new_file_from_filename (NautilusDirectory *directory,
|
||||
const char *filename,
|
||||
gboolean self_owned)
|
||||
{
|
||||
if (!self_owned)
|
||||
{
|
||||
g_warning ("Creating a file within starred://. This shouldn't happen.");
|
||||
return NAUTILUS_DIRECTORY_CLASS (nautilus_starred_directory_parent_class)->new_file_from_filename (directory, filename, self_owned);
|
||||
}
|
||||
|
||||
return NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_INTERNAL_PLACE_FILE,
|
||||
"directory", directory,
|
||||
NULL));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_contains_file (NautilusDirectory *directory,
|
||||
NautilusFile *file)
|
||||
|
@ -499,6 +518,7 @@ nautilus_starred_directory_class_init (NautilusFavoriteDirectoryClass *klass)
|
|||
oclass->finalize = nautilus_starred_directory_finalize;
|
||||
oclass->dispose = nautilus_starred_directory_dispose;
|
||||
|
||||
directory_class->new_file_from_filename = real_new_file_from_filename;
|
||||
directory_class->handles_location = real_handles_location;
|
||||
directory_class->contains_file = real_contains_file;
|
||||
directory_class->is_editable = real_is_editable;
|
||||
|
|
|
@ -719,6 +719,17 @@ nautilus_tag_manager_can_star_contents (NautilusTagManager *self,
|
|||
return g_file_has_prefix (directory, self->home) || g_file_equal (directory, self->home);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nautilus_tag_manager_can_star_location (NautilusTagManager *self,
|
||||
GFile *directory)
|
||||
{
|
||||
/* We only allow files to be starred inside the home directory for now.
|
||||
* This avoids the starred files database growing too big.
|
||||
* See https://gitlab.gnome.org/GNOME/nautilus/-/merge_requests/553#note_903108
|
||||
*/
|
||||
return g_file_has_prefix (directory, self->home);
|
||||
}
|
||||
|
||||
static void
|
||||
update_moved_uris_callback (GObject *object,
|
||||
GAsyncResult *result,
|
||||
|
@ -944,7 +955,7 @@ child_watch_cb (GPid pid,
|
|||
static void
|
||||
export_tracker2_data (NautilusTagManager *self)
|
||||
{
|
||||
gchar *argv[] = {"tracker3", "export", "--2to3", "files-starred", "--keyfile", NULL};
|
||||
gchar *argv[] = {"tinysparql3", "export", "--2to3", "files-starred", "--keyfile", NULL};
|
||||
gint stdout_fd;
|
||||
GPid child_pid;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
@ -968,7 +979,7 @@ export_tracker2_data (NautilusTagManager *self)
|
|||
&error);
|
||||
if (!success)
|
||||
{
|
||||
g_warning ("Tracker 2 migration: Couldn't run `tracker3`: %s", error->message);
|
||||
g_warning ("Tracker 2 migration: Couldn't run `tinysparql3`: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@ gboolean nautilus_tag_manager_file_is_starred (NautilusTagManager *
|
|||
|
||||
gboolean nautilus_tag_manager_can_star_contents (NautilusTagManager *self,
|
||||
GFile *directory);
|
||||
gboolean nautilus_tag_manager_can_star_location (NautilusTagManager *self,
|
||||
GFile *directory);
|
||||
|
||||
void nautilus_tag_manager_update_moved_uris (NautilusTagManager *tag_manager,
|
||||
GFile *src,
|
||||
GFile *dest);
|
||||
|
|
|
@ -33,18 +33,14 @@
|
|||
#include "nautilus-pathbar.h"
|
||||
#include "nautilus-view-controls.h"
|
||||
#include "nautilus-ui-utilities.h"
|
||||
#include "nautilus-window.h"
|
||||
|
||||
struct _NautilusToolbar
|
||||
{
|
||||
AdwBin parent_instance;
|
||||
|
||||
NautilusWindow *window;
|
||||
|
||||
GtkWidget *history_controls_stack;
|
||||
GtkWidget *history_controls;
|
||||
GtkWidget *history_controls_placeholder;
|
||||
GtkWidget *path_bar_container;
|
||||
GtkWidget *location_entry_container;
|
||||
GtkWidget *search_container;
|
||||
GtkWidget *toolbar_switcher;
|
||||
|
@ -55,6 +51,7 @@ struct _NautilusToolbar
|
|||
GtkWidget *search_button_placeholder;
|
||||
|
||||
gboolean show_location_entry;
|
||||
GtkWidget *focus_before_location_entry;
|
||||
|
||||
GtkWidget *sidebar_button;
|
||||
gboolean show_sidebar_button;
|
||||
|
@ -62,8 +59,6 @@ struct _NautilusToolbar
|
|||
|
||||
gboolean show_toolbar_children;
|
||||
|
||||
GtkWidget *location_entry_close_button;
|
||||
|
||||
/* active slot & bindings */
|
||||
NautilusWindowSlot *window_slot;
|
||||
};
|
||||
|
@ -71,7 +66,6 @@ struct _NautilusToolbar
|
|||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_SHOW_LOCATION_ENTRY,
|
||||
PROP_WINDOW_SLOT,
|
||||
PROP_SHOW_SIDEBAR_BUTTON,
|
||||
PROP_SIDEBAR_BUTTON_ACTIVE,
|
||||
|
@ -117,11 +111,70 @@ toolbar_update_appearance (NautilusToolbar *self)
|
|||
search_global ? self->history_controls_placeholder : self->history_controls);
|
||||
}
|
||||
|
||||
static void
|
||||
on_location_entry_close (GtkWidget *close_button,
|
||||
NautilusToolbar *self)
|
||||
void
|
||||
nautilus_toolbar_open_location_entry (NautilusToolbar *self,
|
||||
const char *special_text)
|
||||
{
|
||||
nautilus_toolbar_set_show_location_entry (self, FALSE);
|
||||
if (self->show_location_entry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remember focus widget. */
|
||||
GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
GtkWidget *focus_widget = (root != NULL) ? gtk_root_get_focus (root) : NULL;
|
||||
|
||||
g_set_weak_pointer (&self->focus_before_location_entry, focus_widget);
|
||||
|
||||
self->show_location_entry = TRUE;
|
||||
toolbar_update_appearance (self);
|
||||
|
||||
gtk_widget_grab_focus (self->location_entry);
|
||||
|
||||
if (special_text != NULL)
|
||||
{
|
||||
nautilus_location_entry_set_special_text (NAUTILUS_LOCATION_ENTRY (self->location_entry),
|
||||
special_text);
|
||||
gtk_editable_set_position (GTK_EDITABLE (self->location_entry), -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_toolbar_close_location_entry (NautilusToolbar *self)
|
||||
{
|
||||
if (!self->show_location_entry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->show_location_entry = FALSE;
|
||||
toolbar_update_appearance (self);
|
||||
|
||||
if (self->focus_before_location_entry != NULL)
|
||||
{
|
||||
/* Restore focus widget. */
|
||||
gtk_widget_grab_focus (self->focus_before_location_entry);
|
||||
g_clear_weak_pointer (&self->focus_before_location_entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_path_bar_open_location (NautilusPathBar *path_bar,
|
||||
GFile *location,
|
||||
NautilusOpenFlags open_flags,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusToolbar *self = NAUTILUS_TOOLBAR (user_data);
|
||||
|
||||
if (open_flags & (NAUTILUS_OPEN_FLAG_NEW_WINDOW | NAUTILUS_OPEN_FLAG_NEW_TAB))
|
||||
{
|
||||
nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()),
|
||||
location, open_flags, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
nautilus_window_slot_open_location_full (self->window_slot, location, open_flags, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -149,39 +202,18 @@ on_location_entry_focus_leave (GtkEventControllerFocus *controller,
|
|||
return;
|
||||
}
|
||||
|
||||
nautilus_toolbar_set_show_location_entry (toolbar, FALSE);
|
||||
nautilus_toolbar_close_location_entry (toolbar);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_toolbar_constructed (GObject *object)
|
||||
on_location_entry_location_changed (NautilusLocationEntry *entry,
|
||||
GFile *location,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusToolbar *self = NAUTILUS_TOOLBAR (object);
|
||||
GtkEventController *controller;
|
||||
NautilusToolbar *self = NAUTILUS_TOOLBAR (user_data);
|
||||
|
||||
self->path_bar = GTK_WIDGET (g_object_new (NAUTILUS_TYPE_PATH_BAR, NULL));
|
||||
gtk_box_append (GTK_BOX (self->path_bar_container),
|
||||
self->path_bar);
|
||||
|
||||
self->location_entry = nautilus_location_entry_new ();
|
||||
gtk_box_append (GTK_BOX (self->location_entry_container),
|
||||
self->location_entry);
|
||||
self->location_entry_close_button = gtk_button_new_from_icon_name ("window-close-symbolic");
|
||||
gtk_widget_set_tooltip_text (self->location_entry_close_button, _("Cancel"));
|
||||
gtk_box_append (GTK_BOX (self->location_entry_container),
|
||||
self->location_entry_close_button);
|
||||
g_signal_connect (self->location_entry_close_button, "clicked",
|
||||
G_CALLBACK (on_location_entry_close), self);
|
||||
|
||||
controller = gtk_event_controller_focus_new ();
|
||||
gtk_widget_add_controller (self->location_entry, controller);
|
||||
g_signal_connect (controller, "leave",
|
||||
G_CALLBACK (on_location_entry_focus_leave), self);
|
||||
|
||||
/* Setting a max width on one entry to effectively set a max expansion for
|
||||
* the whole title widget. */
|
||||
gtk_editable_set_max_width_chars (GTK_EDITABLE (self->location_entry), 88);
|
||||
|
||||
toolbar_update_appearance (self);
|
||||
nautilus_toolbar_close_location_entry (self);
|
||||
nautilus_window_slot_open_location_full (self->window_slot, location, 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -189,8 +221,34 @@ nautilus_toolbar_init (NautilusToolbar *self)
|
|||
{
|
||||
g_type_ensure (NAUTILUS_TYPE_HISTORY_CONTROLS);
|
||||
g_type_ensure (NAUTILUS_TYPE_VIEW_CONTROLS);
|
||||
g_type_ensure (NAUTILUS_TYPE_PATH_BAR);
|
||||
g_type_ensure (NAUTILUS_TYPE_LOCATION_ENTRY);
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
/* Setup path bar */
|
||||
g_signal_connect_object (self->path_bar, "open-location",
|
||||
G_CALLBACK (on_path_bar_open_location), self,
|
||||
G_CONNECT_DEFAULT);
|
||||
|
||||
/* Setup location entry */
|
||||
GtkEventController *controller = gtk_event_controller_focus_new ();
|
||||
|
||||
gtk_widget_add_controller (self->location_entry, controller);
|
||||
g_signal_connect (controller, "leave",
|
||||
G_CALLBACK (on_location_entry_focus_leave), self);
|
||||
|
||||
/* Setting a max width on one entry to effectively set a max expansion for
|
||||
* the whole title widget. */
|
||||
gtk_editable_set_max_width_chars (GTK_EDITABLE (self->location_entry), 88);
|
||||
g_signal_connect_object (self->location_entry, "location-changed",
|
||||
G_CALLBACK (on_location_entry_location_changed), self,
|
||||
G_CONNECT_DEFAULT);
|
||||
g_signal_connect_object (self->location_entry, "cancel",
|
||||
G_CALLBACK (nautilus_toolbar_close_location_entry), self,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
toolbar_update_appearance (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -203,12 +261,6 @@ nautilus_toolbar_get_property (GObject *object,
|
|||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_SHOW_LOCATION_ENTRY:
|
||||
{
|
||||
g_value_set_boolean (value, self->show_location_entry);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_WINDOW_SLOT:
|
||||
{
|
||||
g_value_set_object (value, self->window_slot);
|
||||
|
@ -262,12 +314,6 @@ nautilus_toolbar_set_property (GObject *object,
|
|||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_SHOW_LOCATION_ENTRY:
|
||||
{
|
||||
nautilus_toolbar_set_show_location_entry (self, g_value_get_boolean (value));
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_WINDOW_SLOT:
|
||||
{
|
||||
nautilus_toolbar_set_window_slot (self, g_value_get_object (value));
|
||||
|
@ -316,6 +362,8 @@ nautilus_toolbar_finalize (GObject *obj)
|
|||
{
|
||||
NautilusToolbar *self = NAUTILUS_TOOLBAR (obj);
|
||||
|
||||
g_clear_weak_pointer (&self->focus_before_location_entry);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (nautilus_preferences,
|
||||
toolbar_update_appearance, self);
|
||||
|
||||
|
@ -342,14 +390,6 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
|
|||
oclass->set_property = nautilus_toolbar_set_property;
|
||||
oclass->dispose = nautilus_toolbar_dispose;
|
||||
oclass->finalize = nautilus_toolbar_finalize;
|
||||
oclass->constructed = nautilus_toolbar_constructed;
|
||||
|
||||
properties[PROP_SHOW_LOCATION_ENTRY] =
|
||||
g_param_spec_boolean ("show-location-entry",
|
||||
"Whether to show the location entry",
|
||||
"Whether to show the location entry instead of the pathbar",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties [PROP_WINDOW_SLOT] =
|
||||
g_param_spec_object ("window-slot",
|
||||
|
@ -379,12 +419,14 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
|
|||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, history_controls_placeholder);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, toolbar_switcher);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, search_container);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, path_bar_container);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, location_entry_container);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, path_bar);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, location_entry);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, search_button_stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, search_button);
|
||||
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, search_button_placeholder);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, nautilus_toolbar_close_location_entry);
|
||||
|
||||
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_TOOLBAR);
|
||||
}
|
||||
|
||||
|
@ -395,31 +437,6 @@ nautilus_toolbar_new (void)
|
|||
NULL);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
nautilus_toolbar_get_path_bar (NautilusToolbar *self)
|
||||
{
|
||||
return self->path_bar;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
nautilus_toolbar_get_location_entry (NautilusToolbar *self)
|
||||
{
|
||||
return self->location_entry;
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_toolbar_set_show_location_entry (NautilusToolbar *self,
|
||||
gboolean show_location_entry)
|
||||
{
|
||||
if (show_location_entry != self->show_location_entry)
|
||||
{
|
||||
self->show_location_entry = show_location_entry;
|
||||
toolbar_update_appearance (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHOW_LOCATION_ENTRY]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
box_remove_all_children (GtkBox *box)
|
||||
{
|
||||
|
@ -430,6 +447,22 @@ box_remove_all_children (GtkBox *box)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_slot_location_changed (NautilusToolbar *self)
|
||||
{
|
||||
g_assert (self->window_slot != NULL);
|
||||
|
||||
GFile *location = nautilus_window_slot_get_location (self->window_slot);
|
||||
|
||||
if (location == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nautilus_location_entry_set_location (NAUTILUS_LOCATION_ENTRY (self->location_entry), location);
|
||||
nautilus_path_bar_set_path (NAUTILUS_PATH_BAR (self->path_bar), location);
|
||||
}
|
||||
|
||||
static void
|
||||
slot_on_extensions_background_menu_changed (NautilusToolbar *self,
|
||||
GParamSpec *param,
|
||||
|
@ -454,6 +487,12 @@ slot_on_templates_menu_changed (NautilusToolbar *self,
|
|||
menu);
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_toolbar_show_current_location_menu (NautilusToolbar *self)
|
||||
{
|
||||
nautilus_path_bar_show_current_location_menu (NAUTILUS_PATH_BAR (self->path_bar));
|
||||
}
|
||||
|
||||
/* Called from on_window_slot_destroyed(), since bindings and signal handlers
|
||||
* are automatically removed once the slot goes away.
|
||||
*/
|
||||
|
@ -461,8 +500,6 @@ static void
|
|||
nautilus_toolbar_set_window_slot_real (NautilusToolbar *self,
|
||||
NautilusWindowSlot *slot)
|
||||
{
|
||||
g_autoptr (GList) children = NULL;
|
||||
|
||||
self->window_slot = slot;
|
||||
|
||||
if (self->window_slot != NULL)
|
||||
|
@ -471,6 +508,10 @@ nautilus_toolbar_set_window_slot_real (NautilusToolbar *self,
|
|||
on_window_slot_destroyed,
|
||||
self);
|
||||
|
||||
on_slot_location_changed (self);
|
||||
|
||||
g_signal_connect_swapped (self->window_slot, "notify::location",
|
||||
G_CALLBACK (on_slot_location_changed), self);
|
||||
g_signal_connect_swapped (self->window_slot, "notify::extensions-background-menu",
|
||||
G_CALLBACK (slot_on_extensions_background_menu_changed), self);
|
||||
g_signal_connect_swapped (self->window_slot, "notify::templates-menu",
|
||||
|
|
|
@ -36,11 +36,10 @@ G_DECLARE_FINAL_TYPE (NautilusToolbar, nautilus_toolbar, NAUTILUS, TOOLBAR, AdwB
|
|||
|
||||
GtkWidget *nautilus_toolbar_new (void);
|
||||
|
||||
GtkWidget *nautilus_toolbar_get_path_bar (NautilusToolbar *self);
|
||||
GtkWidget *nautilus_toolbar_get_location_entry (NautilusToolbar *self);
|
||||
void nautilus_toolbar_show_current_location_menu (NautilusToolbar *self);
|
||||
|
||||
void nautilus_toolbar_set_show_location_entry (NautilusToolbar *self,
|
||||
gboolean show_location_entry);
|
||||
void nautilus_toolbar_open_location_entry (NautilusToolbar *self,
|
||||
const char *special_text);
|
||||
|
||||
void nautilus_toolbar_set_active_slot (NautilusToolbar *toolbar,
|
||||
NautilusWindowSlot *slot);
|
||||
|
|
|
@ -223,80 +223,6 @@ vfs_file_set_metadata_as_list (NautilusFile *file,
|
|||
nautilus_file_ref (file));
|
||||
}
|
||||
|
||||
static GDateTime *
|
||||
vfs_file_get_date (NautilusFile *file,
|
||||
NautilusDateType date_type)
|
||||
{
|
||||
time_t file_time_raw = 0;
|
||||
|
||||
switch (date_type)
|
||||
{
|
||||
case NAUTILUS_DATE_TYPE_ACCESSED:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_atime (file);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_DATE_TYPE_MODIFIED:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_mtime (file);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_DATE_TYPE_CREATED:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_btime (file);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_DATE_TYPE_TRASHED:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_trash_time (file);
|
||||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_DATE_TYPE_RECENCY:
|
||||
{
|
||||
file_time_raw = nautilus_file_get_recency (file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Before we have info on a file, the date is unknown. */
|
||||
if (file_time_raw == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_date_time_new_from_unix_local (file_time_raw);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
vfs_file_get_where_string (NautilusFile *file)
|
||||
{
|
||||
GFile *activation_location;
|
||||
NautilusFile *location;
|
||||
char *where_string;
|
||||
|
||||
if (!nautilus_file_is_in_recent (file))
|
||||
{
|
||||
location = nautilus_file_ref (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
activation_location = nautilus_file_get_activation_location (file);
|
||||
location = nautilus_file_get (activation_location);
|
||||
g_object_unref (activation_location);
|
||||
}
|
||||
|
||||
where_string = nautilus_file_get_parent_uri_for_display (location);
|
||||
|
||||
nautilus_file_unref (location);
|
||||
return where_string;
|
||||
}
|
||||
|
||||
static void
|
||||
vfs_file_mount_callback (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
|
@ -677,8 +603,6 @@ nautilus_vfs_file_class_init (NautilusVFSFileClass *klass)
|
|||
file_class->call_when_ready = vfs_file_call_when_ready;
|
||||
file_class->cancel_call_when_ready = vfs_file_cancel_call_when_ready;
|
||||
file_class->check_if_ready = vfs_file_check_if_ready;
|
||||
file_class->get_date = vfs_file_get_date;
|
||||
file_class->get_where_string = vfs_file_get_where_string;
|
||||
file_class->set_metadata = vfs_file_set_metadata;
|
||||
file_class->set_metadata_as_list = vfs_file_set_metadata_as_list;
|
||||
file_class->mount = vfs_file_mount;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "nautilus-view-controls.h"
|
||||
|
||||
#include "nautilus-toolbar-menu-sections.h"
|
||||
#include "nautilus-window.h"
|
||||
|
||||
struct _NautilusViewControls
|
||||
{
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#define NAUTILUS_VIEW_LIST_ID 1
|
||||
#define NAUTILUS_VIEW_GRID_ID 2
|
||||
/* Special ids, not used by GSettings schemas: */
|
||||
#define NAUTILUS_VIEW_NETWORK_ID 3
|
||||
#define NAUTILUS_VIEW_INVALID_ID 0
|
||||
#define NAUTILUS_VIEW_OTHER_LOCATIONS_ID 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
@ -375,6 +375,19 @@ nautilus_view_model_set_sorter (NautilusViewModel *self,
|
|||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SORTER]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the section sorter, effectively enabling sections.
|
||||
*
|
||||
* Unlike the regular sorter, which compares NautilusViewItem objects, this one
|
||||
* compares the GtkTreeListRows objects which wrap the NautilusViewItem objects.
|
||||
*/
|
||||
void
|
||||
nautilus_view_model_set_section_sorter (NautilusViewModel *self,
|
||||
GtkSorter *section_sorter)
|
||||
{
|
||||
gtk_sort_list_model_set_section_sorter (self->sort_model, GTK_SORTER (section_sorter));
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_view_model_sort (NautilusViewModel *self)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,8 @@ NautilusViewModel * nautilus_view_model_new (void);
|
|||
GtkSorter *nautilus_view_model_get_sorter (NautilusViewModel *self);
|
||||
void nautilus_view_model_set_sorter (NautilusViewModel *self,
|
||||
GtkSorter *sorter);
|
||||
void nautilus_view_model_set_section_sorter (NautilusViewModel *self,
|
||||
GtkSorter *section_sorter);
|
||||
void nautilus_view_model_sort (NautilusViewModel *self);
|
||||
NautilusViewItem * nautilus_view_model_get_item_for_file (NautilusViewModel *self,
|
||||
NautilusFile *file);
|
||||
|
|
|
@ -124,7 +124,7 @@ nautilus_view_get_icon_name (guint view_id)
|
|||
{
|
||||
return "view-grid-symbolic";
|
||||
}
|
||||
else if (view_id == NAUTILUS_VIEW_LIST_ID || view_id == NAUTILUS_VIEW_OTHER_LOCATIONS_ID)
|
||||
else if (view_id == NAUTILUS_VIEW_LIST_ID || view_id == NAUTILUS_VIEW_NETWORK_ID)
|
||||
{
|
||||
return "view-list-symbolic";
|
||||
}
|
||||
|
@ -149,11 +149,7 @@ nautilus_view_get_tooltip (guint view_id)
|
|||
{
|
||||
return _("Grid View");
|
||||
}
|
||||
else if (view_id == NAUTILUS_VIEW_LIST_ID)
|
||||
{
|
||||
return _("List View");
|
||||
}
|
||||
else if (view_id == NAUTILUS_VIEW_OTHER_LOCATIONS_ID)
|
||||
else if (view_id == NAUTILUS_VIEW_LIST_ID || view_id == NAUTILUS_VIEW_NETWORK_ID)
|
||||
{
|
||||
return _("List View");
|
||||
}
|
||||
|
|
|
@ -31,12 +31,10 @@
|
|||
#include "nautilus-files-view.h"
|
||||
#include "nautilus-location-banner.h"
|
||||
#include "nautilus-mime-actions.h"
|
||||
#include "nautilus-places-view.h"
|
||||
#include "nautilus-query-editor.h"
|
||||
#include "nautilus-scheme.h"
|
||||
#include "nautilus-toolbar.h"
|
||||
#include "nautilus-view.h"
|
||||
#include "nautilus-window.h"
|
||||
#include "nautilus-x-content-bar.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
@ -52,7 +50,6 @@
|
|||
enum
|
||||
{
|
||||
PROP_ACTIVE = 1,
|
||||
PROP_WINDOW,
|
||||
PROP_ICON_NAME,
|
||||
PROP_TOOLBAR_MENU_SECTIONS,
|
||||
PROP_EXTENSIONS_BACKGROUND_MENU,
|
||||
|
@ -72,8 +69,6 @@ struct _NautilusWindowSlot
|
|||
{
|
||||
AdwBin parent_instance;
|
||||
|
||||
NautilusWindow *window;
|
||||
|
||||
gboolean active : 1;
|
||||
guint loading : 1;
|
||||
|
||||
|
@ -85,6 +80,7 @@ struct _NautilusWindowSlot
|
|||
|
||||
/* Slot actions */
|
||||
GActionGroup *slot_action_group;
|
||||
GtkShortcutController *shortcuts;
|
||||
|
||||
/* Current location. */
|
||||
GFile *location;
|
||||
|
@ -134,7 +130,7 @@ struct _NautilusWindowSlot
|
|||
GCancellable *mount_cancellable;
|
||||
GError *mount_error;
|
||||
gboolean tried_mount;
|
||||
gint view_mode_before_places;
|
||||
gint view_mode_before_network;
|
||||
|
||||
/* Menus */
|
||||
GMenuModel *extensions_background_menu;
|
||||
|
@ -152,6 +148,13 @@ G_DEFINE_TYPE (NautilusWindowSlot, nautilus_window_slot, ADW_TYPE_BIN);
|
|||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
static const GtkPadActionEntry pad_actions[] =
|
||||
{
|
||||
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Parent folder"), "up" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("Back"), "back" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Forward"), "forward" },
|
||||
};
|
||||
|
||||
static void nautilus_window_slot_force_reload (NautilusWindowSlot *self);
|
||||
static void change_view (NautilusWindowSlot *self);
|
||||
static void nautilus_window_slot_connect_new_content_view (NautilusWindowSlot *self);
|
||||
|
@ -168,6 +171,8 @@ static void nautilus_window_slot_set_location (NautilusWindowSlot *self,
|
|||
static void nautilus_window_slot_set_viewed_file (NautilusWindowSlot *self,
|
||||
NautilusFile *file);
|
||||
static void update_search_information (NautilusWindowSlot *self);
|
||||
static void nautilus_window_slot_go_up (NautilusWindowSlot *self);
|
||||
static void nautilus_window_slot_go_down (NautilusWindowSlot *self);
|
||||
|
||||
void
|
||||
free_navigation_state (gpointer data)
|
||||
|
@ -235,43 +240,26 @@ static NautilusView *
|
|||
nautilus_window_slot_get_view_for_location (NautilusWindowSlot *self,
|
||||
GFile *location)
|
||||
{
|
||||
g_autoptr (NautilusFile) file = NULL;
|
||||
NautilusView *view;
|
||||
guint view_id;
|
||||
|
||||
file = nautilus_file_get (location);
|
||||
view = NULL;
|
||||
view_id = NAUTILUS_VIEW_INVALID_ID;
|
||||
|
||||
if (nautilus_file_is_other_locations (file))
|
||||
{
|
||||
view = NAUTILUS_VIEW (nautilus_places_view_new ());
|
||||
|
||||
/* Save the current view, so we can go back after places view */
|
||||
if (NAUTILUS_IS_FILES_VIEW (self->content_view))
|
||||
{
|
||||
self->view_mode_before_places = nautilus_view_get_view_id (self->content_view);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
g_autoptr (NautilusFile) file = nautilus_file_get (location);
|
||||
NautilusView *view = NULL;
|
||||
guint view_id = NAUTILUS_VIEW_INVALID_ID;
|
||||
|
||||
if (self->content_view != NULL)
|
||||
{
|
||||
/* If there is already a view, just use the view mode that it's currently using, or
|
||||
* if we were on "Other Locations" before, use what we were using before entering
|
||||
* it. */
|
||||
if (NAUTILUS_IS_PLACES_VIEW (self->content_view))
|
||||
/* If there is already a view, just use the view mode that it's currently using */
|
||||
view_id = nautilus_view_get_view_id (self->content_view);
|
||||
if (view_id == NAUTILUS_VIEW_NETWORK_ID)
|
||||
{
|
||||
view_id = self->view_mode_before_places;
|
||||
self->view_mode_before_places = NAUTILUS_VIEW_INVALID_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
view_id = nautilus_view_get_view_id (self->content_view);
|
||||
view_id = self->view_mode_before_network;
|
||||
}
|
||||
}
|
||||
|
||||
if (nautilus_file_is_network_view (file))
|
||||
{
|
||||
self->view_mode_before_network = view_id;
|
||||
view_id = NAUTILUS_VIEW_NETWORK_ID;
|
||||
}
|
||||
|
||||
/* If there is not previous view in this slot, use the default view mode
|
||||
* from preferences */
|
||||
if (view_id == NAUTILUS_VIEW_INVALID_ID)
|
||||
|
@ -343,6 +331,7 @@ static void
|
|||
nautilus_window_slot_sync_actions (NautilusWindowSlot *self)
|
||||
{
|
||||
NautilusView *view;
|
||||
gboolean is_network_view;
|
||||
GAction *action;
|
||||
GVariant *variant;
|
||||
|
||||
|
@ -363,15 +352,16 @@ nautilus_window_slot_sync_actions (NautilusWindowSlot *self)
|
|||
|
||||
/* Files view mode */
|
||||
view = nautilus_window_slot_get_current_view (self);
|
||||
is_network_view = nautilus_view_get_view_id (view) == NAUTILUS_VIEW_NETWORK_ID;
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (self->slot_action_group), "files-view-mode");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), NAUTILUS_IS_FILES_VIEW (view));
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !is_network_view);
|
||||
if (g_action_get_enabled (action))
|
||||
{
|
||||
variant = g_variant_new_uint32 (nautilus_view_get_view_id (view));
|
||||
g_action_change_state (action, variant);
|
||||
}
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (self->slot_action_group), "files-view-mode-toggle");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), NAUTILUS_IS_FILES_VIEW (view));
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !is_network_view);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -452,7 +442,7 @@ hide_query_editor (NautilusWindowSlot *self)
|
|||
|
||||
if (nautilus_window_slot_get_active (self))
|
||||
{
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->window));
|
||||
gtk_widget_grab_focus (GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (self))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -672,18 +662,6 @@ nautilus_window_slot_set_property (GObject *object,
|
|||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_ACTIVE:
|
||||
{
|
||||
nautilus_window_slot_set_active (self, g_value_get_boolean (value));
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_WINDOW:
|
||||
{
|
||||
nautilus_window_slot_set_window (self, g_value_get_object (value));
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_LOCATION:
|
||||
{
|
||||
nautilus_window_slot_set_location (self, g_value_get_object (value));
|
||||
|
@ -769,12 +747,6 @@ nautilus_window_slot_get_property (GObject *object,
|
|||
}
|
||||
break;
|
||||
|
||||
case PROP_WINDOW:
|
||||
{
|
||||
g_value_set_object (value, self->window);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_ICON_NAME:
|
||||
{
|
||||
g_value_set_static_string (value, nautilus_window_slot_get_icon_name (self));
|
||||
|
@ -912,6 +884,87 @@ nautilus_window_slot_constructed (GObject *object)
|
|||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TITLE]);
|
||||
}
|
||||
|
||||
static void
|
||||
update_back_forward_actions (NautilusWindowSlot *self)
|
||||
{
|
||||
GAction *action;
|
||||
gboolean enabled;
|
||||
|
||||
enabled = (nautilus_window_slot_get_back_history (self) != NULL &&
|
||||
!nautilus_window_slot_get_search_global (self));
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (self->slot_action_group), "back");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (self->slot_action_group), "back-n");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled);
|
||||
|
||||
enabled = (nautilus_window_slot_get_forward_history (self) != NULL &&
|
||||
!nautilus_window_slot_get_search_global (self));
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (self->slot_action_group), "forward");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (self->slot_action_group), "forward-n");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
action_back (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusWindowSlot *self = NAUTILUS_WINDOW_SLOT (user_data);
|
||||
|
||||
nautilus_window_slot_back_or_forward (self, TRUE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
action_forward (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusWindowSlot *self = NAUTILUS_WINDOW_SLOT (user_data);
|
||||
|
||||
nautilus_window_slot_back_or_forward (self, FALSE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
action_back_n (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusWindowSlot *self = NAUTILUS_WINDOW_SLOT (user_data);
|
||||
|
||||
nautilus_window_slot_back_or_forward (self, TRUE, g_variant_get_uint32 (parameter));
|
||||
}
|
||||
|
||||
static void
|
||||
action_forward_n (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusWindowSlot *self = NAUTILUS_WINDOW_SLOT (user_data);
|
||||
|
||||
nautilus_window_slot_back_or_forward (self, FALSE, g_variant_get_uint32 (parameter));
|
||||
}
|
||||
|
||||
static void
|
||||
action_up (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusWindowSlot *self = NAUTILUS_WINDOW_SLOT (user_data);
|
||||
|
||||
nautilus_window_slot_go_up (self);
|
||||
}
|
||||
|
||||
static void
|
||||
action_down (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusWindowSlot *self = NAUTILUS_WINDOW_SLOT (user_data);
|
||||
|
||||
nautilus_window_slot_go_down (self);
|
||||
}
|
||||
|
||||
static void
|
||||
action_focus_search (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
|
@ -1006,6 +1059,8 @@ action_search_global (GSimpleAction *action,
|
|||
nautilus_window_slot_set_search_visible (self, search_global);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->banner), !search_global);
|
||||
|
||||
update_back_forward_actions (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SEARCH_GLOBAL]);
|
||||
}
|
||||
}
|
||||
|
@ -1074,8 +1129,34 @@ action_files_view_mode (GSimpleAction *action,
|
|||
g_simple_action_set_state (action, value);
|
||||
}
|
||||
|
||||
static void
|
||||
action_reload (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusWindowSlot *self = NAUTILUS_WINDOW_SLOT (user_data);
|
||||
|
||||
nautilus_window_slot_queue_reload (self);
|
||||
}
|
||||
|
||||
static void
|
||||
action_stop (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NautilusWindowSlot *self = NAUTILUS_WINDOW_SLOT (user_data);
|
||||
|
||||
nautilus_window_slot_stop_loading (self);
|
||||
}
|
||||
|
||||
const GActionEntry slot_entries[] =
|
||||
{
|
||||
{ .name = "back", .activate = action_back },
|
||||
{ .name = "forward", .activate = action_forward },
|
||||
{ .name = "back-n", .activate = action_back_n, .parameter_type = "u" },
|
||||
{ .name = "forward-n", .activate = action_forward_n, .parameter_type = "u" },
|
||||
{ .name = "up", .activate = action_up },
|
||||
{ .name = "down", .activate = action_down },
|
||||
{
|
||||
.name = "files-view-mode", .parameter_type = "u",
|
||||
.state = "uint32 " G_STRINGIFY (NAUTILUS_VIEW_INVALID_ID),
|
||||
|
@ -1085,6 +1166,8 @@ const GActionEntry slot_entries[] =
|
|||
{ .name = "search-visible", .state = "false", .change_state = action_search_visible },
|
||||
{ .name = "search-global", .state = "false", .change_state = action_search_global },
|
||||
{ .name = "focus-search", .activate = action_focus_search },
|
||||
{ .name = "reload", .activate = action_reload },
|
||||
{ .name = "stop", .activate = action_stop },
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -1109,11 +1192,8 @@ update_search_information (NautilusWindowSlot *self)
|
|||
file = nautilus_file_get (location);
|
||||
label = NULL;
|
||||
|
||||
if (nautilus_file_is_other_locations (file))
|
||||
{
|
||||
label = _("Searching locations only");
|
||||
}
|
||||
else if (nautilus_is_root_for_scheme (location, SCHEME_NETWORK))
|
||||
if (nautilus_is_root_for_scheme (location, SCHEME_NETWORK_VIEW) ||
|
||||
nautilus_is_root_for_scheme (location, SCHEME_NETWORK))
|
||||
{
|
||||
label = _("Searching network locations only");
|
||||
}
|
||||
|
@ -1145,19 +1225,25 @@ recursive_search_preferences_changed (GSettings *settings,
|
|||
update_search_information (self);
|
||||
}
|
||||
|
||||
static void
|
||||
set_back_forward_accelerators (NautilusWindowSlot *self)
|
||||
{
|
||||
gboolean ltr = (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_LTR);
|
||||
|
||||
#define ADD_SHORTCUT_FOR_ACTION(controller, action, trigger) \
|
||||
(gtk_shortcut_controller_add_shortcut ((controller), \
|
||||
gtk_shortcut_new (gtk_shortcut_trigger_parse_string ((trigger)), \
|
||||
gtk_named_action_new ((action)))))
|
||||
|
||||
ADD_SHORTCUT_FOR_ACTION (self->shortcuts, "slot.back", ltr ? "<alt>Left|Back" : "<alt>Right|Back");
|
||||
ADD_SHORTCUT_FOR_ACTION (self->shortcuts, "slot.forward", ltr ? "<alt>Right|Forward" : "<alt>Left|Forward");
|
||||
|
||||
#undef ADD_SHORTCUT_FOR_ACTION
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_window_slot_init (NautilusWindowSlot *self)
|
||||
{
|
||||
GApplication *app;
|
||||
const gchar *search_visible_accels[] =
|
||||
{
|
||||
"<control>f",
|
||||
"Search",
|
||||
NULL
|
||||
};
|
||||
|
||||
app = g_application_get_default ();
|
||||
|
||||
g_signal_connect_object (nautilus_preferences,
|
||||
"changed::recursive-search",
|
||||
G_CALLBACK (recursive_search_preferences_changed),
|
||||
|
@ -1172,17 +1258,47 @@ nautilus_window_slot_init (NautilusWindowSlot *self)
|
|||
"slot",
|
||||
G_ACTION_GROUP (self->slot_action_group));
|
||||
|
||||
nautilus_application_set_accelerator (app,
|
||||
"slot.files-view-mode(uint32 " G_STRINGIFY (NAUTILUS_VIEW_LIST_ID) ")",
|
||||
"<control>1");
|
||||
nautilus_application_set_accelerator (app,
|
||||
"slot.files-view-mode(uint32 " G_STRINGIFY (NAUTILUS_VIEW_GRID_ID) ")",
|
||||
"<control>2");
|
||||
nautilus_application_set_accelerators (app, "slot.focus-search", search_visible_accels);
|
||||
nautilus_application_set_accelerator (app, "slot.search-global", "<control><shift>f");
|
||||
self->shortcuts = GTK_SHORTCUT_CONTROLLER (gtk_shortcut_controller_new ());
|
||||
|
||||
gtk_shortcut_controller_set_scope (self->shortcuts, GTK_SHORTCUT_SCOPE_MANAGED);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (self->shortcuts));
|
||||
|
||||
g_autoptr (GtkShortcutAction) view_mode_action = gtk_named_action_new ("slot.files-view-mode");
|
||||
GtkShortcut *shortcut;
|
||||
|
||||
shortcut = gtk_shortcut_new_with_arguments (gtk_shortcut_trigger_parse_string ("<control>1"),
|
||||
g_object_ref (view_mode_action),
|
||||
"u", NAUTILUS_VIEW_LIST_ID);
|
||||
gtk_shortcut_controller_add_shortcut (self->shortcuts, shortcut);
|
||||
shortcut = gtk_shortcut_new_with_arguments (gtk_shortcut_trigger_parse_string ("<control>2"),
|
||||
g_object_ref (view_mode_action),
|
||||
"u", NAUTILUS_VIEW_GRID_ID);
|
||||
gtk_shortcut_controller_add_shortcut (self->shortcuts, shortcut);
|
||||
|
||||
#define ADD_SHORTCUT_FOR_ACTION(controller, action, trigger) \
|
||||
(gtk_shortcut_controller_add_shortcut ((controller), \
|
||||
gtk_shortcut_new (gtk_shortcut_trigger_parse_string ((trigger)), \
|
||||
gtk_named_action_new ((action)))))
|
||||
|
||||
ADD_SHORTCUT_FOR_ACTION (self->shortcuts, "slot.focus-search", "<control>f|Search");
|
||||
ADD_SHORTCUT_FOR_ACTION (self->shortcuts, "slot.search-global", "<control><shift>f");
|
||||
ADD_SHORTCUT_FOR_ACTION (self->shortcuts, "slot.reload", "F5|<ctrl>r|Refresh|Reload");
|
||||
ADD_SHORTCUT_FOR_ACTION (self->shortcuts, "slot.stop", "Stop");
|
||||
ADD_SHORTCUT_FOR_ACTION (self->shortcuts, "slot.up", "<alt>Up");
|
||||
ADD_SHORTCUT_FOR_ACTION (self->shortcuts, "slot.down", "<alt>Down");
|
||||
|
||||
#undef ADD_SHORTCUT_FOR_ACTION
|
||||
|
||||
set_back_forward_accelerators (self);
|
||||
g_signal_connect_swapped (self, "direction-changed",
|
||||
G_CALLBACK (set_back_forward_accelerators), self);
|
||||
|
||||
GtkPadController *pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (self->slot_action_group), NULL);
|
||||
gtk_pad_controller_set_action_entries (pad_controller, pad_actions, G_N_ELEMENTS (pad_actions));
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (pad_controller));
|
||||
|
||||
self->fd_holder = nautilus_fd_holder_new ();
|
||||
self->view_mode_before_places = NAUTILUS_VIEW_INVALID_ID;
|
||||
self->view_mode_before_network = NAUTILUS_VIEW_INVALID_ID;
|
||||
}
|
||||
|
||||
static void begin_location_change (NautilusWindowSlot *slot,
|
||||
|
@ -1197,12 +1313,6 @@ static void got_file_info_for_view_selection_callback (NautilusFile *file,
|
|||
gpointer callback_data);
|
||||
static gboolean setup_view (NautilusWindowSlot *self,
|
||||
NautilusView *view);
|
||||
static void load_new_location (NautilusWindowSlot *slot,
|
||||
GFile *location,
|
||||
GList *selection,
|
||||
NautilusFile *file_to_activate,
|
||||
gboolean tell_current_content_view,
|
||||
gboolean tell_new_content_view);
|
||||
|
||||
void
|
||||
nautilus_window_slot_open_location_full (NautilusWindowSlot *self,
|
||||
|
@ -1410,11 +1520,6 @@ nautilus_window_slot_set_location (NautilusWindowSlot *self,
|
|||
old_location = self->location;
|
||||
self->location = g_object_ref (location);
|
||||
|
||||
if (nautilus_window_slot_get_active (self))
|
||||
{
|
||||
nautilus_window_sync_location_widgets (self->window);
|
||||
}
|
||||
|
||||
nautilus_window_slot_update_title (self);
|
||||
|
||||
if (old_location)
|
||||
|
@ -1423,6 +1528,7 @@ nautilus_window_slot_set_location (NautilusWindowSlot *self,
|
|||
}
|
||||
|
||||
nautilus_fd_holder_set_location (self->fd_holder, self->location);
|
||||
update_back_forward_actions (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LOCATION]);
|
||||
}
|
||||
|
@ -1601,10 +1707,10 @@ mount_not_mounted_callback (GObject *source_object,
|
|||
}
|
||||
|
||||
static void
|
||||
nautilus_window_slot_display_view_selection_failure (NautilusWindow *window,
|
||||
NautilusFile *file,
|
||||
GFile *location,
|
||||
GError *error)
|
||||
nautilus_window_slot_display_view_selection_failure (GtkWindow *window,
|
||||
NautilusFile *file,
|
||||
GFile *location,
|
||||
GError *error)
|
||||
{
|
||||
char *error_message;
|
||||
char *detail_message;
|
||||
|
@ -1712,7 +1818,7 @@ nautilus_window_slot_display_view_selection_failure (NautilusWindow *window,
|
|||
detail_message = g_strdup_printf (_("Unhandled error message: %s"), error->message);
|
||||
}
|
||||
|
||||
show_dialog (error_message, detail_message, GTK_WINDOW (window), GTK_MESSAGE_ERROR);
|
||||
show_dialog (error_message, detail_message, window, GTK_MESSAGE_ERROR);
|
||||
|
||||
done:
|
||||
g_free (error_message);
|
||||
|
@ -1740,14 +1846,12 @@ static gboolean
|
|||
handle_mount_if_needed (NautilusWindowSlot *self,
|
||||
NautilusFile *file)
|
||||
{
|
||||
NautilusWindow *window;
|
||||
GMountOperation *mount_op;
|
||||
MountNotMountedData *data;
|
||||
GFile *location;
|
||||
GError *error = NULL;
|
||||
gboolean needs_mount_handling = FALSE;
|
||||
|
||||
window = nautilus_window_slot_get_window (self);
|
||||
if (self->mount_error)
|
||||
{
|
||||
error = g_error_copy (self->mount_error);
|
||||
|
@ -1762,7 +1866,7 @@ handle_mount_if_needed (NautilusWindowSlot *self,
|
|||
{
|
||||
self->tried_mount = TRUE;
|
||||
|
||||
mount_op = gtk_mount_operation_new (GTK_WINDOW (window));
|
||||
mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))));
|
||||
g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
|
||||
location = nautilus_file_get_location (file);
|
||||
data = g_new0 (MountNotMountedData, 1);
|
||||
|
@ -1825,14 +1929,11 @@ got_file_info_for_view_selection_callback (NautilusFile *file,
|
|||
gpointer callback_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
NautilusWindow *window;
|
||||
NautilusWindowSlot *self;
|
||||
NautilusView *view;
|
||||
GFile *location;
|
||||
NautilusApplication *app;
|
||||
|
||||
self = callback_data;
|
||||
window = nautilus_window_slot_get_window (self);
|
||||
|
||||
g_assert (self->determine_view_file == file);
|
||||
self->determine_view_file = NULL;
|
||||
|
@ -1858,88 +1959,56 @@ got_file_info_for_view_selection_callback (NautilusFile *file,
|
|||
|
||||
location = self->pending_location;
|
||||
|
||||
/* desktop and other-locations GFile operations report G_IO_ERROR_NOT_SUPPORTED,
|
||||
* but it's not an actual error for Nautilus */
|
||||
if (!error || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
|
||||
if (error == NULL)
|
||||
{
|
||||
view = nautilus_window_slot_get_view_for_location (self, location);
|
||||
setup_view (self, view);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self)));
|
||||
|
||||
nautilus_window_slot_display_view_selection_failure (window,
|
||||
file,
|
||||
location,
|
||||
error);
|
||||
|
||||
if (!gtk_widget_get_visible (GTK_WIDGET (window)))
|
||||
GFile *slot_location = nautilus_window_slot_get_location (self);
|
||||
|
||||
if (slot_location == NULL)
|
||||
{
|
||||
/* Destroy never-had-a-chance-to-be-seen window. This case
|
||||
* happens when a new window cannot display its initial URI.
|
||||
*/
|
||||
/* if this is the only window, we don't want to quit, so we redirect it to home */
|
||||
/* This happens when a new slot cannot display its initial URI.
|
||||
* As usual, fallback to $HOME.
|
||||
*
|
||||
* But guard against the case that $HOME cannot be displayed either,
|
||||
* otherwise we would enter an infinite loop. */
|
||||
|
||||
app = NAUTILUS_APPLICATION (g_application_get_default ());
|
||||
|
||||
if (g_list_length (nautilus_application_get_windows (app)) == 1)
|
||||
if (!nautilus_is_home_directory (location))
|
||||
{
|
||||
/* the user could have typed in a home directory that doesn't exist,
|
||||
* in which case going home would cause an infinite loop, so we
|
||||
* better test for that */
|
||||
|
||||
if (!nautilus_is_root_directory (location))
|
||||
{
|
||||
if (!nautilus_is_home_directory (location))
|
||||
{
|
||||
nautilus_window_slot_go_home (self, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *root;
|
||||
|
||||
root = g_file_new_for_path ("/");
|
||||
/* the last fallback is to go to a known place that can't be deleted! */
|
||||
nautilus_window_slot_open_location_full (self, location, 0, NULL);
|
||||
g_object_unref (root);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
}
|
||||
nautilus_window_slot_go_home (self, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Since this is a window, destroying it will also unref it. */
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
/* the last fallback is to go to a known place that can't be deleted! */
|
||||
g_autoptr (GFile) root = g_file_new_for_path ("/");
|
||||
nautilus_window_slot_open_location_full (self, root, 0, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *slot_location;
|
||||
|
||||
/* Clean up state of already-showing window */
|
||||
/* Clean up state of slot already showing a previous location */
|
||||
end_location_change (self);
|
||||
slot_location = nautilus_window_slot_get_location (self);
|
||||
|
||||
if (slot_location == NULL)
|
||||
{
|
||||
/* Location is NULL if we open a broken bookmark in a new window */
|
||||
nautilus_window_slot_go_home (self, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We disconnected this, so we need to re-connect it.
|
||||
* Although not conceptually correct, a force reload is a simple
|
||||
* way to do that. In the future we may want to have an error
|
||||
* status page instead and only reload on explicit request. */
|
||||
nautilus_window_slot_force_reload (self);
|
||||
/* We disconnected this, so we need to re-connect it.
|
||||
* Although not conceptually correct, a force reload is a simple
|
||||
* way to do that. In the future we may want to have an error
|
||||
* status page instead and only reload on explicit request. */
|
||||
nautilus_window_slot_force_reload (self);
|
||||
|
||||
/* Leave the location bar showing the bad location that the user
|
||||
* typed (or maybe achieved by dragging or something). Many times
|
||||
* the mistake will just be an easily-correctable typo.
|
||||
*/
|
||||
}
|
||||
/* Leave the location bar showing the bad location that the user
|
||||
* typed (or maybe achieved by dragging or something). Many times
|
||||
* the mistake will just be an easily-correctable typo.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1960,6 +2029,8 @@ static gboolean
|
|||
setup_view (NautilusWindowSlot *self,
|
||||
NautilusView *view)
|
||||
{
|
||||
g_assert (view != NULL);
|
||||
|
||||
gboolean ret = TRUE;
|
||||
GFile *old_location;
|
||||
|
||||
|
@ -1972,31 +2043,33 @@ setup_view (NautilusWindowSlot *self,
|
|||
/* Forward search selection and state before loading the new model */
|
||||
old_location = self->content_view ? nautilus_view_get_location (self->content_view) : NULL;
|
||||
|
||||
/* Actually load the pending location and selection: */
|
||||
if (self->pending_location != NULL)
|
||||
{
|
||||
load_new_location (self,
|
||||
self->pending_location,
|
||||
self->pending_selection,
|
||||
self->pending_file_to_activate,
|
||||
FALSE,
|
||||
TRUE);
|
||||
/* Load the pending location and selection */
|
||||
nautilus_view_set_location (self->new_content_view, self->pending_location);
|
||||
|
||||
nautilus_file_list_free (self->pending_selection);
|
||||
self->pending_selection = NULL;
|
||||
if (self->pending_file_to_activate != NULL &&
|
||||
NAUTILUS_IS_FILES_VIEW (self->new_content_view))
|
||||
{
|
||||
g_autoptr (GAppInfo) app_info = NULL;
|
||||
const gchar *app_id;
|
||||
|
||||
app_info = nautilus_mime_get_default_application_for_file (self->pending_file_to_activate);
|
||||
app_id = g_app_info_get_id (app_info);
|
||||
if (g_strcmp0 (app_id, NAUTILUS_DESKTOP_ID) == 0)
|
||||
{
|
||||
nautilus_files_view_activate_file (NAUTILUS_FILES_VIEW (view),
|
||||
self->pending_file_to_activate, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (old_location != NULL)
|
||||
{
|
||||
g_autolist (NautilusFile) selection = NULL;
|
||||
/* Reuse current location and selection */
|
||||
g_autolist (NautilusFile) selection = nautilus_view_get_selection (self->content_view);
|
||||
|
||||
selection = nautilus_view_get_selection (self->content_view);
|
||||
|
||||
load_new_location (self,
|
||||
old_location,
|
||||
selection,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE);
|
||||
nautilus_view_set_location (self->new_content_view, old_location);
|
||||
nautilus_view_set_selection (self->new_content_view, selection);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2010,52 +2083,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
load_new_location (NautilusWindowSlot *self,
|
||||
GFile *location,
|
||||
GList *selection,
|
||||
NautilusFile *file_to_activate,
|
||||
gboolean tell_current_content_view,
|
||||
gboolean tell_new_content_view)
|
||||
{
|
||||
NautilusView *view = NULL;
|
||||
g_assert (self != NULL);
|
||||
g_assert (location != NULL);
|
||||
|
||||
/* Note, these may recurse into report_load_underway */
|
||||
if (self->content_view != NULL && tell_current_content_view)
|
||||
{
|
||||
view = self->content_view;
|
||||
nautilus_view_set_location (self->content_view, location);
|
||||
}
|
||||
|
||||
if (self->new_content_view != NULL && tell_new_content_view &&
|
||||
(!tell_current_content_view ||
|
||||
self->new_content_view != self->content_view))
|
||||
{
|
||||
view = self->new_content_view;
|
||||
nautilus_view_set_location (self->new_content_view, location);
|
||||
}
|
||||
if (view)
|
||||
{
|
||||
nautilus_view_set_selection (view, selection);
|
||||
if (file_to_activate != NULL)
|
||||
{
|
||||
g_autoptr (GAppInfo) app_info = NULL;
|
||||
const gchar *app_id;
|
||||
|
||||
g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view));
|
||||
app_info = nautilus_mime_get_default_application_for_file (file_to_activate);
|
||||
app_id = g_app_info_get_id (app_info);
|
||||
if (g_strcmp0 (app_id, NAUTILUS_DESKTOP_ID) == 0)
|
||||
{
|
||||
nautilus_files_view_activate_file (NAUTILUS_FILES_VIEW (view),
|
||||
file_to_activate, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
end_location_change (NautilusWindowSlot *self)
|
||||
{
|
||||
|
@ -2521,6 +2548,24 @@ nautilus_window_slot_update_for_new_location (NautilusWindowSlot *self)
|
|||
nautilus_location_banner_load (self->banner, new_location);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
focus_is_on_popup (GtkRoot *window)
|
||||
{
|
||||
GtkWidget *focus = gtk_root_get_focus (window);
|
||||
|
||||
if (focus != NULL)
|
||||
{
|
||||
GtkNative *native = gtk_widget_get_native (focus);
|
||||
|
||||
if (native != NULL)
|
||||
{
|
||||
return GDK_IS_POPUP (gtk_native_get_surface (native));
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
view_started_loading (NautilusWindowSlot *self,
|
||||
NautilusView *view)
|
||||
|
@ -2530,12 +2575,29 @@ view_started_loading (NautilusWindowSlot *self,
|
|||
nautilus_window_slot_set_allow_stop (self, TRUE);
|
||||
}
|
||||
|
||||
/* Only grab focus if the menu isn't showing. Otherwise the menu disappears
|
||||
* e.g. when the user toggles Show Hidden Files
|
||||
*/
|
||||
if (!nautilus_window_is_menu_visible (self->window))
|
||||
GtkRoot *window = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
|
||||
if (!focus_is_on_popup (window))
|
||||
{
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self->window));
|
||||
/* This mysterious gtk_widget_grab_focus() call has been carried over
|
||||
* many refactorings, along the way having been wrapped in multiple ways
|
||||
* (nautilus_view_grab_focus(), nautilus_window_pane_grab_focus(),
|
||||
* nautilus_view_grab_focus()). It's been added in a series of bugfixes
|
||||
* related to extra pane.[0] If I had to guess, I'd say it was to deal
|
||||
* with side effects of the grandparent commit[1], which removed a much
|
||||
* older bugfix[2].
|
||||
*
|
||||
* Regardless of its original purpose, we still rely on this call to
|
||||
* prevent a "lost focus" situation. This is easily reproduced, in a
|
||||
* build where this call is removed, by refreshing a view where nothing
|
||||
* is selected. This "lost focus" state means, e.g., some keybindings,
|
||||
* such as Ctrl+A, won't work.
|
||||
*
|
||||
* [0] Commit c69f3a2ba2d0bd23de5a218b8ce13d256481213a
|
||||
* [1] Commit 4efd42312584b46f248e2839582a87776a7baebe
|
||||
* [2] Commit 4f7ae827f7e13cf06965cc72ca60cf7801906a33
|
||||
*/
|
||||
gtk_widget_grab_focus (GTK_WIDGET (window));
|
||||
}
|
||||
|
||||
nautilus_window_slot_set_loading (self, TRUE);
|
||||
|
@ -2668,6 +2730,7 @@ nautilus_window_slot_switch_new_content_view (NautilusWindowSlot *self)
|
|||
widget = GTK_WIDGET (self->content_view);
|
||||
gtk_box_append (GTK_BOX (self->vbox), widget);
|
||||
gtk_widget_set_vexpand (widget, TRUE);
|
||||
|
||||
/* Note that this is not bidirectional and that we may also change
|
||||
* :search-visible alone, e.g. when clicking the search button. */
|
||||
self->searching_binding = g_object_bind_property (self->content_view, "searching",
|
||||
|
@ -2830,7 +2893,7 @@ nautilus_window_slot_class_init (NautilusWindowSlotClass *klass)
|
|||
"Whether the slot is active",
|
||||
"Whether the slot is the active slot of the window",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_LOADING] =
|
||||
g_param_spec_boolean ("loading",
|
||||
|
@ -2861,13 +2924,6 @@ nautilus_window_slot_class_init (NautilusWindowSlotClass *klass)
|
|||
"The selection of the current view of the slot. Proxy property from the view",
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
properties[PROP_WINDOW] =
|
||||
g_param_spec_object ("window",
|
||||
"The NautilusWindow",
|
||||
"The NautilusWindow this slot is part of",
|
||||
NAUTILUS_TYPE_WINDOW,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
properties[PROP_ICON_NAME] =
|
||||
g_param_spec_string ("icon-name",
|
||||
"Icon that represents the slot",
|
||||
|
@ -2956,28 +3012,6 @@ nautilus_window_slot_get_location_uri (NautilusWindowSlot *self)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
NautilusWindow *
|
||||
nautilus_window_slot_get_window (NautilusWindowSlot *self)
|
||||
{
|
||||
g_assert (NAUTILUS_IS_WINDOW_SLOT (self));
|
||||
|
||||
return self->window;
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_window_slot_set_window (NautilusWindowSlot *self,
|
||||
NautilusWindow *window)
|
||||
{
|
||||
g_assert (NAUTILUS_IS_WINDOW_SLOT (self));
|
||||
g_assert (NAUTILUS_IS_WINDOW (window));
|
||||
|
||||
if (self->window != window)
|
||||
{
|
||||
self->window = window;
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_WINDOW]);
|
||||
}
|
||||
}
|
||||
|
||||
/* nautilus_window_slot_update_title:
|
||||
*
|
||||
* Re-calculate the slot title.
|
||||
|
@ -2988,10 +3022,7 @@ nautilus_window_slot_set_window (NautilusWindowSlot *self,
|
|||
void
|
||||
nautilus_window_slot_update_title (NautilusWindowSlot *self)
|
||||
{
|
||||
NautilusWindow *window;
|
||||
g_autofree char *title = NULL;
|
||||
title = nautilus_compute_title_for_location (self->location);
|
||||
window = nautilus_window_slot_get_window (self);
|
||||
g_autofree char *title = nautilus_compute_title_for_location (self->location);
|
||||
|
||||
if (g_strcmp0 (title, self->title) != 0)
|
||||
{
|
||||
|
@ -2999,8 +3030,6 @@ nautilus_window_slot_update_title (NautilusWindowSlot *self)
|
|||
self->title = g_steal_pointer (&title);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TITLE]);
|
||||
|
||||
nautilus_window_sync_title (window, self);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3014,13 +3043,16 @@ void
|
|||
nautilus_window_slot_set_allow_stop (NautilusWindowSlot *self,
|
||||
gboolean allow)
|
||||
{
|
||||
NautilusWindow *window;
|
||||
g_assert (NAUTILUS_IS_WINDOW_SLOT (self));
|
||||
|
||||
self->allow_stop = allow;
|
||||
|
||||
window = nautilus_window_slot_get_window (self);
|
||||
nautilus_window_sync_allow_stop (window, self);
|
||||
GActionMap *action_map = G_ACTION_MAP (self->slot_action_group);
|
||||
GAction *stop_action = g_action_map_lookup_action (action_map, "stop");
|
||||
GAction *reload_action = g_action_map_lookup_action (action_map, "reload");
|
||||
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (stop_action), self->allow_stop);
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (reload_action), !self->allow_stop);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ALLOW_STOP]);
|
||||
}
|
||||
|
@ -3050,15 +3082,10 @@ nautilus_window_slot_stop_loading (NautilusWindowSlot *self)
|
|||
* be told, or it is the very pending change we wish
|
||||
* to cancel.
|
||||
*/
|
||||
g_autolist (NautilusFile) selection = NULL;
|
||||
g_autolist (NautilusFile) selection = nautilus_view_get_selection (self->content_view);
|
||||
|
||||
selection = nautilus_view_get_selection (self->content_view);
|
||||
load_new_location (self,
|
||||
location,
|
||||
selection,
|
||||
NULL,
|
||||
TRUE,
|
||||
FALSE);
|
||||
nautilus_view_set_location (self->content_view, location);
|
||||
nautilus_view_set_selection (self->content_view, selection);
|
||||
}
|
||||
|
||||
end_location_change (self);
|
||||
|
@ -3104,10 +3131,9 @@ nautilus_window_slot_get_forward_history (NautilusWindowSlot *self)
|
|||
}
|
||||
|
||||
NautilusWindowSlot *
|
||||
nautilus_window_slot_new (NautilusWindow *window)
|
||||
nautilus_window_slot_new (void)
|
||||
{
|
||||
return g_object_new (NAUTILUS_TYPE_WINDOW_SLOT,
|
||||
"window", window,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -3137,9 +3163,9 @@ nautilus_window_slot_get_icon_name (NautilusWindowSlot *self)
|
|||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_VIEW_OTHER_LOCATIONS_ID:
|
||||
case NAUTILUS_VIEW_NETWORK_ID:
|
||||
{
|
||||
return nautilus_view_get_icon_name (NAUTILUS_VIEW_OTHER_LOCATIONS_ID);
|
||||
return nautilus_view_get_icon_name (NAUTILUS_VIEW_NETWORK_ID);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3176,9 +3202,9 @@ nautilus_window_slot_get_tooltip (NautilusWindowSlot *self)
|
|||
}
|
||||
break;
|
||||
|
||||
case NAUTILUS_VIEW_OTHER_LOCATIONS_ID:
|
||||
case NAUTILUS_VIEW_NETWORK_ID:
|
||||
{
|
||||
return nautilus_view_get_tooltip (NAUTILUS_VIEW_OTHER_LOCATIONS_ID);
|
||||
return nautilus_view_get_tooltip (NAUTILUS_VIEW_NETWORK_ID);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3213,39 +3239,23 @@ void
|
|||
nautilus_window_slot_set_active (NautilusWindowSlot *self,
|
||||
gboolean active)
|
||||
{
|
||||
NautilusWindow *window;
|
||||
|
||||
g_return_if_fail (NAUTILUS_IS_WINDOW_SLOT (self));
|
||||
|
||||
if (self->active != active)
|
||||
{
|
||||
GtkRoot *window = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
|
||||
self->active = active;
|
||||
|
||||
if (active)
|
||||
{
|
||||
AdwTabView *tab_view;
|
||||
AdwTabPage *page;
|
||||
|
||||
window = self->window;
|
||||
|
||||
tab_view = nautilus_window_get_tab_view (window);
|
||||
page = adw_tab_view_get_page (tab_view, GTK_WIDGET (self));
|
||||
|
||||
adw_tab_view_set_selected_page (tab_view, page);
|
||||
|
||||
/* sync window to new slot */
|
||||
nautilus_window_sync_allow_stop (window, self);
|
||||
nautilus_window_sync_title (window, self);
|
||||
nautilus_window_sync_location_widgets (window);
|
||||
nautilus_window_slot_sync_actions (self);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (window), "slot", self->slot_action_group);
|
||||
}
|
||||
else
|
||||
{
|
||||
window = nautilus_window_slot_get_window (self);
|
||||
g_assert (self == nautilus_window_get_active_slot (window));
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (window), "slot", NULL);
|
||||
}
|
||||
|
||||
|
@ -3280,7 +3290,7 @@ nautilus_window_slot_get_query_editor (NautilusWindowSlot *self)
|
|||
return self->query_editor;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
nautilus_window_slot_go_up (NautilusWindowSlot *self)
|
||||
{
|
||||
GFile *location = nautilus_window_slot_get_location (self);
|
||||
|
@ -3302,7 +3312,7 @@ nautilus_window_slot_go_up (NautilusWindowSlot *self)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
nautilus_window_slot_go_down (NautilusWindowSlot *self)
|
||||
{
|
||||
g_autolist (GFile) down_list = g_steal_pointer (&self->down_list);
|
||||
|
|
|
@ -46,11 +46,7 @@ typedef struct
|
|||
NautilusQuery *current_search_query;
|
||||
} NautilusNavigationState;
|
||||
|
||||
NautilusWindowSlot * nautilus_window_slot_new (NautilusWindow *window);
|
||||
|
||||
NautilusWindow * nautilus_window_slot_get_window (NautilusWindowSlot *slot);
|
||||
void nautilus_window_slot_set_window (NautilusWindowSlot *slot,
|
||||
NautilusWindow *window);
|
||||
NautilusWindowSlot * nautilus_window_slot_new (void);
|
||||
|
||||
void nautilus_window_slot_open_location_full (NautilusWindowSlot *slot,
|
||||
GFile *location,
|
||||
|
@ -119,7 +115,4 @@ void nautilus_window_slot_back_or_forward (NautilusWindowSlot *
|
|||
gboolean back,
|
||||
guint distance);
|
||||
|
||||
void nautilus_window_slot_go_up (NautilusWindowSlot *slot);
|
||||
void nautilus_window_slot_go_down (NautilusWindowSlot *slot);
|
||||
|
||||
void free_navigation_state (gpointer data);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -41,11 +41,6 @@ typedef gboolean (* NautilusWindowGoToCallback) (NautilusWindow *window,
|
|||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
typedef void (* NautilusWindowHandleExported) (NautilusWindow *window,
|
||||
const char *handle,
|
||||
guint xid,
|
||||
gpointer user_data);
|
||||
|
||||
/* window geometry */
|
||||
/* Min values are very small, and a Nautilus window at this tiny size is *almost*
|
||||
* completely unusable. However, if all the extra bits (sidebar, location bar, etc)
|
||||
|
@ -81,24 +76,8 @@ GList * nautilus_window_get_slots (NautilusWindow *wind
|
|||
void nautilus_window_slot_close (NautilusWindow *window,
|
||||
NautilusWindowSlot *slot);
|
||||
|
||||
void nautilus_window_sync_location_widgets (NautilusWindow *window);
|
||||
|
||||
void nautilus_window_reset_menus (NautilusWindow *window);
|
||||
|
||||
AdwTabView * nautilus_window_get_tab_view (NautilusWindow *window);
|
||||
|
||||
void nautilus_window_show_about_dialog (NautilusWindow *window);
|
||||
|
||||
gboolean nautilus_window_is_menu_visible (NautilusWindow *toolbar);
|
||||
|
||||
/* sync window GUI with current slot. Used when changing slots,
|
||||
* and when updating the slot state.
|
||||
*/
|
||||
void nautilus_window_sync_allow_stop (NautilusWindow *window,
|
||||
NautilusWindowSlot *slot);
|
||||
void nautilus_window_sync_title (NautilusWindow *window,
|
||||
NautilusWindowSlot *slot);
|
||||
|
||||
void nautilus_window_show_operation_notification (NautilusWindow *window,
|
||||
gchar *main_label,
|
||||
GFile *folder_to_open,
|
||||
|
@ -111,11 +90,6 @@ void nautilus_window_initialize_slot (NautilusWindow *window,
|
|||
NautilusWindowSlot *slot,
|
||||
NautilusOpenFlags flags);
|
||||
|
||||
gboolean nautilus_window_export_handle (NautilusWindow *window,
|
||||
NautilusWindowHandleExported callback,
|
||||
gpointer user_data);
|
||||
void nautilus_window_unexport_handle (NautilusWindow *window);
|
||||
|
||||
void nautilus_window_back_or_forward_in_new_tab (NautilusWindow *window,
|
||||
NautilusNavigationDirection back);
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes" context="shortcut window">Search Everywhere</property>
|
||||
<property name="action-name">slot.search-global</property>
|
||||
<property name="accelerator"><Primary><Shift>F</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -193,7 +193,7 @@
|
|||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes" context="shortcut window">Go Up</property>
|
||||
<property name="action-name">win.up</property>
|
||||
<property name="accelerator"><alt>Up</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -258,7 +258,7 @@
|
|||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes" context="shortcut window">Show/Hide Hidden Files</property>
|
||||
<property name="action-name">view.show-hidden-files</property>
|
||||
<property name="accelerator"><Primary>H</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -321,7 +321,7 @@
|
|||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes" context="shortcut window">Create Folder</property>
|
||||
<property name="action-name">view.new-folder</property>
|
||||
<property name="accelerator"><Primary><shift>N</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -369,7 +369,7 @@
|
|||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes" context="shortcut window">Paste</property>
|
||||
<property name="action-name">view.paste_accel</property>
|
||||
<property name="accelerator"><Primary>V</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -387,7 +387,7 @@
|
|||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="title" translatable="yes" context="shortcut window">Select Items Matching</property>
|
||||
<property name="action-name">view.select-pattern</property>
|
||||
<property name="accelerator"><Primary>S</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
|
4
src/resources/icons/info-outline-symbolic.svg
Normal file
4
src/resources/icons/info-outline-symbolic.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 8 0 c -4.410156 0 -8 3.589844 -8 8 s 3.589844 8 8 8 s 8 -3.589844 8 -8 s -3.589844 -8 -8 -8 z m 0 2 c 3.332031 0 6 2.667969 6 6 s -2.667969 6 -6 6 s -6 -2.667969 -6 -6 s 2.667969 -6 6 -6 z m 0 1.875 c -0.621094 0 -1.125 0.503906 -1.125 1.125 s 0.503906 1.125 1.125 1.125 s 1.125 -0.503906 1.125 -1.125 s -0.503906 -1.125 -1.125 -1.125 z m -1.523438 3.125 c -0.265624 0.011719 -0.476562 0.230469 -0.476562 0.5 c 0 0.277344 0.222656 0.5 0.5 0.5 h 0.5 v 3 h -0.5 c -0.277344 0 -0.5 0.222656 -0.5 0.5 s 0.222656 0.5 0.5 0.5 h 3 c 0.277344 0 0.5 -0.222656 0.5 -0.5 s -0.222656 -0.5 -0.5 -0.5 h -0.5 v -4 h -2.5 c -0.007812 0 -0.015625 0 -0.023438 0 z m 0 0" fill="#222222"/>
|
||||
</svg>
|
After Width: | Height: | Size: 819 B |
|
@ -27,9 +27,9 @@
|
|||
<file>ui/nautilus-operations-ui-manager-request-passphrase.ui</file>
|
||||
<file>ui/nautilus-grid-cell.ui</file>
|
||||
<file>ui/nautilus-name-cell.ui</file>
|
||||
<file>ui/nautilus-network-address-bar.ui</file>
|
||||
<file>ui/nautilus-network-cell.ui</file>
|
||||
<file alias="gtk/ui/nautilusgtksidebarrow.ui">../gtk/nautilusgtksidebarrow.ui</file>
|
||||
<file alias="gtk/ui/nautilusgtkplacesview.ui">../gtk/nautilusgtkplacesview.ui</file>
|
||||
<file alias="gtk/ui/nautilusgtkplacesviewrow.ui">../gtk/nautilusgtkplacesviewrow.ui</file>
|
||||
<file alias="icons/filmholes.png">../../icons/filmholes.png</file>
|
||||
<file>style.css</file>
|
||||
<file>style-hc.css</file>
|
||||
|
@ -46,5 +46,6 @@
|
|||
<file alias="remove-custom-icon-symbolic.svg" preprocess="xml-stripblanks">icons/remove-custom-icon-symbolic.svg</file>
|
||||
<file alias="nautilus-folder-search-symbolic.svg" preprocess="xml-stripblanks">icons/nautilus-folder-search-symbolic.svg</file>
|
||||
<file alias="network-computer-symbolic.svg" preprocess="xml-stripblanks">icons/network-computer-symbolic.svg</file>
|
||||
<file alias="info-outline-symbolic.svg" preprocess="xml-stripblanks">icons/info-outline-symbolic.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
.floating-bar {
|
||||
padding: 3px;
|
||||
background-color: @view_bg_color;
|
||||
box-shadow: inset 0 100px 0 0 alpha(currentColor, 0.05);
|
||||
box-shadow: inset 0 100px 0 0 alpha(currentColor, 0.1);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
@ -162,10 +162,12 @@
|
|||
|
||||
/* Setup padding on the list. Horizontal padding must be set on the columnview
|
||||
* for it to calculate column widths correctly. */
|
||||
.nautilus-network-view listview,
|
||||
.nautilus-list-view columnview {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
.nautilus-network-view listview,
|
||||
.nautilus-list-view columnview > listview {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 24px;
|
||||
|
@ -187,6 +189,7 @@
|
|||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.nautilus-network-view listview > row,
|
||||
.nautilus-list-view columnview > listview > row {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
@ -198,6 +201,8 @@
|
|||
padding: 0px;
|
||||
}
|
||||
|
||||
|
||||
.nautilus-network-view #NautilusViewCell,
|
||||
.nautilus-list-view #NautilusViewCell {
|
||||
padding: 6px;
|
||||
}
|
||||
|
@ -234,6 +239,7 @@
|
|||
}
|
||||
|
||||
/* Both views */
|
||||
.nautilus-network-view:drop(active),
|
||||
.nautilus-list-view:drop(active),
|
||||
.nautilus-grid-view:drop(active) {
|
||||
box-shadow: none;
|
||||
|
@ -242,6 +248,7 @@
|
|||
/* Remove the default background of the various view widgets
|
||||
* since we already apply a background to the entire content
|
||||
* pane with the .view class. Doing this will avoid overdraw. */
|
||||
.nautilus-network-view listview,
|
||||
.nautilus-grid-view gridview,
|
||||
.nautilus-list-view columnview,
|
||||
placesview list {
|
||||
|
@ -270,6 +277,15 @@ placesview list {
|
|||
filter: drop-shadow(0px 1px 1px rgba(0,0,0,0.3));
|
||||
}
|
||||
|
||||
.nautilus-network-view {
|
||||
-gtk-icon-style: symbolic;
|
||||
}
|
||||
.nautilus-network-view image.network-icon {
|
||||
padding: 8px;
|
||||
border-radius: 999999px;
|
||||
background-color: alpha(currentColor, 0.1);
|
||||
}
|
||||
|
||||
.view .cut {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
|
|
@ -31,12 +31,12 @@
|
|||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Season Number</attribute>
|
||||
<attribute name="action">dialog.add-season-tag</attribute>
|
||||
<attribute name="action">dialog.add-season-number-tag</attribute>
|
||||
<attribute name="hidden-when">action-disabled</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Episode Number</attribute>
|
||||
<attribute name="action">dialog.add-episode-tag</attribute>
|
||||
<attribute name="action">dialog.add-episode-number-tag</attribute>
|
||||
<attribute name="hidden-when">action-disabled</attribute>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
<property name="title" translatable="yes">Change Permissions for Enclosed Files</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="destroy-with-parent">True</property>
|
||||
<property name="width-request">360</property>
|
||||
<property name="height-request">294</property>
|
||||
<property name="default-width">480</property>
|
||||
<property name="content">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
|
@ -29,124 +32,56 @@
|
|||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkGrid" id="change_permissions_grid">
|
||||
<property name="halign">center</property>
|
||||
<property name="margin-top">18</property>
|
||||
<property name="margin-bottom">18</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="margin-end">18</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<object class="AdwPreferencesPage">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Files</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Owner</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="file_owner_combo_row">
|
||||
<property name="title" translatable="yes">_Files</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="folder_owner_combo_row">
|
||||
<property name="title" translatable="yes">F_olders</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Folders</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Group</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="file_group_combo_row">
|
||||
<property name="title" translatable="yes">Fi_les</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="folder_group_combo_row">
|
||||
<property name="title" translatable="yes">Fol_ders</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Owner</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="file_owner_drop_down">
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="folder_owner_drop_down">
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Group</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="file_group_drop_down">
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="folder_group_drop_down">
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="file_other_drop_down">
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown" id="folder_other_drop_down">
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Others</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
</layout>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Others</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="file_other_combo_row">
|
||||
<property name="title" translatable="yes">Fil_es</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="folder_other_combo_row">
|
||||
<property name="title" translatable="yes">Folde_rs</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -165,7 +165,7 @@
|
|||
<attribute name="hidden-when">action-disabled</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<section id="move-copy-section">
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Cu_t</attribute>
|
||||
<attribute name="action">view.cut</attribute>
|
||||
|
@ -183,7 +183,7 @@
|
|||
<attribute name="action">view.copy-to</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<section id="file-actions-section">
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Rena_me…</attribute>
|
||||
<attribute name="action">view.rename</attribute>
|
||||
|
@ -249,6 +249,17 @@
|
|||
<attribute name="hidden-when">action-disabled</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section id="network-view-section">
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Copy Address</attribute>
|
||||
<attribute name="action">view.copy-network-address</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Remove</attribute>
|
||||
<attribute name="action">view.remove-recent-server</attribute>
|
||||
<attribute name="hidden-when">action-disabled</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section id="selection-extensions-section"/>
|
||||
<section>
|
||||
<item>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user