source: src-qt4/pc-zmanager/dialogfsprop.cpp @ 125dbc9

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since 125dbc9 was 125dbc9, checked in by Kris Moore <kris@…>, 11 months ago

Welcome the new 'pc-zmanager' for ZFS & Disk Management

A HUGE Thank You to: Claudio L <claudio@…>

Update pkg-plist and add it to the control panel

  • Property mode set to 100644
File size: 46.5 KB
Line 
1#include "zmanagerwindow.h"
2#include "dialogfsprop.h"
3#include "ui_dialogfsprop.h"
4#include <QTreeWidget>
5#include <QTreeWidgetItem>
6#include <QTreeWidgetItemIterator>
7#include <QComboBox>
8#include <QColor>
9#include <QMenu>
10#include <QTimer>
11
12
13DialogFSProp::DialogFSProp(QWidget *parent) :
14    QDialog(parent),
15    ui(new Ui::DialogFSProp)
16{
17    ui->setupUi(this);
18
19    ui->propList->setIconSize(QSize(32,32));
20    ui->propList->header()->setResizeMode(1,QHeaderView::Stretch);
21    ui->propList->header()->setResizeMode(0,QHeaderView::ResizeToContents);
22    ui->propList->header()->setResizeMode(2,QHeaderView::ResizeToContents);
23    ui->propList->sortByColumn(0,Qt::AscendingOrder);
24    InitAllProperties();
25    on_propList_currentItemChanged(NULL,NULL);
26
27}
28
29DialogFSProp::~DialogFSProp()
30{
31    delete ui;
32}
33
34
35void DialogFSProp::InitAllProperties()
36{
37    // INITIALIZATION CANNOT BE STATIC DUE TO CALLS TO tr() FOR PROPER TRANSLATION
38    // IT MUST BE DONE AT RUNTIME AND AS PART OF A CLASS BASED IN QOBJECT
39    zproperty tmp;
40
41
42    tmp.Name="aclinherit";
43    tmp.Description=tr("Controls how ACL entries are inherited when files and directories are created. The values are\n"
44                       "discard, noallow, restricted, and passthrough. For a description of these values, see ACL Properties.");
45    tmp.Flags=PROP_ISOPTION;
46    tmp.ValidOptions.clear();
47    tmp.ValidOptions.append("discard");
48    tmp.ValidOptions.append("noallow");
49    tmp.ValidOptions.append("restricted");
50    tmp.ValidOptions.append("passthrough");
51    tmp.ValidOptions.append("passthrough-x");
52    AllProperties.append(tmp);
53
54
55
56
57//    aclmode
58
59    tmp.Name="aclmode";
60    tmp.Description=tr("Controls how an ACL entry is modified during a chmod operation.\n"
61                       "The values are discard, groupmask, and passthrough. For a description of\n"
62                       "these values, see ACL Properties.");
63    tmp.Flags=PROP_ISOPTION;
64    tmp.ValidOptions.clear();
65    tmp.ValidOptions.append("discard");
66    tmp.ValidOptions.append("groupmask");
67    tmp.ValidOptions.append("passthrough");
68    AllProperties.append(tmp);
69
70//    atime
71
72    tmp.Name="atime";
73    tmp.Description=tr("Controls whether the access time for files is updated when they are read.\n"
74                       "Turning this property off avoids producing write traffic when reading files and\n"
75                       "can result in significant performance gains, though it might confuse mailers and\n"
76                       "similar utilities.");
77    tmp.Flags=PROP_ISOPTION;
78    tmp.ValidOptions.clear();
79    tmp.ValidOptions.append("on");
80    tmp.ValidOptions.append("off");
81    AllProperties.append(tmp);
82
83
84
85//    available
86
87
88
89    tmp.Name="available";
90    tmp.Description=tr("Read-only property that identifies the amount of disk space available to a dataset\n"
91                       "and all its children, assuming no other activity in the pool. Because disk space is\n"
92                       "shared within a pool, available space can be limited by various factors including\n"
93                       "physical pool size, quotas, reservations, and other datasets within the pool.");
94    tmp.Flags=PROP_READONLY;
95    tmp.ValidOptions.clear();
96    AllProperties.append(tmp);
97
98
99
100
101//    canmount
102
103
104            tmp.Name="canmount";
105            tmp.Description=tr("If this property is set to off, the file system cannot be mounted,\n"
106                               "and is ignored by 'zfs mount -a'.  Setting this property to off is\n"
107                               "similar to setting the mountpoint property to none, except that the\n"
108                               "dataset still has a normal mountpoint property, which can be inherited\n"
109                               "Setting this property to off allows datasets to be used solely as a\n"
110                               "mechanism to inherit properties. One example of setting canmount=off is\n"
111                               "to have two datasets with the same mountpoint, so that the children of\n"
112                               "both datasets appear in the same directory, but might have different\n"
113                               "inherited characteristics.");
114
115            tmp.Flags=PROP_ISOPTION;
116            tmp.ValidOptions.clear();
117            tmp.ValidOptions.append("on");
118            tmp.ValidOptions.append("off");
119            tmp.ValidOptions.append("noauto");
120            AllProperties.append(tmp);
121
122
123
124
125//    checksum
126            tmp.Name="checksum";
127            tmp.Description=tr("Controls the checksum used to verify data integrity. The default\n"
128                               "value is on, which automatically selects an appropriate algorithm\n"
129                               "(currently, fletcher4, but this may change in future releases). The\n"
130                               "value off disables integrity checking on user data. Disabling\n"
131                               "checksums is NOT a recommended practice.");
132
133            tmp.Flags=PROP_ISOPTION;
134            tmp.ValidOptions.clear();
135            tmp.ValidOptions.append("on");
136            tmp.ValidOptions.append("off");
137            tmp.ValidOptions.append("fletcher2");
138            tmp.ValidOptions.append("fletcher4");
139            AllProperties.append(tmp);
140
141
142//    compression
143
144            tmp.Name="compression";
145            tmp.Description=tr("Enables or disables compression for a dataset. The values are on, off, lzjb, zle, gzip,\n"
146                               "and gzip-N. Currently, setting this property to lzjb, gzip, or gzip-N has the same\n"
147                               "effect as setting this property to on. Enabling compression on a file system with\n"
148                               "existing data only compresses new data. Existing data remains uncompressed.");
149
150            tmp.Flags=PROP_ISOPTION;
151            tmp.ValidOptions.clear();
152            tmp.ValidOptions.append("on");
153            tmp.ValidOptions.append("off");
154            tmp.ValidOptions.append("lzjb");
155            tmp.ValidOptions.append("zle");
156            tmp.ValidOptions.append("gzip");
157            tmp.ValidOptions.append("gzip-1");
158            tmp.ValidOptions.append("gzip-2");
159            tmp.ValidOptions.append("gzip-3");
160            tmp.ValidOptions.append("gzip-4");
161            tmp.ValidOptions.append("gzip-5");
162            tmp.ValidOptions.append("gzip-6");
163            tmp.ValidOptions.append("gzip-7");
164            tmp.ValidOptions.append("gzip-8");
165            tmp.ValidOptions.append("gzip-9");
166
167            AllProperties.append(tmp);
168
169//    compressratio
170            tmp.Name="compressratio";
171            tmp.Description=tr("Read-only property that identifies the compression ratio achieved for a dataset,\n"
172                               "expressed as a multiplier. Compression can be enabled by the zfs set compression=on\n"
173                               "dataset command. The value is calculated from the logical size of all files and the\n"
174                               "amount of referenced physical data. It includes explicit savings through the use of\n"
175                               "the compression property.");
176
177            tmp.Flags=PROP_READONLY;
178            tmp.ValidOptions.clear();
179            AllProperties.append(tmp);
180
181
182//    copies
183
184
185            tmp.Name="copies";
186            tmp.Description=tr("Sets the number of copies of user data per file system. These copies\n"
187                               "are in addition to any pool-level redundancy. Disk space used by\n"
188                               "multiple copies of user data is charged to the corresponding file and\n"
189                               "dataset, and counts against quotas and reservations. In addition, the\n"
190                               "used property is updated when multiple copies are enabled. Consider setting\n"
191                               "this property when the file system is created because changing this property\n"
192                               "on an existing file system only affects newly written data.");
193
194            tmp.Flags=PROP_ISOPTION;
195            tmp.ValidOptions.clear();
196            tmp.ValidOptions.append("1");
197            tmp.ValidOptions.append("2");
198            tmp.ValidOptions.append("3");
199            AllProperties.append(tmp);
200
201
202
203
204//    creation
205
206           tmp.Name="creation";
207           tmp.Description=tr("Read-only property that identifies the date and time that a dataset was created.");
208           tmp.Flags=PROP_READONLY;
209           tmp.ValidOptions.clear();
210           AllProperties.append(tmp);
211
212
213//    dedup
214           tmp.Name="dedup";
215           tmp.Description=tr("Configures deduplication for a dataset. The default value is off.\n"
216                              "The default deduplication checksum is sha256 (this may change in the\n"
217                              "future).  When dedup is enabled, the checksum defined here overrides\n"
218                              "the checksum property. Setting the value to verify has the same\n"
219                              "effect as the setting sha256,verify.\n"
220                              "If set to verify, ZFS will do a byte-to-byte comparsion in case of\n"
221                              "two blocks having the same signature to make sure the block contents\n"
222                              "are identical.");
223           tmp.Flags=PROP_ISOPTION;
224           tmp.ValidOptions.clear();
225           tmp.ValidOptions.append("on");
226           tmp.ValidOptions.append("off");
227           tmp.ValidOptions.append("verify");
228           tmp.ValidOptions.append("sha256");
229           AllProperties.append(tmp);
230
231
232
233//    devices
234            tmp.Name="devices";
235            tmp.Description=tr("The devices property is currently not supported on FreeBSD.");
236            tmp.Flags=PROP_ISOPTION;
237            tmp.ValidOptions.clear();
238            tmp.ValidOptions.append("on");
239            tmp.ValidOptions.append("off");
240            AllProperties.append(tmp);
241
242
243//    exec
244            tmp.Name="exec";
245            tmp.Description=tr("Controls whether processes can be executed from within this file\n"
246                               "system. The default value is on.");
247            tmp.Flags=PROP_ISOPTION;
248            tmp.ValidOptions.clear();
249            tmp.ValidOptions.append("on");
250            tmp.ValidOptions.append("off");
251            AllProperties.append(tmp);
252
253
254
255//    mounted
256
257            tmp.Name="mounted";
258            tmp.Description=tr("Read-only property that indicates whether a file system, clone, or snapshot\n"
259                               "is currently mounted.");
260            tmp.Flags=PROP_READONLY;
261            tmp.ValidOptions.clear();
262            AllProperties.append(tmp);
263
264
265//    mountpoint
266
267
268            tmp.Name="mountpoint";
269            tmp.Description=tr("Controls the mount point used for this file system. When the mountpoint property\n"
270                               "is changed for a file system, the file system and any descendents that inherit the\n"
271                               "mount point are unmounted. If the new value is legacy, then they remain unmounted.\n"
272                               "Otherwise, they are automatically remounted in the new location if the property was\n"
273                               "previously legacy or none, or if they were mounted before the property was changed.\n"
274                               "In addition, any shared file systems are unshared and shared in the new location.");
275            tmp.Flags=PROP_ISPATH;
276            tmp.ValidOptions.clear();
277            AllProperties.append(tmp);
278
279
280
281//    primarycache
282
283
284
285            tmp.Name="primarycache";
286            tmp.Description=tr("Controls what is cached in the primary cache (ARC). Possible values are all,\n"
287                               "none, and metadata. If set to all, both user data and metadata are cached. If\n"
288                               "set to none, neither user data nor metadata is cached. If set to metadata, only\n"
289                               "metadata is cached.");
290            tmp.Flags=PROP_ISOPTION;
291            tmp.ValidOptions.clear();
292            tmp.ValidOptions.append("none");
293            tmp.ValidOptions.append("metadata");
294            tmp.ValidOptions.append("all");
295            AllProperties.append(tmp);
296
297
298//    origin
299            tmp.Name="origin";
300            tmp.Description=tr("Read-only property for cloned file systems or volumes that identifies\n"
301                               "the snapshot from which the clone was created. The origin cannot be\n"
302                               "destroyed (even with the -r or -f option) as long as a clone exists.\n"
303                               "Non-cloned file systems have an origin of none.");
304            tmp.Flags=PROP_READONLY;
305            tmp.ValidOptions.clear();
306            AllProperties.append(tmp);
307
308
309
310//    quota
311
312            tmp.Name="quota";
313            tmp.Description=tr("Limits the amount of disk space a dataset and its descendents can consume.\n"
314                               "This property enforces a hard limit on the amount of disk space used,\n"
315                               "including all space consumed by descendents, such as file systems and snapshots.\n"
316                               "Setting a quota on a descendent of a dataset that already has a quota does not\n"
317                               "override the ancestor's quota, but rather imposes an additional limit.");
318            tmp.Flags=PROP_ISSTRING;
319            tmp.ValidOptions.clear();
320            AllProperties.append(tmp);
321
322//    readonly
323            tmp.Name="readonly";
324            tmp.Description=tr("Controls whether a dataset can be modified. When set to on,\n"
325                               "no modifications can be made.");
326            tmp.Flags=PROP_ISOPTION;
327            tmp.ValidOptions.clear();
328            tmp.ValidOptions.append("on");
329            tmp.ValidOptions.append("off");
330            AllProperties.append(tmp);
331
332//    recordsize
333            tmp.Name="recordsize";
334            tmp.Description=tr("Specifies a suggested block size for files in the file system. This\n"
335                               "property is designed solely for use with database workloads that\n"
336                               "access files in fixed-size records.  ZFS automatically tunes block\n"
337                               "sizes according to internal algorithms optimized for typical access\n"
338                               "patterns.\n"
339                               "Use of this property for general purpose file systems is strongly\n"
340                               "discouraged, and may adversely affect performance.\n"
341                               "The size specified must be a power of two greater than or equal to\n"
342                               "512 and less than or equal to 128 Kbytes.");
343            tmp.Flags=PROP_ISNUMBER;
344            tmp.ValidOptions.clear();
345            AllProperties.append(tmp);
346
347
348
349
350
351//    referenced
352            tmp.Name="referenced";
353            tmp.Description=tr("Read-only property that identifies the amount of data accessible by a\n"
354                               "dataset, which might or might not be shared with other datasets in the\n"
355                               "pool.");
356            tmp.Flags=PROP_READONLY;
357            tmp.ValidOptions.clear();
358            AllProperties.append(tmp);
359
360
361//    refquota
362            tmp.Name="refquota";
363            tmp.Description=tr("Sets the amount of disk space that a dataset can consume. This property\n"
364                               "enforces a hard limit on the amount of space used. This hard limit does\n"
365                               "not include disk space used by descendents, such as snapshots and clones.");
366            tmp.Flags=PROP_ISNUMBER;
367            tmp.ValidOptions.clear();
368            AllProperties.append(tmp);
369
370//    refreservation
371
372            tmp.Name="refreservation";
373            tmp.Description=tr("Sets the minimum amount of disk space that is guaranteed to a dataset, not\n"
374                               "including descendents, such as snapshots and clones. When the amount of disk\n"
375                               "space used is below this value, the dataset is treated as if it were taking up\n"
376                               "the amount of space specified by refreservation. The refreservation reservation\n"
377                               "is accounted for in the parent dataset's disk space used, and counts against\n"
378                               "the parent dataset's quotas and reservations.\n"
379                               "If refreservation is set, a snapshot is only allowed if enough free pool space\n"
380                               "is available outside of this reservation to accommodate the current number of\n"
381                               "referenced bytes in the dataset.");
382            tmp.Flags=PROP_ISNUMBER;
383            tmp.ValidOptions.clear();
384            AllProperties.append(tmp);
385
386
387//    reservation
388            tmp.Name="reservation";
389            tmp.Description=tr("Sets the minimum amount of disk space guaranteed to a dataset and its descendents.\n"
390                               "When the amount of disk space used is below this value, the dataset is treated as if\n"
391                               "it were using the amount of space specified by its reservation. Reservations are\n"
392                               "accounted for in the parent dataset's disk space used, and count against the parent\n"
393                               "dataset's quotas and reservations.");
394            tmp.Flags=PROP_ISNUMBER;
395            tmp.ValidOptions.clear();
396            AllProperties.append(tmp);
397
398
399
400//    secondarycache
401            tmp.Name="secondarycache";
402            tmp.Description=tr("Controls what is cached in the secondary cache (L2ARC). Possible values are all, none,\n"
403                               "and metadata. If set to all, both user data and metadata are cached. If set to none,\n"
404                               "neither user data nor metadata is cached. If set to metadata, only metadata is cached.");
405            tmp.Flags=PROP_ISOPTION;
406            tmp.ValidOptions.clear();
407            tmp.ValidOptions.append("none");
408            tmp.ValidOptions.append("metadata");
409            tmp.ValidOptions.append("all");
410            AllProperties.append(tmp);
411
412//    setuid
413            tmp.Name="setuid";
414            tmp.Description=tr("Controls whether the setuid bit is honored in a file system.");
415            tmp.Flags=PROP_ISOPTION;
416            tmp.ValidOptions.clear();
417            tmp.ValidOptions.append("on");
418            tmp.ValidOptions.append("off");
419            AllProperties.append(tmp);
420
421
422//    sharenfs
423            tmp.Name="sharenfs";
424            tmp.Description=tr("Controls whether a file system is available over NFS and what\n"
425                               "options are used. If set to on, the zfs share command is invoked\n"
426                               "with no options. Otherwise, the zfs share command is invoked with\n"
427                               "options equivalent to the contents of this property.");
428            tmp.Flags=PROP_ISSTRING;
429            tmp.ValidOptions.clear();
430            AllProperties.append(tmp);
431
432//    sharesmb
433            tmp.Name="sharesmb";
434            tmp.Description=tr("The sharesmb property has currently no effect on FreeBSD.");
435            tmp.Flags=PROP_ISSTRING;
436            tmp.ValidOptions.clear();
437            AllProperties.append(tmp);
438
439
440
441//    snapdir
442            tmp.Name="snapdir";
443            tmp.Description=tr("Controls whether the .zfs directory is hidden or visible in the root of the file system.");
444            tmp.Flags=PROP_ISOPTION;
445            tmp.ValidOptions.clear();
446            tmp.ValidOptions.append("hidden");
447            tmp.ValidOptions.append("visible");
448            AllProperties.append(tmp);
449
450//    type
451    tmp.Name="type";
452    tmp.Description=tr("Read-only property that identifies the dataset type as filesystem (file system or clone), volume, or snapshot.");
453    tmp.Flags=PROP_READONLY;
454    tmp.ValidOptions.clear();
455    AllProperties.append(tmp);
456
457//    used
458            tmp.Name="used";
459            tmp.Description=tr("Read-only property that identifies the amount of disk space consumed by a dataset and all its descendents.");
460            tmp.Flags=PROP_READONLY;
461            tmp.ValidOptions.clear();
462            AllProperties.append(tmp);
463
464
465//    usedbychildren
466            tmp.Name="usedbychildren";
467            tmp.Description=tr("Read-only property that identifies the amount of disk space that is used by\n"
468                               "children of this dataset, which would be freed if all the dataset's children\n"
469                               "were destroyed.");
470            tmp.Flags=PROP_READONLY;
471            tmp.ValidOptions.clear();
472            AllProperties.append(tmp);
473
474//    usedbydataset
475            tmp.Name="usedbydataset";
476            tmp.Description=tr("Read-only property that identifies the amount of disk space that is used by\n"
477                               "a dataset itself, which would be freed if the dataset was destroyed, after\n"
478                               "first destroying any snapshots and removing any refreservation reservations.");
479            tmp.Flags=PROP_READONLY;
480            tmp.ValidOptions.clear();
481            AllProperties.append(tmp);
482
483//    usedbyrefreservation
484            tmp.Name="usedbyrefreservation";
485            tmp.Description=tr("Read-only property that identifies the amount of disk space that is used by a\n"
486                               "refreservation set on a dataset, which would be freed if the refreservation was\n"
487                               "removed.");
488            tmp.Flags=PROP_READONLY;
489            tmp.ValidOptions.clear();
490            AllProperties.append(tmp);
491//    usedbysnapshots
492            tmp.Name="usedbysnapshots";
493            tmp.Description=tr("Read-only property that identifies the amount of disk space that is consumed\n"
494                               "by snapshots of a dataset. In particular, it is the amount of disk space that\n"
495                               "would be freed if all of this dataset's snapshots were destroyed. Note that\n"
496                               "this value is not simply the sum of the snapshots' used properties, because\n"
497                               "space can be shared by multiple snapshots.");
498            tmp.Flags=PROP_READONLY;
499            tmp.ValidOptions.clear();
500            AllProperties.append(tmp);
501//    version
502            tmp.Name="version";
503            tmp.Description=tr("Identifies the on-disk version of a file system, which is independent of the\n"
504                               "pool version. This property can only be set to a later version that is available\n"
505                               "from the supported software release.");
506            tmp.Flags=PROP_READONLY;
507            tmp.ValidOptions.clear();
508            AllProperties.append(tmp);
509
510//    volsize
511            tmp.Name="volsize";
512            tmp.Description=tr("For volumes, specifies the logical size of the volume.");
513            tmp.Flags=PROP_ISNUMBER;
514            tmp.ValidOptions.clear();
515            AllProperties.append(tmp);
516
517//    volblocksize
518            tmp.Name="volblocksize";
519            tmp.Description=tr("For volumes, specifies the block size of the volume.");
520            tmp.Flags=PROP_READONLY;
521            tmp.ValidOptions.clear();
522            AllProperties.append(tmp);
523
524//    jailed
525            tmp.Name="jailed";
526            tmp.Description=tr("Indicates whether a dataset has been added to a jail.");
527            tmp.Flags=PROP_ISOPTION;
528            tmp.ValidOptions.clear();
529            tmp.ValidOptions.append("on");
530            tmp.ValidOptions.append("off");
531            AllProperties.append(tmp);
532
533//    mlslabel
534            tmp.Name="mlslabel";
535            tmp.Description=tr("This property is not supported on FreeBSD.");
536            tmp.Flags=PROP_READONLY;
537            tmp.ValidOptions.clear();
538            AllProperties.append(tmp);
539//    nbmand
540            tmp.Name="nbmand";
541            tmp.Description=tr("This property is not supported on FreeBSD.");
542            tmp.Flags=PROP_READONLY;
543            tmp.ValidOptions.clear();
544            AllProperties.append(tmp);
545//    vscan
546            tmp.Name="vscan";
547            tmp.Description=tr("This property is not supported on FreeBSD.");
548            tmp.Flags=PROP_READONLY;
549            tmp.ValidOptions.clear();
550            AllProperties.append(tmp);
551
552//    xattr
553            tmp.Name="xattr";
554            tmp.Description=tr("This property is not supported on FreeBSD.");
555            tmp.Flags=PROP_READONLY;
556            tmp.ValidOptions.clear();
557            AllProperties.append(tmp);
558//    clones
559            tmp.Name="clones";
560            tmp.Description=tr("This property is not supported on FreeBSD.");
561            tmp.Flags=PROP_READONLY;
562            tmp.ValidOptions.clear();
563            AllProperties.append(tmp);
564
565//    defer_destroy
566            tmp.Name="defer_destroy";
567            tmp.Description=tr("The file system is marked to be destroyed after unmount.");
568            tmp.Flags=PROP_READONLY;
569            tmp.ValidOptions.clear();
570            AllProperties.append(tmp);
571
572
573//    refcompressratio
574            tmp.Name="refcompressratio";
575            tmp.Description=tr("The compression ratio achieved for the referenced space of this\n"
576                               "dataset, expressed as a multiplier.");
577            tmp.Flags=PROP_READONLY;
578            tmp.ValidOptions.clear();
579            AllProperties.append(tmp);
580
581//    written
582             tmp.Name="written";
583             tmp.Description=tr("The amount of referenced space written to this dataset since the\n"
584                                "previous snapshot.");
585             tmp.Flags=PROP_READONLY;
586             tmp.ValidOptions.clear();
587             AllProperties.append(tmp);
588//    userrefs
589             tmp.Name="userrefs";
590             tmp.Description=tr("This property is set to the number of user holds on this snapshot.\n");
591             tmp.Flags=PROP_READONLY;
592             tmp.ValidOptions.clear();
593             AllProperties.append(tmp);
594
595//    logbias
596             tmp.Name="logbias";
597             tmp.Description=tr("Provide a hint to ZFS about handling of synchronous requests in this\n"
598                                "dataset.  If logbias is set to latency (the default), ZFS will use\n"
599                                "pool log devices (if configured) to handle the requests at low\n"
600                                "latency. If logbias is set to throughput, ZFS will not use configured\n"
601                                "pool log devices.  ZFS will instead optimize synchronous operations\n"
602                                "for global pool throughput and efficient use of resources.");
603             tmp.Flags=PROP_ISOPTION;
604             tmp.ValidOptions.clear();
605             tmp.ValidOptions.append("latency");
606             tmp.ValidOptions.append("throughput");
607             AllProperties.append(tmp);
608//    sync
609             tmp.Name="sync";
610             tmp.Description=tr("Controls the behavior of synchronous requests (e.g.  fsync(2),\n"
611                                "O_DSYNC). This property accepts the following values:\n"
612                                    "standard  This is the POSIX specified behavior of ensuring all\n"
613                                    "          synchronous requests are written to stable storage and\n"
614                                    "          all devices are flushed to ensure data is not cached by\n"
615                                    "          device controllers (this is the default).\n"
616                                    "always    All file system transactions are written and flushed\n"
617                                    "          before their system calls return. This has a large\n"
618                                    "          performance penalty.\n"
619                                    "disabled  Disables synchronous requests. File system transactions\n"
620                                    "          are only committed to stable storage periodically. This\n"
621                                    "          option will give the highest performance.  However, it\n"
622                                    "          is very dangerous as ZFS would be ignoring the synchro-\n"
623                                    "          nous transaction demands of applications such as data-\n"
624                                    "          bases or NFS.  Administrators should only use this\n"
625                                    "          option when the risks are understood.");
626             tmp.Flags=PROP_ISOPTION;
627             tmp.ValidOptions.clear();
628             tmp.ValidOptions.append("standard");
629             tmp.ValidOptions.append("always");
630             tmp.ValidOptions.append("disabled");
631             AllProperties.append(tmp);
632//    casesensitivity
633             tmp.Name="casesensitivity";
634             tmp.Description=tr("This property is not supported on FreeBSD.");
635             tmp.Flags=PROP_READONLY;
636             tmp.ValidOptions.clear();
637             AllProperties.append(tmp);
638//    normalization
639             tmp.Name="normalization";
640             tmp.Description=tr("This property cannot be changed after the system is created.");
641             tmp.Flags=PROP_READONLY;
642             tmp.ValidOptions.clear();
643             AllProperties.append(tmp);
644//    utf8only
645             tmp.Name="utf8only";
646             tmp.Description=tr("This property cannot be changed after the system is created.");
647             tmp.Flags=PROP_READONLY;
648             tmp.ValidOptions.clear();
649             AllProperties.append(tmp);
650
651}
652
653QString DialogFSProp::getFSProperty(QString Property)
654{
655    zprop_t tmp;
656
657    foreach(tmp,fsprops->Properties) {
658        if(tmp.Name==Property) {
659            if(tmp.Value=="-") return "";
660            else return tmp.Value;
661        }
662    }
663
664    return "";
665
666}
667
668QString DialogFSProp::getFSPropertySource(QString Property)
669{
670    zprop_t tmp;
671
672    foreach(tmp,fsprops->Properties) {
673        if(tmp.Name==Property) {
674            return tmp.From;
675        }
676    }
677
678    return "";
679
680}
681
682
683bool DialogFSProp::FSPropertyExists(QString Property)
684{
685
686    QList<zprop_t>::Iterator it=fsprops->Properties.begin();
687
688    while(it!=fsprops->Properties.end())
689    {
690        if((*it).Name==Property) return true;
691        ++it;
692    }
693    return false;
694
695}
696
697
698
699
700zproperty *DialogFSProp::getFSBaseProperty(QString Property)
701{
702
703    QList<zproperty>::Iterator it=AllProperties.begin();
704
705    while(it!=AllProperties.end())
706    {
707        if((*it).Name==Property) return &(*it);
708        ++it;
709    }
710    return NULL;
711
712}
713
714
715void DialogFSProp::setDataset(zfs_t *props)
716{
717    fsprops=props;
718    refreshList();
719}
720
721
722void DialogFSProp::refreshList()
723{
724
725    // FIRST MERGE THE PROPERTIES LIST
726
727    // ANY NATIVE PROPERTIES NOT IN fs.Properties ARE BECAUSE SOME PROPERTIES ARE SNAPSHOT ONLY, ETC AND NEED TO BE REMOVED FROM THE LIST
728    int idx;
729
730    for(idx=0;idx<AllProperties.size();++idx)
731    {
732        if(!FSPropertyExists(AllProperties[idx].Name) && !(AllProperties.at(idx).Flags&PROP_CREATE)) { AllProperties.removeAt(idx); --idx; }
733    }
734
735    // ANY USER PROPERTIES IN fs.Properties NOT IN AllProperties NEED TO BE ADDED
736
737
738    for(idx=0;idx<fsprops->Properties.size();++idx)
739    {
740        if(getFSBaseProperty(fsprops->Properties.at(idx).Name)==NULL) {
741            zproperty tmp;
742            tmp.Name=fsprops->Properties[idx].Name;
743            tmp.Flags=PROP_ISSTRING | (fsprops->Properties[idx].Source*PROP_SRCDEFAULT);
744            tmp.ValidOptions.clear();
745            if(tmp.Name.contains(":")) {
746                tmp.Flags|=PROP_ISUSER;
747                tmp.Description=tr("User Property");
748            }
749            else tmp.Description=tr("Unknown property or information not available.\nRead ZFS manual for more information.");
750            AllProperties.append(tmp);
751        }
752    }
753
754    zproperty pr;
755
756    // PREVENT SIGNALS FROM BEING SENT
757    ui->propList->blockSignals(true);
758
759
760    foreach(pr,AllProperties)
761    {
762        QTreeWidgetItem *item=new QTreeWidgetItem(ui->propList);
763        if(!item) return;
764        item->setText(0,pr.Name);
765        item->setToolTip(0,pr.Description);
766        item->setData(0,Qt::UserRole,QVariant(pr.Name));    // SET DATA TO THE PROPERTY NAME
767
768        if(pr.Flags&PROP_ISOPTION) {
769            QComboBox *opt=new QComboBox();
770            if(!opt) return;    // EXIT IF OUT OF MEMORY
771            opt->setEditable(false);
772            opt->addItems(pr.ValidOptions);
773            opt->setItemData(0,QVariant(pr.Name));
774
775            opt->setCurrentIndex(pr.ValidOptions.indexOf(QRegExp(getFSProperty(pr.Name))));
776            ui->propList->setItemWidget(item,1,opt);
777            connect(opt,SIGNAL(currentIndexChanged(int)),SLOT(on_propList_comboChanged(int)));
778        }
779        else{
780        item->setText(1,getFSProperty(pr.Name));
781        }
782        if(pr.Flags&PROP_READONLY) {
783            item->setIcon(0,QIcon(":/icons/user-busy-small-32.png"));
784        }
785        else {
786            if(pr.Flags&PROP_ISUSER)
787                item->setIcon(0,QIcon(":/icons/list-add-user-32.png"));
788            else item->setIcon(0,QIcon(":/icons/user-online-small-32.png"));
789            item->setFlags(item->flags()|Qt::ItemIsEditable);
790        }
791
792        item->setText(2,getFSPropertySource(pr.Name));
793
794
795
796    }
797
798
799    // RE-ENABLE SIGNALS
800    ui->propList->blockSignals(false);
801
802
803}
804
805void DialogFSProp::on_propList_itemDoubleClicked(QTreeWidgetItem *item, int column)
806{
807    Q_UNUSED(column);
808
809    if(column==0)
810    {
811        QString prop=item->data(0,Qt::UserRole).toString();
812        if(prop.isEmpty()) ui->propList->editItem(item,0);
813        else {
814        if(item->text(0).contains(":"))  ui->propList->editItem(item,0);
815            else ui->propList->editItem(item,1);
816        }
817
818    }
819    else ui->propList->editItem(item,1);
820}
821
822
823QStringList DialogFSProp::getAllChangedProps()
824{
825    QStringList result;
826    zproperty pr;
827
828    foreach(pr,AllProperties)
829    {
830        if( !(pr.Flags&PROP_READONLY) && (pr.Flags&(PROP_CHANGED|PROP_CREATE|PROP_INHERIT)))
831        {
832            result.append(pr.Name);
833        }
834    }
835    return result;
836}
837
838QList<int> DialogFSProp::getAllChangedFlags()
839{
840    QList<int> result;
841    zproperty pr;
842
843    foreach(pr,AllProperties)
844    {
845        if( !(pr.Flags&PROP_READONLY) && (pr.Flags&(PROP_CHANGED|PROP_CREATE|PROP_INHERIT)))
846        {
847            result.append(pr.Flags);
848        }
849    }
850    return result;
851}
852
853
854
855
856QStringList DialogFSProp::getAllChangedValues()
857{
858    QStringList result;
859    zproperty pr;
860
861    foreach(pr,AllProperties)
862    {
863        if( !(pr.Flags&PROP_READONLY) && (pr.Flags&(PROP_CHANGED|PROP_CREATE|PROP_INHERIT)))
864        {
865            QTreeWidgetItemIterator it(ui->propList);
866            while(*it) {
867                if((*it)->text(0)==pr.Name) {
868                    if(pr.Flags&PROP_ISOPTION) {
869                        // READ IT FROM THE COMBO WIDGET
870                        QComboBox *combo=(QComboBox *)ui->propList->itemWidget((*it),1);
871                        result.append(combo->currentText());
872                    }
873                    else {
874                        // READ VALUE DIRECTLY
875                        result.append((*it)->text(1));
876                    }
877                }
878                ++it;
879            }
880        }
881    }
882    return result;
883}
884
885void DialogFSProp::itemRevertChanges(QTreeWidgetItem *item,zproperty *prop)
886{
887
888    ui->propList->blockSignals(true);
889
890    prop->Flags&=~(PROP_CHANGED|PROP_INHERIT);
891
892    if(prop->Flags&PROP_ISOPTION) {
893        // CHANGE TO THE PROPER OPTION IN THE COMBOBOX
894        QComboBox *opt=(QComboBox *)ui->propList->itemWidget(item,1);
895        opt->blockSignals(true);
896        opt->clear();
897        opt->addItems(prop->ValidOptions);
898        opt->setItemData(0,QVariant(prop->Name));
899        opt->setCurrentIndex(prop->ValidOptions.indexOf(QRegExp(getFSProperty(prop->Name))));
900        opt->blockSignals(false);
901    }
902    else {
903        item->setText(1,getFSProperty(prop->Name));
904        item->setFlags(item->flags()|Qt::ItemIsEditable);
905    }
906
907    item->setText(2,getFSPropertySource(prop->Name));
908
909    item->setBackgroundColor(0,Qt::white);
910    item->setBackgroundColor(1,Qt::white);
911    item->setBackgroundColor(2,Qt::white);
912
913    ui->propList->blockSignals(false);
914
915}
916
917void DialogFSProp::itemInherit(QTreeWidgetItem *item,zproperty *prop)
918{
919
920    ui->propList->blockSignals(true);
921
922    prop->Flags|=PROP_CHANGED|PROP_INHERIT;
923
924    if(prop->Flags&PROP_ISOPTION) {
925        // CHANGE TO THE PROPER OPTION IN THE COMBOBOX
926        QComboBox *opt=(QComboBox *)ui->propList->itemWidget(item,1);
927        //opt->setCurrentIndex(prop->ValidOptions.indexOf(QRegExp(getFSProperty(prop->Name))));
928        opt->clear();
929    }
930    else item->setText(1,"");
931
932    item->setFlags(item->flags()&~Qt::ItemIsEditable);
933
934    ui->propList->blockSignals(false);
935
936    on_propList_itemChanged(item,1);
937
938}
939
940
941
942void DialogFSProp::on_propList_itemChanged(QTreeWidgetItem *item, int column)
943{
944
945    QString prop=item->data(0,Qt::UserRole).toString();
946
947    QList<zproperty>::iterator pr=AllProperties.begin();
948
949    while(pr!=AllProperties.end())
950    {
951        if((*pr).Name==prop) {
952
953            if(column==0) {
954             // THE USER PROPERTY WAS RENAMED
955                if(!((*pr).Flags&PROP_CREATE)) {
956                    // PROPERTY WAS EXISTING, CANNOT BE RENAMED
957                    item->setText(0,(*pr).Name);
958                    return;
959                }
960                else {
961                    // IT'S OK TO RENAME PROPERTIES THAT ARE ABOUT TO BE CREATED
962                    if(item->text(0).contains(":")) {
963
964                        // CHECK IF THE NEW NAME IS REPEATED
965                        if(getFSBaseProperty(item->text(0))!=NULL) {
966                            // A PROPERTY WITH THAT NAME ALREADY EXISTS
967                            ui->propList->blockSignals(true);
968                            item->setBackgroundColor(0,QColor(255,200,200));
969                            item->setBackgroundColor(1,QColor(255,200,200));
970                            item->setBackgroundColor(2,QColor(255,200,200));
971                            item->setText(2,tr("[Invalid]"));
972                            item->setData(0,Qt::UserRole,QVariant());
973                            ui->propList->blockSignals(false);
974                            QTimer::singleShot(20,this,SLOT(scrollToCurrentItemAndEdit()));
975                            return;
976                        }
977                        (*pr).Name=item->text(0);
978
979                    }
980
981
982
983                    else {
984                        // INVALID NAME, MARK IN RED AND RETURN
985                        ui->propList->blockSignals(true);
986                        item->setBackgroundColor(0,QColor(255,200,200));
987                        item->setBackgroundColor(1,QColor(255,200,200));
988                        item->setBackgroundColor(2,QColor(255,200,200));
989                        item->setText(2,tr("[Invalid]"));
990                        item->setData(0,Qt::UserRole,QVariant());
991                        ui->propList->blockSignals(false);
992                        QTimer::singleShot(20,this,SLOT(scrollToCurrentItemAndEdit()));
993
994                        return;
995                    }
996
997
998                }
999            }
1000
1001            (*pr).Flags|=PROP_CHANGED;
1002
1003            ui->propList->blockSignals(true);
1004            item->setBackgroundColor(0,QColor(255,240,200));
1005            item->setBackgroundColor(1,QColor(255,240,200));
1006            item->setBackgroundColor(2,QColor(255,240,200));
1007            if((*pr).Flags&PROP_INHERIT)  item->setText(2,tr("[Inherit]"));
1008            else if((*pr).Flags&PROP_CREATE) item->setText(2,tr("[Added]"));
1009                    else item->setText(2,tr("[Changed]"));
1010            ui->propList->blockSignals(false);
1011
1012            QTimer::singleShot(20,this,SLOT(scrollToCurrentItem()));
1013
1014
1015            return;
1016        }
1017    ++pr;
1018    }
1019
1020    // NO PROPERTY WAS FOUND! THIS CAN ONLY HAPPEN IMMEDIATELY AFTER A NEW PROPERTY IS CREATED
1021
1022    if(column==0) {
1023        if(!item->text(0).contains(":"))  {
1024            // INVALID NAME, MARK IN RED AND RETURN
1025            ui->propList->blockSignals(true);
1026            item->setBackgroundColor(0,QColor(255,200,200));
1027            item->setBackgroundColor(1,QColor(255,200,200));
1028            item->setBackgroundColor(2,QColor(255,200,200));
1029            item->setText(2,tr("[Invalid]"));
1030            ui->propList->blockSignals(false);
1031
1032            QTimer::singleShot(20,this,SLOT(scrollToCurrentItemAndEdit()));
1033            return;
1034        }
1035
1036        // CHECK IF THE NEW NAME IS REPEATED
1037        if(getFSBaseProperty(item->text(0))!=NULL) {
1038            // A PROPERTY WITH THAT NAME ALREADY EXISTS
1039            ui->propList->blockSignals(true);
1040            item->setBackgroundColor(0,QColor(255,200,200));
1041            item->setBackgroundColor(1,QColor(255,200,200));
1042            item->setBackgroundColor(2,QColor(255,200,200));
1043            item->setText(2,tr("[Invalid]"));
1044            item->setData(0,Qt::UserRole,QVariant());
1045            ui->propList->blockSignals(false);
1046            QTimer::singleShot(20,this,SLOT(scrollToCurrentItemAndEdit()));
1047            return;
1048        }
1049
1050
1051        zproperty tmp;
1052
1053        tmp.Name=item->text(0);
1054        tmp.Flags=PROP_ISSTRING|PROP_ISUSER|PROP_CREATE|PROP_CHANGED|PROP_SRCLOCAL;
1055        tmp.ValidOptions.clear();
1056        tmp.Description=tr("User property");
1057
1058        AllProperties.append(tmp);
1059
1060        ui->propList->blockSignals(true);
1061        item->setBackgroundColor(0,QColor(255,240,200));
1062        item->setBackgroundColor(1,QColor(255,240,200));
1063        item->setBackgroundColor(2,QColor(255,240,200));
1064        if((*pr).Flags&PROP_INHERIT)  item->setText(2,tr("[Inherit]"));
1065        else if((*pr).Flags&PROP_CREATE) item->setText(2,tr("[Added]"));
1066                else item->setText(2,tr("[Changed]"));
1067
1068        item->setData(0,Qt::UserRole,QVariant(tmp.Name));
1069
1070        ui->propList->blockSignals(false);
1071
1072        QTimer::singleShot(20,this,SLOT(scrollToCurrentItem()));
1073
1074    }
1075
1076}
1077
1078
1079void DialogFSProp::on_propList_comboChanged(int index)
1080{
1081    Q_UNUSED(index);
1082
1083    QComboBox *caller=(QComboBox *)sender();
1084    QString prop=caller->itemData(0).toString();
1085
1086    QTreeWidgetItemIterator it(ui->propList);
1087    while((*it)) {
1088        if((*it)->text(0)==prop) { on_propList_itemChanged((*it),1); return; }
1089        ++it;
1090    }
1091
1092    return;
1093}
1094
1095void DialogFSProp::on_propList_customContextMenuRequested(const QPoint &pos)
1096{
1097    QMenu m(tr("Device Menu"),this);
1098
1099    QTreeWidgetItem *item=ui->propList->itemAt(pos);
1100
1101    zproperty *prop = getFSBaseProperty(item->text(0));
1102
1103    m.addAction(tr("Add new user property"))->setData(QVariant(1));
1104    if(prop && ((prop->Flags&(PROP_ISUSER|PROP_CREATE))==(PROP_ISUSER|PROP_CREATE))) m.addAction(tr("Delete user property"))->setData(QVariant(2));
1105    if(prop && !(prop->Flags&PROP_READONLY) && !(prop->Flags&(PROP_SRCINHERIT|PROP_INHERIT))) {
1106        m.addAction(tr("Inherit from parent"))->setData(QVariant(3));
1107    }
1108    if(prop && (prop->Flags&(PROP_CHANGED))) {
1109        m.addAction(tr("Revert changes"))->setData(QVariant(4));
1110    }
1111
1112
1113
1114    QAction *result=m.exec(ui->propList->viewport()->mapToGlobal(pos));
1115
1116    if(result!=NULL) {
1117        int selected=result->data().toInt();
1118        switch(selected)
1119        {
1120        case 1:
1121            // ADD NEW PROPERTY
1122            itemNewProperty();
1123            on_propList_currentItemChanged(ui->propList->currentItem(),NULL);
1124            break;
1125        case 2:
1126            // REMOVE USER PROPERTY
1127            itemRemoveProperty();
1128            on_propList_currentItemChanged(ui->propList->currentItem(),NULL);
1129
1130            break;
1131        case 3:
1132            // INHERIT FROM PARENT
1133            itemInherit(item,prop);
1134            on_propList_currentItemChanged(ui->propList->currentItem(),NULL);
1135            break;
1136        case 4:
1137            // REVERT LOCAL CHANGES
1138            itemRevertChanges(item,prop);
1139            on_propList_currentItemChanged(ui->propList->currentItem(),NULL);
1140            break;
1141
1142        }
1143    }
1144
1145
1146
1147}
1148
1149
1150void DialogFSProp::on_propList_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
1151{
1152    Q_UNUSED(previous);
1153
1154    if(current) {
1155        zproperty *prop=getFSBaseProperty(current->text(0));
1156
1157        if(prop) {
1158            if((prop->Flags&(PROP_ISUSER|PROP_CREATE))==(PROP_ISUSER|PROP_CREATE)) ui->buttonRemove->setEnabled(true);
1159            else ui->buttonRemove->setEnabled(false);
1160            if(!(prop->Flags&(PROP_INHERIT|PROP_SRCINHERIT))&& !(prop->Flags&PROP_READONLY)) ui->buttonInherit->setEnabled(true);
1161            else ui->buttonInherit->setEnabled(false);
1162            if(prop->Flags&PROP_CHANGED) ui->buttonRevert->setEnabled(true);
1163            else ui->buttonRevert->setEnabled(false);
1164        }
1165    }
1166    else {
1167        ui->buttonRemove->setEnabled(false);
1168        ui->buttonInherit->setEnabled(false);
1169        ui->buttonRevert->setEnabled(false);
1170    }
1171}
1172
1173
1174void DialogFSProp::itemNewProperty()
1175{
1176    ui->propList->blockSignals(true);
1177    QTreeWidgetItem *item=new QTreeWidgetItem(ui->propList);
1178    item->setIcon(0,QIcon(":/icons/list-add-user-32.png"));
1179    item->setText(2,tr("[Added]"));
1180    item->setFlags(item->flags()|Qt::ItemIsEditable);
1181    ui->propList->setCurrentItem(item,0);
1182
1183    ui->propList->blockSignals(false);
1184
1185    ui->propList->editItem(item,0);
1186
1187
1188}
1189
1190void DialogFSProp::scrollToCurrentItem()
1191{
1192    ui->propList->scrollToItem(ui->propList->currentItem(),QAbstractItemView::EnsureVisible);
1193}
1194
1195void DialogFSProp::scrollToCurrentItemAndEdit()
1196{
1197    ui->propList->scrollToItem(ui->propList->currentItem(),QAbstractItemView::EnsureVisible);
1198    ui->propList->editItem(ui->propList->currentItem(),0);
1199}
1200
1201void DialogFSProp::on_buttonAdd_clicked()
1202{
1203    itemNewProperty();
1204}
1205
1206
1207void DialogFSProp::itemRemoveProperty()
1208{
1209
1210    if(!ui->propList->currentItem()) return;
1211    QString propname=ui->propList->currentItem()->data(0,Qt::UserRole).toString();
1212
1213    delete ui->propList->currentItem();
1214
1215    zproperty *prop=getFSBaseProperty(propname);
1216
1217    int i;
1218
1219    for(i=0;i<AllProperties.count();++i)
1220    {
1221        if(&(AllProperties[i])==prop) {
1222            AllProperties.removeAt(i);
1223            return;
1224        }
1225    }
1226
1227}
1228
1229void DialogFSProp::on_buttonRemove_clicked()
1230{
1231    itemRemoveProperty();
1232
1233    on_propList_currentItemChanged(ui->propList->currentItem(),NULL);
1234}
1235
1236
1237
1238void DialogFSProp::on_buttonRevert_clicked()
1239{
1240    if(!ui->propList->currentItem()) return;
1241    QString propname=ui->propList->currentItem()->data(0,Qt::UserRole).toString();
1242
1243    zproperty *prop=getFSBaseProperty(propname);
1244
1245    itemRevertChanges(ui->propList->currentItem(),prop);
1246    on_propList_currentItemChanged(ui->propList->currentItem(),NULL);
1247
1248}
1249
1250void DialogFSProp::on_buttonInherit_clicked()
1251{
1252    if(!ui->propList->currentItem()) return;
1253    QString propname=ui->propList->currentItem()->data(0,Qt::UserRole).toString();
1254
1255    zproperty *prop=getFSBaseProperty(propname);
1256
1257    itemInherit(ui->propList->currentItem(),prop);
1258    on_propList_currentItemChanged(ui->propList->currentItem(),NULL);
1259
1260}
1261
1262
1263void DialogFSProp::on_buttonBox_clicked(QAbstractButton *button)
1264{
1265    if(ui->buttonBox->buttonRole(button)==QDialogButtonBox::ApplyRole)
1266        this->accept();
1267}
1268
1269
1270bool        DialogFSProp::applyRecursively()
1271{
1272    return ui->recursiveCheck->isChecked();
1273}
Note: See TracBrowser for help on using the repository browser.