private void createButtonRow() {
    logger.log(Level.INFO, "Detail panel: Creating button row ...");

    Button backButton = new Button(this, SWT.NONE);
    backButton.setText(I18n.getText("org.syncany.gui.history.DetailPanel.button.back"));
    backButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1));
    backButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            historyDialog.showMainPanel();
          }
        });

    GridData restoreStatusCompositeGridData =
        new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1);
    restoreStatusCompositeGridData.verticalIndent = 3;

    restoreStatusComposite = new Composite(this, SWT.NONE);
    restoreStatusComposite.setLayout(new GridLayout(2, false));
    restoreStatusComposite.setLayoutData(restoreStatusCompositeGridData);

    restoreStatusIconComposite = new ImageComposite(restoreStatusComposite, SWT.NONE);
    restoreStatusIconComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

    restoreStatusTextLabel = new Label(restoreStatusComposite, SWT.NONE);
    restoreStatusTextLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));
    restoreStatusTextLabel.addMouseListener(
        new MouseAdapter() {
          @Override
          public void mouseUp(MouseEvent e) {
            if (restoredFile != null) {
              DesktopUtil.launch(restoredFile.getAbsolutePath());
            }
          }
        });

    restoreButton = new Button(this, SWT.NONE);
    restoreButton.setEnabled(false);
    restoreButton.setText(I18n.getText("org.syncany.gui.history.DetailPanel.button.restore"));
    restoreButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
    restoreButton.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
            restoreSelectedFile();
          }
        });
  }
  private void restoreFileVersion(FileVersion fileVersion) {
    // Set labels/status
    String shortFileName = shortenFileName(fileVersion.getPath());
    String versionStr = Long.toString(fileVersion.getVersion());

    restoreButton.setEnabled(false);
    restoreStatusIconComposite.setVisible(true);
    restoreStatusTextLabel.setVisible(true);

    restoreStatusIconComposite.setAnimatedImage(
        IMAGE_LOADING_SPINNER_RESOURCE, IMAGE_LOADING_SPINNER_FRAME_RATE);
    restoreStatusTextLabel.setText(
        I18n.getText(
            "org.syncany.gui.history.DetailPanel.label.fileRestoreOngoing",
            shortFileName,
            versionStr));
    restoreStatusTextLabel.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_ARROW));
    restoreStatusTextLabel.setToolTipText("");

    restoredFile = null;

    layout();

    // Send restore request
    RestoreOperationOptions restoreOptions = new RestoreOperationOptions();
    restoreOptions.setFileHistoryId(fileVersion.getFileHistoryId());
    restoreOptions.setFileVersion(fileVersion.getVersion().intValue());

    pendingRestoreRequest = new RestoreFolderRequest();
    pendingRestoreRequest.setRoot(historyModel.getSelectedRoot());
    pendingRestoreRequest.setOptions(restoreOptions);

    eventBus.post(pendingRestoreRequest);
  }
  private void createHistoryTableColumns() {
    logger.log(Level.INFO, "Detail panel: Creating history table columns ...");

    // When reordering/adding columns, make sure to adjust the constants!
    // e.g TABLE_COLUMN_REMOTE_VERSION, ...

    TableColumn columnStatus = new TableColumn(historyTable, SWT.LEFT);
    columnStatus.setWidth(30);

    TableColumn columnPath = new TableColumn(historyTable, SWT.NONE);
    columnPath.setText(I18n.getText("org.syncany.gui.history.DetailPanel.table.path"));
    columnPath.setWidth(210);

    TableColumn columnVersion = new TableColumn(historyTable, SWT.NONE);
    columnVersion.setText(I18n.getText("org.syncany.gui.history.DetailPanel.table.version"));
    columnVersion.setWidth(30);

    TableColumn columnType = new TableColumn(historyTable, SWT.LEFT);
    columnType.setText(I18n.getText("org.syncany.gui.history.DetailPanel.table.type"));
    columnType.setWidth(60);

    TableColumn columnSize = new TableColumn(historyTable, SWT.LEFT);
    columnSize.setText(I18n.getText("org.syncany.gui.history.DetailPanel.table.size"));
    columnSize.setWidth(70);

    TableColumn columnPosixPermissions = new TableColumn(historyTable, SWT.LEFT);
    columnPosixPermissions.setText(
        I18n.getText("org.syncany.gui.history.DetailPanel.table.posixPermissions"));
    columnPosixPermissions.setWidth(70);

    TableColumn columnDosAttributes = new TableColumn(historyTable, SWT.LEFT);
    columnDosAttributes.setText(
        I18n.getText("org.syncany.gui.history.DetailPanel.table.dosAttributes"));
    columnDosAttributes.setWidth(70);

    TableColumn columnChecksum = new TableColumn(historyTable, SWT.LEFT);
    columnChecksum.setText(I18n.getText("org.syncany.gui.history.DetailPanel.table.checksum"));
    columnChecksum.setWidth(200);

    TableColumn columnLastModified = new TableColumn(historyTable, SWT.LEFT);
    columnLastModified.setText(
        I18n.getText("org.syncany.gui.history.DetailPanel.table.lastModified"));
    columnLastModified.setWidth(130);

    TableColumn columnUpdated = new TableColumn(historyTable, SWT.LEFT);
    columnUpdated.setText(I18n.getText("org.syncany.gui.history.DetailPanel.table.updated"));
    columnUpdated.setWidth(130);
  }
  private void updateRestoreStatus(
      RestoreFolderRequest restoreRequest, RestoreFolderResponse restoreResponse) {
    RestoreOperationResult restoreResult = restoreResponse.getResult();
    RestoreResultCode restoreResultCode = restoreResult.getResultCode();

    // Set labels/status
    restoreButton.setEnabled(true);
    restoreStatusIconComposite.setVisible(true);
    restoreStatusTextLabel.setVisible(true);

    if (restoreResultCode == RestoreResultCode.ACK) {
      String shortFileName = shortenFileName(restoreResult.getTargetFile().getAbsolutePath());
      logger.log(
          Level.INFO,
          "Detail panel: Restore successful, file restored to "
              + restoreResult.getTargetFile().toString());

      restoreStatusIconComposite.setImage(
          SWTResourceManager.getImage(String.format(IMAGE_RESOURCE_FORMAT, "success")));
      restoreStatusTextLabel.setText(
          I18n.getText(
              "org.syncany.gui.history.DetailPanel.label.fileRestoreSuccess", shortFileName));
      restoreStatusTextLabel.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_HAND));
      restoreStatusTextLabel.setToolTipText(restoreResult.getTargetFile().toString());

      restoredFile = restoreResult.getTargetFile();
    } else {
      logger.log(Level.WARNING, "Detail panel: Restore FAILED, error code " + restoreResultCode);

      restoreStatusIconComposite.setImage(
          SWTResourceManager.getImage(String.format(IMAGE_RESOURCE_FORMAT, "failure")));
      restoreStatusTextLabel.setText(
          I18n.getText("org.syncany.gui.history.DetailPanel.label.fileRestoreFailure"));
      restoreStatusTextLabel.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_ARROW));
      restoreStatusTextLabel.setToolTipText("");

      restoredFile = null;
    }

    layout();
  }