/*******************************************************************************
* ALMA - Atacama Large Millimeter Array
* Copyright (c) ESO - European Southern Observatory, 2013
* (in the framework of the ALMA collaboration).
* All rights reserved.
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*******************************************************************************/
package alma.acs.eventbrowser.status;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.e4.ui.model.application.ui.menu.MToolControl;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.swt.widgets.Composite;
/**
* As of Eclipse 4.2, it is not well documented how to implement a status bar.
* There seems to be an improvement over E3 though, that the status bar is no longer tied to a view
* and thus can display messages from async jobs etc.
* http://www.eclipse.org/forums/index.php/m/962170/ (StatusLineManager
* http://www.vogella.com/articles/EclipseJobs/article.html
* http://www.eclipse.org/forums/index.php/m/753670/
* <p>
* Note that "@Inject IStatusLineManager" (as described in http://wiki.eclipse.org/Eclipse4/RCP/FAQ#Accessing_the_status_line and elsewhere)
* does not work, see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=332499
*
* @author hsommer
*
*/
public class MyStatusBar {
public static final String STATUS_BAR_TOPIC_ID = "statusbar";
/**
* @see StatusLineWriter#flashMessage(String, int)
*/
public static class MessageWithTime {
String msg;
int timeSeconds;
public MessageWithTime(String msg, int timeSeconds) {
this.msg = msg;
this.timeSeconds = timeSeconds;
}
}
@Inject
private UISynchronize uiSync;
/**
* The SWT or jface control. Alternatively use a Label.
*/
private StatusLineManager slm;
/**
*
*/
private String permanentMessage = "";
/**
* Is null whenever we do not display a flash message.
*/
private Job msgRestoreJob;
@PostConstruct
void createControls(Composite parent, MToolControl toolControl) {
if (!toolControl.isVisible()) {
System.out.println("Skipping creation of status bar as it is marked invisible in the model.");
return;
}
slm = new StatusLineManager();
slm.createControl(parent);
slm.setMessage("Refresh service data to get correct supplier/consumer info.");
}
/**
* See http://www.vogella.com/articles/Eclipse4EventSystem/article.html
* Alternatively an object can also register an instance of the EventHandler directly with the IEventBroker
* via the subscribe() method.
* Using dependency injection for subscribing should be preferred compared to the direct subscription.
* @param s
*/
@Inject
@Optional
private void getNotified(@UIEventTopic(STATUS_BAR_TOPIC_ID) String s) {
if (slm != null) {
slm.setMessage(s);
permanentMessage = s;
clearFlashJob();
}
}
@Inject
@Optional
private void getNotified(@UIEventTopic(STATUS_BAR_TOPIC_ID) MessageWithTime msgWithTime) {
if (slm != null) {
String flashMsg = msgWithTime.msg;
int timeSeconds = msgWithTime.timeSeconds;
slm.setMessage(flashMsg);
// TODO fix truncation of larger strings, e.g.
// slm.getControl().pack(true); ??
clearFlashJob();
msgRestoreJob = new Job(MyStatusBar.class.getSimpleName() + "RemoveFlashMessage") {
@Override
protected IStatus run(IProgressMonitor monitor) {
// restore the previous message
uiSync.syncExec(new Runnable() {
@Override
public void run() {
slm.setMessage(permanentMessage);
}
});
return Status.OK_STATUS;
}
};
msgRestoreJob.schedule(timeSeconds*1000);
}
}
private synchronized void clearFlashJob() {
if (msgRestoreJob != null) {
msgRestoreJob.cancel();
msgRestoreJob = null;
}
}
@PreDestroy
public void preDestroy() {
slm.removeAll();
slm.dispose();
}
}