/********************************************************************************************* * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved. * This program and the accompanying materials are made available under the terms * of the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * William Chen (Wind River) - [345384]Provide property pages for remote file system nodes * [361322]Minor improvements to the properties dialog of a file. *********************************************************************************************/ package org.eclipse.tm.te.tcf.filesystem.internal.properties; import java.text.DateFormat; import java.text.DecimalFormat; import java.util.Date; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.tm.te.tcf.filesystem.internal.handlers.ContentTypeHelper; import org.eclipse.tm.te.tcf.filesystem.internal.handlers.StateManager; import org.eclipse.tm.te.tcf.filesystem.internal.nls.Messages; import org.eclipse.tm.te.tcf.filesystem.model.FSTreeNode; import org.eclipse.ui.dialogs.PropertyPage; /** * The general information page of a file's properties dialog. */ public class GeneralInformationPage extends PropertyPage { // The formatter for the modified time and the accessed time. private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT); // The formatter for the size of a file. private static final DecimalFormat SIZE_FORMAT = new DecimalFormat(); // The original node. FSTreeNode node; // Cloned node for modification. FSTreeNode clone; // The button of "Read-Only" Button btnReadOnly; // The button of "Hidden" Button btnHidden; // The button of "Permissions" Button[] btnPermissions; /** * Get the type of an FSTreeNode. * * @return "folder" if it is a directory, "file" if is a file, or else * defaults to node.type. */ protected String getNodeTypeLabel() { if (clone.isDirectory()) return Messages.GeneralInformationPage_Folder; else if (clone.isFile()) { IContentType contentType = ContentTypeHelper.getInstance().getContentType(node); String contentTypeName = contentType == null ? Messages.GeneralInformationPage_UnknownFileType : contentType.getName(); return NLS.bind(Messages.GeneralInformationPage_File, contentTypeName); } else return clone.type; } /** * Create a horizontal separator between field sections. * * @param parent * The parent composite of the separator. */ protected void createSeparator(Composite parent) { Label label = new Label(parent, SWT.SEPARATOR | SWT.SHADOW_ETCHED_IN | SWT.HORIZONTAL); GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false); data.horizontalSpan = 2; label.setLayoutData(data); } /** * Create a field displaying the a specific value with a specific label. * * @param text * The label text for the field. * @param value * The value to be displayed. * @param parent * The parent composite of the field. */ protected void createField(String text, String value, Composite parent) { Label label = new Label(parent, SWT.NONE); label.setText(text); GridData data = new GridData(); data.horizontalAlignment = SWT.LEFT; data.verticalAlignment = SWT.TOP; label.setLayoutData(data); Text txt = new Text(parent, SWT.WRAP | SWT.READ_ONLY); data = new GridData(); data.verticalAlignment = SWT.TOP; data.widthHint = 300; data.grabExcessHorizontalSpace = true; data.horizontalAlignment = GridData.FILL; txt.setLayoutData(data); txt.setBackground(txt.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); txt.setText(value); } /** * Get the string of the file size using using the formatter, SIZE_FORMAT. * * @param size * The size of the file to be formatted. * @return The string in the format of SIZE_FORMAT. */ protected String getSizeText(long size) { return SIZE_FORMAT.format(size / 1024) + " KB (" + SIZE_FORMAT.format(size) + " bytes)"; //$NON-NLS-1$ //$NON-NLS-2$ } /** * Get the string of the specific time using the formatter, DATE_FORMAT. * * @param time * The time to be formatted. * @return The string in the format of DATE_FORMAT. */ protected String getDateText(long time) { return DATE_FORMAT.format(new Date(time)); } /** * Create the attributes section for a Windows file/folder. * * @param parent * The parent composite on which it is created. */ protected void createAttributesSection(Composite parent) { // Attributes Label label = new Label(parent, SWT.NONE); label.setText(Messages.GeneralInformationPage_Attributes); GridData data = new GridData(); data.horizontalAlignment = SWT.LEFT; label.setLayoutData(data); Composite attr = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(3, true); layout.marginHeight = 0; attr.setLayout(layout); // Read-only btnReadOnly = new Button(attr, SWT.CHECK); btnReadOnly.setText(Messages.GeneralInformationPage_ReadOnly); btnReadOnly.addSelectionListener(new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e) { if(btnReadOnly.getSelection()!=clone.isReadOnly()){ clone.setReadOnly(btnReadOnly.getSelection()); } } }); // Hidden btnHidden = new Button(attr, SWT.CHECK); btnHidden.setText(Messages.GeneralInformationPage_Hidden); btnHidden.addSelectionListener(new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e) { Button btnHidden = (Button) e.getSource(); if(btnHidden.getSelection()!=clone.isHidden()){ clone.setHidden(btnHidden.getSelection()); } } }); // Advanced Attributes Button btnAdvanced = new Button(attr, SWT.PUSH); btnAdvanced.setText(Messages.GeneralInformationPage_Advanced); btnAdvanced.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { showAdvancedAttributes(); } }); // Update the attribute values. updateAttributes(); } /** * Update the value of attributes section. */ private void updateAttributes() { btnReadOnly.setSelection(clone.isReadOnly()); btnHidden.setSelection(clone.isHidden()); } /** * Show the advanced attributes dialog for the specified file/folder. */ void showAdvancedAttributes() { AdvancedAttributesDialog dialog = new AdvancedAttributesDialog(this.getShell(), (FSTreeNode)(clone.clone())); if (dialog.open() == Window.OK) { FSTreeNode result = dialog.getResult(); clone.attr = result.attr; } } /** * Create the permissions section for a Unix/Linux file/folder. * * @param parent * The parent composite on which it is created. */ protected void createPermissionsSection(Composite parent) { GridLayout gridLayout; Label label = new Label(parent, SWT.NONE); label.setText("Permissions:"); //$NON-NLS-1$ GridData data = new GridData(); data.horizontalAlignment = SWT.LEFT; data.verticalAlignment = SWT.TOP; label.setLayoutData(data); Composite perms = new Composite(parent, SWT.NONE); gridLayout = new GridLayout(2, false); gridLayout.marginHeight = 0; perms.setLayout(gridLayout); btnPermissions = new Button[9]; createPermissionGroup(perms, 0, Messages.PermissionsGroup_UserPermissions); createPermissionGroup(perms, 3, Messages.PermissionsGroup_GroupPermissions); createPermissionGroup(perms, 6, Messages.PermissionsGroup_OtherPermissions); // Update the permission values. updatePermissions(); } /** * Create a permission group for a role, such as a user, a group or others. * * @param parent * The parent composite. * @param bit * The permission bit index. * @param header * The group's header label. */ protected void createPermissionGroup(Composite parent, int bit, String header) { Label label = new Label(parent, SWT.NONE); label.setText(header); GridData data = new GridData(); data.horizontalAlignment = SWT.LEFT; label.setLayoutData(data); Composite group = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(3, true); layout.marginHeight = 0; group.setLayout(layout); createPermissionButton(Messages.PermissionsGroup_Readable, bit, group); createPermissionButton(Messages.PermissionsGroup_Writable, bit + 1, group); createPermissionButton(Messages.PermissionsGroup_Executable, bit + 2, group); } /** * Create a check-box field for a single permission item. * * @param label * The label of the permission. * @param index * The index of current permission bit mask index. * @param parent * The parent to hold the check-box field. */ private void createPermissionButton(String label, final int index, Composite parent) { btnPermissions[index] = new Button(parent, SWT.CHECK); btnPermissions[index].setText(label); btnPermissions[index].addSelectionListener(new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e) { int bit = 1 << (8 - index); boolean on = (clone.attr.permissions & bit) != 0; boolean newOn = btnPermissions[index].getSelection(); if (newOn != on) { int permissions = clone.attr.permissions; permissions = newOn ? (permissions | bit) : (permissions & ~bit); clone.setPermissions(permissions); } } }); } /** * Update the value of permissions section. */ private void updatePermissions(){ for (int i = 0; i < 9; i++) { final int bit = 1 << (8 - i); final boolean on = (clone.attr.permissions & bit) != 0; btnPermissions[i].setSelection(on); } } /* * (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#performDefaults() */ @Override protected void performDefaults() { clone = (FSTreeNode) node.clone(); if (node.isWindowsNode()) { updateAttributes(); } else { updatePermissions(); } super.performDefaults(); } /* * (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#performOk() */ @Override public boolean performOk() { if (hasAttrsChanged()) { final boolean[] success = new boolean[1]; success[0] = true; SafeRunner.run(new ISafeRunnable() { @Override public void handleException(Throwable exception) { String errorMessage = NLS .bind(Messages.GeneralInformationPage_PropertiesChangeFailure, new Object[] { node.name, exception .getLocalizedMessage() }); MessageDialog.openError(getShell(), Messages.GeneralInformationPage_PropertiesChangeTitle, errorMessage); success[0] = false; } @Override public void run() throws Exception { StateManager.getInstance().setFileAttrs(node, clone.attr); } }); return success[0]; } return true; } /** * If the attributes has been changed. * @return If the attributes has been changed. */ private boolean hasAttrsChanged(){ if(node.isWindowsNode()){ // If it is a Windows file, only check its attributes. return node.getWin32Attrs() != clone.getWin32Attrs(); } // If it is not a Windows file, only check its permissions. return node.attr.permissions != clone.attr.permissions; } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) */ @Override protected Control createContents(Composite parent) { IAdaptable element = getElement(); Assert.isTrue(element instanceof FSTreeNode); node = (FSTreeNode) element; clone = (FSTreeNode) node.clone(); Composite page = new Composite(parent, SWT.NONE); GridLayout gridLayout = new GridLayout(2, false); page.setLayout(gridLayout); // Field "Name" createField(Messages.GeneralInformationPage_Name, clone.name, page); // Field "Type" createField(Messages.GeneralInformationPage_Type, getNodeTypeLabel(), page); // Field "Location" String location = clone.type.endsWith("FSRootNode") //$NON-NLS-1$ || clone.type.endsWith("FSRootDirNode") ? Messages.GeneralInformationPage_Computer //$NON-NLS-1$ : clone.getLocation(); createField(Messages.GeneralInformationPage_Location, location, page); // Field "Size" if (clone.isFile()) { createField(Messages.GeneralInformationPage_Size, getSizeText(clone.attr.size), page); } // Field "Modified" createField(Messages.GeneralInformationPage_Modified, getDateText(clone.attr.mtime), page); // Field "Accessed" if (clone.isFile()) { createField(Messages.GeneralInformationPage_Accessed, getDateText(clone.attr.atime), page); } createSeparator(page); if (clone.isWindowsNode()) { createAttributesSection(page); } else { createPermissionsSection(page); } return page; } }