1 /*
2 * Part of WCM Commander
3 * https://github.com/corporateshark/WCMCommander
4 * wcm@linderdaum.com
5 */
6
7 #include "fileattributes.h"
8
9 #include "ncdialogs.h"
10 #include "dialog_enums.h"
11 #include "dialog_helpers.h"
12 #include "ltext.h"
13 #include "panel.h"
14 #include "vfs.h"
15
16 /*
17 Windows:
18 Read only
19 Archive
20 Hidden
21 System
22 Compressed
23 Encrypted
24
25 Not Indexed
26 Sparse
27 Temporary
28 Offline
29 Reparse point
30 Virtual
31
32 *NIX:
33 Read by owner
34 Write by owner
35 Execute by owner
36 Read by group
37 Write by group
38 Execute by group
39 Read by others
40 Write by others
41 Execute by others
42 Owner name
43 Group Name
44
45 Common:
46 Last write time
47 Creation time
48 Last access time
49 Change time (unsupported yet)
50 */
51
52 class clFileAttributesWin: public NCVertDialog
53 {
54 public:
clFileAttributesWin(NCDialogParent * parent,PanelWin * Panel)55 clFileAttributesWin( NCDialogParent* parent, PanelWin* Panel )
56 : NCVertDialog( ::createDialogAsChild, 0, parent, utf8_to_unicode(_LT("Attributes")).data(), bListOkCancel )
57 , m_Panel( Panel )
58 , m_Node( Panel ? Panel->GetCurrent() : nullptr )
59 , m_URI( Panel ? Panel->UriOfCurrent() : FSString() )
60 , m_Layout( 17, 3 )
61 , m_CaptionText( 0, this, utf8_to_unicode( _LT( "" ) ).data(), nullptr, StaticLine::CENTER )
62 , m_FileNameText( uiValue, this, utf8_to_unicode( _LT( "" ) ).data(), nullptr, StaticLine::CENTER )
63 #if defined(_WIN32)
64 , m_ReadOnly( uiVariable, this, utf8_to_unicode( _LT( "Read only" ) ).data(), 0, false )
65 , m_Archive( uiVariable, this, utf8_to_unicode( _LT( "Archive" ) ).data(), 0, false )
66 , m_Hidden( uiVariable, this, utf8_to_unicode( _LT( "Hidden" ) ).data(), 0, false )
67 , m_System( uiVariable, this, utf8_to_unicode( _LT( "System" ) ).data(), 0, false )
68 , m_Compressed( 0, this, utf8_to_unicode( _LT( "Compressed" ) ).data(), 0, false )
69 , m_Encrypted( 0, this, utf8_to_unicode( _LT( "Encrypted" ) ).data(), 0, false )
70 , m_NotIndexed( 0, this, utf8_to_unicode( _LT( "NotIndexed" ) ).data(), 0, false )
71 , m_Sparse( 0, this, utf8_to_unicode( _LT( "Sparse" ) ).data(), 0, false )
72 , m_Temporary( 0, this, utf8_to_unicode( _LT( "Temporary" ) ).data(), 0, false )
73 , m_Offline( 0, this, utf8_to_unicode( _LT( "Offline" ) ).data(), 0, false )
74 , m_ReparsePoint( 0, this, utf8_to_unicode( _LT( "ReparsePoint" ) ).data(), 0, false )
75 , m_Virtual( 0, this, utf8_to_unicode( _LT( "Virtual" ) ).data(), 0, false )
76 #else
77 , m_UserRead( uiVariable, this, utf8_to_unicode( _LT( "User &read" ) ).data(), 0, false )
78 , m_UserWrite( uiVariable, this, utf8_to_unicode( _LT( "User &write" ) ).data(), 0, false )
79 , m_UserExecute( uiVariable, this, utf8_to_unicode( _LT( "User e&xecute" ) ).data(), 0, false )
80 , m_GroupRead( uiVariable, this, utf8_to_unicode( _LT( "&Group read" ) ).data(), 0, false )
81 , m_GroupWrite( uiVariable, this, utf8_to_unicode( _LT( "Group write" ) ).data(), 0, false )
82 , m_GroupExecute( uiVariable, this, utf8_to_unicode( _LT( "Group execute" ) ).data(), 0, false )
83 , m_OthersRead( uiVariable, this, utf8_to_unicode( _LT( "&Others read" ) ).data(), 0, false )
84 , m_OthersWrite( uiVariable, this, utf8_to_unicode( _LT( "Others write" ) ).data(), 0, false )
85 , m_OthersExecute( uiVariable, this, utf8_to_unicode( _LT( "Others execute" ) ).data(), 0, false )
86 #endif
87 // time
88 , m_LastWriteTimeLabel( 0, this, utf8_to_unicode( _LT( "Last write time" ) ).data(), nullptr, StaticLine::LEFT )
89 , m_CreationTimeLabel( 0, this, utf8_to_unicode( _LT( "Creation time" ) ).data(), nullptr, StaticLine::LEFT )
90 , m_LastAccessTimeLabel( 0, this, utf8_to_unicode( _LT( "Last access time" ) ).data(), nullptr, StaticLine::LEFT )
91 , m_ChangeTimeLabel( 0, this, utf8_to_unicode( _LT( "Change time" ) ).data(), nullptr, StaticLine::LEFT )
92 //
93 , m_LastWriteDate( 0, this, nullptr, utf8_to_unicode( _LT( "DD.MM.YYYY" ) ).data(), 9 )
94 , m_CreationDate( 0, this, nullptr, utf8_to_unicode( _LT( "DD.MM.YYYY" ) ).data(), 9 )
95 , m_LastAccessDate( 0, this, nullptr, utf8_to_unicode( _LT( "DD.MM.YYYY" ) ).data(), 9 )
96 , m_ChangeDate( 0, this, nullptr, utf8_to_unicode( _LT( "DD.MM.YYYY" ) ).data(), 9 )
97 //
98 , m_LastWriteTime( 0, this, nullptr, utf8_to_unicode( _LT( "HH:MM:SS" ) ).data(), 13 )
99 , m_CreationTime( 0, this, nullptr, utf8_to_unicode( _LT( "HH:MM:SS" ) ).data(), 13 )
100 , m_LastAccessTime( 0, this, nullptr, utf8_to_unicode( _LT( "HH:MM:SS" ) ).data(), 13 )
101 , m_ChangeTime( 0, this, nullptr, utf8_to_unicode( _LT( "HH:MM:SS" ) ).data(), 13 )
102 {
103 if ( m_Panel )
104 {
105 const unicode_t* FileName = m_Panel->GetCurrentFileName();
106
107 m_FileNameText.SetText( FileName );
108 }
109
110 if ( m_Node && m_Node->IsDir() )
111 {
112 m_CaptionText.SetText( utf8_to_unicode( _LT("Change attributes for folder:") ).data() );
113 }
114 else
115 {
116 m_CaptionText.SetText( utf8_to_unicode( _LT("Change file attributes for:") ).data() );
117 }
118
119 int Row = 0;
120
121 m_Layout.AddWinAndEnable( &m_CaptionText, Row, 0, Row, 2 ); Row++;
122 m_Layout.AddWinAndEnable( &m_FileNameText, Row, 0, Row, 2 ); Row++;
123
124 int TRow = Row;
125
126 #if defined(_WIN32)
127 m_Layout.AddWinAndEnable( &m_ReadOnly, Row++, 0 );
128 m_Layout.AddWinAndEnable( &m_Archive, Row++, 0 );
129 m_Layout.AddWinAndEnable( &m_Hidden, Row++, 0 );
130 m_Layout.AddWinAndEnable( &m_System, Row++, 0 );
131 m_Layout.AddWinAndEnable( &m_Compressed, Row++, 0 );
132 m_Layout.AddWinAndEnable( &m_Encrypted, Row++, 0 );
133 Row = TRow;
134 m_Layout.AddWinAndEnable( &m_NotIndexed, Row++, 1 );
135 m_Layout.AddWinAndEnable( &m_Sparse, Row++, 1 );
136 m_Layout.AddWinAndEnable( &m_Temporary, Row++, 1 );
137 m_Layout.AddWinAndEnable( &m_Offline, Row++, 1 );
138 m_Layout.AddWinAndEnable( &m_ReparsePoint, Row++, 1 );
139 m_Layout.AddWinAndEnable( &m_Virtual, Row++, 1 );
140
141 // disable editing of these properties
142 m_Compressed.Enable( false );
143 m_Encrypted.Enable( false );
144 m_NotIndexed.Enable( false );
145 m_Sparse.Enable( false );
146 m_Temporary.Enable( false );
147 m_Offline.Enable( false );
148 m_ReparsePoint.Enable( false );
149 m_Virtual.Enable( false );
150 #else
151 m_Layout.AddWinAndEnable( &m_UserRead, Row, 0 );
152 m_Layout.AddWinAndEnable( &m_UserWrite, Row, 1 );
153 m_Layout.AddWinAndEnable( &m_UserExecute, Row, 2 );
154 Row++;
155 m_Layout.AddWinAndEnable( &m_GroupRead, Row, 0 );
156 m_Layout.AddWinAndEnable( &m_GroupWrite, Row, 1 );
157 m_Layout.AddWinAndEnable( &m_GroupExecute, Row, 2 );
158 Row++;
159 m_Layout.AddWinAndEnable( &m_OthersRead, Row, 0 );
160 m_Layout.AddWinAndEnable( &m_OthersWrite, Row, 1 );
161 m_Layout.AddWinAndEnable( &m_OthersExecute, Row, 2 );
162 #endif
163
164 m_Layout.LineSet( Row++, 5 );
165
166 TRow = Row;
167 m_Layout.AddWinAndEnable( &m_LastWriteTimeLabel, Row++, 0 );
168 m_Layout.AddWinAndEnable( &m_CreationTimeLabel, Row++, 0 );
169 m_Layout.AddWinAndEnable( &m_LastAccessTimeLabel, Row++, 0 );
170 #if defined(HAS_CHANGETIME)
171 m_Layout.AddWinAndEnable( &m_ChangeTimeLabel, Row++, 0 );
172 #endif
173 Row = TRow;
174 m_Layout.AddWinAndEnable( &m_LastWriteDate, Row++, 1 );
175 m_Layout.AddWinAndEnable( &m_CreationDate, Row++, 1 );
176 m_Layout.AddWinAndEnable( &m_LastAccessDate, Row++, 1 );
177 #if defined(HAS_CHANGETIME)
178 m_Layout.AddWinAndEnable( &m_ChangeDate, Row++, 1 );
179 #endif
180 Row = TRow;
181 m_Layout.AddWinAndEnable( &m_LastWriteTime, Row++, 2 );
182 m_Layout.AddWinAndEnable( &m_CreationTime, Row++, 2 );
183 m_Layout.AddWinAndEnable( &m_LastAccessTime, Row++, 2 );
184 #if defined(HAS_CHANGETIME)
185 m_Layout.AddWinAndEnable( &m_ChangeTime, Row++, 2 );
186 #endif
187
188 m_LastWriteDate.SetValidator( new clDateValidator() );
189 m_LastWriteDate.SetReplaceMode( true );
190 m_CreationDate.SetValidator( new clDateValidator() );
191 m_CreationDate.SetReplaceMode( true );
192 m_LastAccessDate.SetValidator( new clDateValidator() );
193 m_LastAccessDate.SetReplaceMode( true );
194 #if defined(HAS_CHANGETIME)
195 m_ChangeDate.SetValidator( new clDateValidator() );
196 m_ChangeDate.SetReplaceMode( true );
197 #endif
198 m_LastWriteTime.SetValidator( new clTimeValidator() );
199 m_LastWriteTime.SetReplaceMode( true );
200 m_CreationTime.SetValidator( new clTimeValidator() );
201 m_CreationTime.SetReplaceMode( true );
202 m_LastAccessTime.SetValidator( new clTimeValidator() );
203 m_LastAccessTime.SetReplaceMode( true );
204 #if defined(HAS_CHANGETIME)
205 m_ChangeTime.SetValidator( new clTimeValidator() );
206 m_ChangeTime.SetReplaceMode( true );
207 #endif
208
209 UpdateAttributes( m_Node );
210
211 AddLayout( &m_Layout );
212
213 order.clear();
214 #if defined(_WIN32)
215 order.append(&m_ReadOnly);
216 order.append(&m_Archive);
217 order.append(&m_Hidden);
218 order.append(&m_System);
219 #else
220 order.append(&m_UserRead);
221 order.append(&m_UserWrite);
222 order.append(&m_UserExecute);
223 order.append(&m_GroupRead);
224 order.append(&m_GroupWrite);
225 order.append(&m_GroupExecute);
226 order.append(&m_OthersRead);
227 order.append(&m_OthersWrite);
228 order.append(&m_OthersExecute);
229 #endif // _WIN32
230 order.append(&m_LastWriteDate);
231 order.append(&m_LastWriteTime);
232 order.append(&m_CreationDate);
233 order.append(&m_CreationTime);
234 order.append(&m_LastAccessDate);
235 order.append(&m_LastAccessTime);
236 #if defined(HAS_CHANGETIME)
237 order.append(&m_ChangeDate);
238 order.append(&m_ChangeTime);
239 #endif // HAS_CHANGETIME
240
241 SetEnterCmd( CMD_OK );
242 SetPosition();
243 }
244
GetURI() const245 FSString GetURI() const { return m_URI; }
246
GetNode() const247 FSNode* GetNode() const
248 {
249 if ( !m_Node ) return nullptr;
250
251 #if defined(_WIN32)
252 m_Node->SetAttrReadOnly( m_ReadOnly.IsSet() );
253 m_Node->SetAttrArchive( m_Archive.IsSet() );
254 m_Node->SetAttrHidden( m_Hidden.IsSet() );
255 m_Node->SetAttrSystem( m_System.IsSet() );
256 // m_Node->SetAttrNotIndexed( m_NotIndexed.IsSet() );
257 // m_Node->SetAttrTemporary( m_Temporary.IsSet() );
258 #else
259 m_Node->SetAttrUserRead( m_UserRead.IsSet() );
260 m_Node->SetAttrUserWrite( m_UserWrite.IsSet() );
261 m_Node->SetAttrUserExecute( m_UserExecute.IsSet() );
262 m_Node->SetAttrGroupRead( m_GroupRead.IsSet() );
263 m_Node->SetAttrGroupWrite( m_GroupWrite.IsSet() );
264 m_Node->SetAttrGroupExecute( m_GroupExecute.IsSet() );
265 m_Node->SetAttrOthersRead( m_OthersRead.IsSet() );
266 m_Node->SetAttrOthersWrite( m_OthersWrite.IsSet() );
267 m_Node->SetAttrOthersExecute( m_OthersExecute.IsSet() );
268 #endif
269 std::string LastWriteDate = m_LastWriteDate.GetTextStr();
270 std::string LastWriteTime = m_LastWriteTime.GetTextStr();
271 std::string CreationDate = m_CreationDate.GetTextStr();
272 std::string CreationTime = m_CreationTime.GetTextStr();
273 std::string LastAccessDate = m_LastAccessDate.GetTextStr();
274 std::string LastAccessTime = m_LastAccessTime.GetTextStr();
275 std::string ChangeDate = m_ChangeDate.GetTextStr();
276 std::string ChangeTime = m_ChangeTime.GetTextStr();
277
278 m_Node->SetLastWriteTime( GetFSTimeFromStr( LastWriteDate, LastWriteTime ) );
279 m_Node->SetCreationTime( GetFSTimeFromStr( CreationDate, CreationTime ) );
280 m_Node->SetLastAccessTime( GetFSTimeFromStr( LastAccessDate, LastAccessTime ) );
281 m_Node->SetChangeTime( GetFSTimeFromStr( ChangeDate, ChangeTime ) );
282
283 return m_Node;
284 }
285
286 private:
UpdateAttributes(FSNode * Node)287 void UpdateAttributes( FSNode* Node )
288 {
289 if ( !Node ) return;
290 #if defined(_WIN32)
291 m_ReadOnly.Change( Node->IsAttrReadOnly() );
292 m_Archive.Change( Node->IsAttrArchive() );
293 m_Hidden.Change( Node->IsAttrHidden() );
294 m_System.Change( Node->IsAttrSystem() );
295 m_Compressed.Change( Node->IsAttrCompressed() );
296 m_Encrypted.Change( Node->IsAttrEncrypted() );
297 m_NotIndexed.Change( Node->IsAttrNotIndexed() );
298 m_Sparse.Change( Node->IsAttrSparse() );
299 m_Temporary.Change( Node->IsAttrTemporary() );
300 m_Offline.Change( Node->IsAttrOffline() );
301 m_ReparsePoint.Change( Node->IsAttrReparsePoint() );
302 m_Virtual.Change( Node->IsAttrVirtual() );
303 #else
304 m_UserRead.Change( Node->IsAttrUserRead() );
305 m_UserWrite.Change( Node->IsAttrUserWrite() );
306 m_UserExecute.Change( Node->IsAttrUserExecute() );
307 m_GroupRead.Change( Node->IsAttrGroupRead() );
308 m_GroupWrite.Change( Node->IsAttrGroupWrite() );
309 m_GroupExecute.Change( Node->IsAttrGroupExecute() );
310 m_OthersRead.Change( Node->IsAttrOthersRead() );
311 m_OthersWrite.Change( Node->IsAttrOthersWrite() );
312 m_OthersExecute.Change( Node->IsAttrOthersExecute() );
313 #endif
314 FSTime LastWriteTime = Node->GetLastWriteTime();
315 FSTime CreationTime = Node->GetCreationTime();
316 FSTime LastAccessTime = Node->GetLastAccessTime();
317 FSTime ChangeTime = Node->GetChangeTime();
318
319 m_LastWriteDate.SetText( GetFSTimeStrDate( LastWriteTime ) );
320 m_CreationDate.SetText( GetFSTimeStrDate( CreationTime ) );
321 m_LastAccessDate.SetText( GetFSTimeStrDate( LastAccessTime ) );
322 m_ChangeDate.SetText( GetFSTimeStrDate( ChangeTime ) );
323
324 m_LastWriteTime.SetText( GetFSTimeStrTime( LastWriteTime ) );
325 m_CreationTime.SetText( GetFSTimeStrTime( CreationTime ) );
326 m_LastAccessTime.SetText( GetFSTimeStrTime( LastAccessTime ) );
327 m_ChangeTime.SetText( GetFSTimeStrTime( ChangeTime ) );
328 }
329
330 private:
331 PanelWin* m_Panel;
332 FSNode* m_Node;
333 FSString m_URI;
334
335 Layout m_Layout;
336
337 StaticLine m_CaptionText;
338 StaticLine m_FileNameText;
339 #if defined(_WIN32)
340 SButton m_ReadOnly;
341 SButton m_Archive;
342 SButton m_Hidden;
343 SButton m_System;
344 SButton m_Compressed;
345 SButton m_Encrypted;
346 SButton m_NotIndexed;
347 SButton m_Sparse;
348 SButton m_Temporary;
349 SButton m_Offline;
350 SButton m_ReparsePoint;
351 SButton m_Virtual;
352 #else
353 SButton m_UserRead;
354 SButton m_UserWrite;
355 SButton m_UserExecute;
356 SButton m_GroupRead;
357 SButton m_GroupWrite;
358 SButton m_GroupExecute;
359 SButton m_OthersRead;
360 SButton m_OthersWrite;
361 SButton m_OthersExecute;
362 #endif
363 // time
364 StaticLine m_LastWriteTimeLabel;
365 StaticLine m_CreationTimeLabel;
366 StaticLine m_LastAccessTimeLabel;
367 StaticLine m_ChangeTimeLabel;
368
369 EditLine m_LastWriteDate;
370 EditLine m_CreationDate;
371 EditLine m_LastAccessDate;
372 EditLine m_ChangeDate;
373
374 EditLine m_LastWriteTime;
375 EditLine m_CreationTime;
376 EditLine m_LastAccessTime;
377 EditLine m_ChangeTime;
378 };
379
FileAttributesDlg(NCDialogParent * Parent,PanelWin * Panel)380 bool FileAttributesDlg( NCDialogParent* Parent, PanelWin* Panel )
381 {
382 clFileAttributesWin Dialog( Parent, Panel );
383
384 if ( Dialog.DoModal( ) == CMD_OK )
385 {
386 FSNode* Node = Dialog.GetNode();
387
388 // apply changes
389 if ( Node )
390 {
391 FSPath fspath;
392 FSString URI = Dialog.GetURI();
393 clPtr<FS> fs = ParzeURI( URI.GetUnicode(), fspath, {} );
394 if ( fs )
395 {
396 int Err = 0;
397 FSCInfo Info;
398 fs->StatSetAttr( fspath, &Node->st, &Err, &Info );
399 if ( Err != 0 )
400 {
401 throw_msg( "Error setting file attributes: %s", fs->StrError( Err ).GetUtf8() );
402 }
403 fs->SetFileTime( fspath, Node->GetCreationTime(), Node->GetLastAccessTime(), Node->GetLastWriteTime(), &Err, &Info );
404 if ( Err != 0 )
405 {
406 throw_msg("Error setting file date & time: %s", fs->StrError(Err).GetUtf8());
407 }
408 }
409 }
410
411 return true;
412 }
413
414 return false;
415 }
416
417