- * Note: when application asks for frames of kind 3 the warning is logged. + * COFS contains only frames of kind 1 and 2. Kind 3 (all frames) contains too many files and are outside of COFS. + * However this interface partially works only with GIFs and second aligned JPGs. Each method includes + * notes on whether the method supports non-second-aligned frames. * * @author hazard157 */ @@ -30,6 +29,8 @@ public interface ICofsFrames { * Returns frame file if exists. *
* For {@link IFrame#NONE} returns special file with unknown episode meaning. + *
+ * Supports non-seconds aligned frames they will be found by this method.
*
* @param aFrame {@link IFrame} - the frame
* @return {@link File} - existing frame image file or null
@@ -39,6 +40,8 @@ public interface ICofsFrames {
/**
* Returns all frames with images files.
+ *
+ * Does not supports non-seconds aligned frames, they are not included in the returned set.
*
* @param aEpisodeId String - the requested episode ID
* @return {@link IList}<{@link IFrame}> - the list of all frames of the episode
@@ -47,6 +50,4 @@ public interface ICofsFrames {
*/
IFramesSet listEpisodeFrames( String aEpisodeId );
- // TODO add non-sec-alignes frames management
-
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsFrames.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsFrames.java
index 1f3bce6..fc786a9 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsFrames.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsFrames.java
@@ -27,6 +27,9 @@
class CofsFrames
implements ICofsFrames {
+ // FIXME move to settings? argument of this service?
+ private static final File NONSECS_ROOT = new File( "/home/.psx/episodes/frames-nonsec/" ); //$NON-NLS-1$
+
/**
* Episodes resources root directory or
+ * Note: user may override this settings at any time in by the frames viewer GUI.
+ *
+ * @return {@link ISvinFramesParams} - the SVINs to frames strategy
+ */
+ ISvinFramesParams framesSelectionParams();
+
+ /**
+ * Returns event manager informing of changes in {@link #svins()} list.
+ *
+ * Note: {@link #framesSelectionParams()} has own eventer, so does not affects this one.
+ *
+ * @return {@link IGenericChangeEventer} - SVINs list change eventer
+ */
+ IGenericChangeEventer eventer();
+
+ // ------------------------------------------------------------------------------------
+ // Convenience inline methods
+
+ /**
+ * Set single SVIN.
+ *
+ * @param aSvin {@link Svin} - the SVIN, may be null
+ */
+ default void setSvin( Svin aSvin ) {
+ if( aSvin != null ) {
+ setSvins( new SingleItemList<>( aSvin ) );
+ return;
+ }
+ setSvins( IList.EMPTY );
+ }
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/services/selsvins/PsxSelectedSvinsService.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/services/selsvins/PsxSelectedSvinsService.java
new file mode 100644
index 0000000..f548408
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/services/selsvins/PsxSelectedSvinsService.java
@@ -0,0 +1,59 @@
+package com.hazard157.prisex24.e4.services.selsvins;
+
+import org.toxsoft.core.tslib.bricks.events.change.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.glib.frasel.*;
+import com.hazard157.psx.common.stuff.svin.*;
+
+/**
+ * {@link IPsxSelectedSvinsService} implementation.
+ *
+ * @author hazard157
+ */
+public class PsxSelectedSvinsService
+ implements IPsxSelectedSvinsService {
+
+ private final GenericChangeEventer eventer;
+ private final IListEdit
+ * When {@link IPsxSelectedSvinsService#eventer()} or {@link IPsxSelectedSvinsService#framesSelectionParams()} eventers
+ * fire the change event refreshes the view.
+ *
+ * @author hazard157
+ */
+public class UipartSharedSvinsFramesViewer
+ extends PsxAbstractUipart {
+
+ @Inject
+ IPsxSelectedSvinsService selectedSvinsService;
+
+ private ISvinsFramesViewer svinViewer;
+
+ @Override
+ protected void doInit( Composite aParent ) {
+ svinViewer = new SvinsFramesViewer( aParent, tsContext() );
+ selectedSvinsService.eventer().addListener( s -> refreshView() );
+ selectedSvinsService.framesSelectionParams().genericChangeEventer().addListener( s -> refreshView() );
+ }
+
+ private void refreshView() {
+ svinViewer.svinFramesParams().setParams( selectedSvinsService.framesSelectionParams() );
+ svinViewer.svinSeq().svins().setAll( selectedSvinsService.svins() );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/dialogs/DialogWorkWithFrames.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/dialogs/DialogWorkWithFrames.java
new file mode 100644
index 0000000..da2b229
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/dialogs/DialogWorkWithFrames.java
@@ -0,0 +1,76 @@
+package com.hazard157.prisex24.glib.dialogs;
+
+import static com.hazard157.prisex24.glib.dialogs.IPsxResources.*;
+import static org.toxsoft.core.tsgui.dialogs.datarec.ITsDialogConstants.*;
+
+import org.eclipse.e4.core.contexts.*;
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.dialogs.datarec.*;
+import org.toxsoft.core.tsgui.utils.layout.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.glib.epframes.*;
+import com.hazard157.psx.common.stuff.frame.*;
+import com.hazard157.psx.proj3.episodes.*;
+
+/**
+ * Dialog to show and work with frames around the specified frame.
+ *
+ * @author hazard157
+ */
+public class DialogWorkWithFrames
+ extends AbstractTsDialogPanelnull
is specified one is not accessible.
*/
@@ -116,41 +119,75 @@ private void ensureEpisodeFrames( LocalDate aEpisodeDate ) {
cachedEpFrames.put( epId, new FramesSet( llCacheAllFrames ) );
}
- // ------------------------------------------------------------------------------------
- // ICofsFrames
- //
-
- @Override
- public File findFrameFile( IFrame aFrame ) {
- TsNullArgumentRtException.checkNull( aFrame );
- if( epsRoot == null ) {
+ private File internalFindSecAlignedStillFrame( IFrame aFrame ) {
+ LocalDate ld = EPsxIncidentKind.EPISODE.id2date( aFrame.episodeId() );
+ File epDir = new File( epsRoot, ld.toString() );
+ File epFramesDir = new File( epDir, SUBDIR_EP_STILL_IMAGES );
+ File epCamDir = new File( epFramesDir, aFrame.cameraId() );
+ if( !TsFileUtils.isDirReadable( epCamDir ) ) {
return null;
}
- if( aFrame.frameNo() < 0 || !aFrame.isDefined() ) {
- return null;
+ String bareName = PsxCofsUtils.bareSourceFrameFileName( aFrame.frameNo() );
+ File frameFile = new File( epCamDir, bareName + '.' + STILL_IMAGE_FILE_EXT );
+ if( frameFile.exists() ) {
+ return frameFile;
}
+ return null;
+ }
+
+ private File internalFindGifFrame( IFrame aFrame ) {
LocalDate ld = EPsxIncidentKind.EPISODE.id2date( aFrame.episodeId() );
File epDir = new File( epsRoot, ld.toString() );
- File epFramesDir;
- if( aFrame.isAnimated() ) {
- epFramesDir = new File( epDir, SUBDIR_EP_ANIM_IMAGES );
+ File epFramesDir = new File( epDir, SUBDIR_EP_ANIM_IMAGES );
+ File epCamDir = new File( epFramesDir, aFrame.cameraId() );
+ if( !TsFileUtils.isDirReadable( epCamDir ) ) {
+ return null;
}
- else {
- epFramesDir = new File( epDir, SUBDIR_EP_STILL_IMAGES );
+ String bareName = PsxCofsUtils.bareSourceFrameFileName( aFrame.frameNo() );
+ File frameFile = new File( epCamDir, bareName + '.' + ANIM_IMAGE_FILE_EXT );
+ if( frameFile.exists() ) {
+ return frameFile;
}
+ return null;
+ }
+
+ private static File internalFindNonSecFrame( IFrame aFrame ) {
+ LocalDate ld = EPsxIncidentKind.EPISODE.id2date( aFrame.episodeId() );
+ File epFramesDir = new File( NONSECS_ROOT, ld.toString() );
File epCamDir = new File( epFramesDir, aFrame.cameraId() );
if( !TsFileUtils.isDirReadable( epCamDir ) ) {
return null;
}
String bareName = PsxCofsUtils.bareSourceFrameFileName( aFrame.frameNo() );
- String ext = aFrame.isAnimated() ? ANIM_IMAGE_FILE_EXT : STILL_IMAGE_FILE_EXT;
- File frameFile = new File( epCamDir, bareName + '.' + ext );
+ File frameFile = new File( epCamDir, bareName + '.' + STILL_IMAGE_FILE_EXT );
if( frameFile.exists() ) {
return frameFile;
}
return null;
}
+ // ------------------------------------------------------------------------------------
+ // ICofsFrames
+ //
+
+ @Override
+ public File findFrameFile( IFrame aFrame ) {
+ TsNullArgumentRtException.checkNull( aFrame );
+ if( epsRoot == null ) {
+ return null;
+ }
+ if( aFrame.frameNo() < 0 || !aFrame.isDefined() ) {
+ return null;
+ }
+ if( aFrame.isAnimated() ) {
+ return internalFindGifFrame( aFrame );
+ }
+ if( aFrame.isSecAligned() ) {
+ return internalFindSecAlignedStillFrame( aFrame );
+ }
+ return internalFindNonSecFrame( aFrame );
+ }
+
@Override
public IFramesSet listEpisodeFrames( String aEpisodeId ) {
LocalDate epDate = EPsxIncidentKind.EPISODE.id2date( aEpisodeId );
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/addons/AddonPrisex24Behaviour.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/addons/AddonPrisex24Behaviour.java
new file mode 100644
index 0000000..8772f84
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/addons/AddonPrisex24Behaviour.java
@@ -0,0 +1,59 @@
+package com.hazard157.prisex24.e4.addons;
+
+import org.eclipse.e4.core.contexts.*;
+import org.toxsoft.core.tsgui.mws.bases.*;
+import org.toxsoft.core.tslib.coll.primtypes.*;
+
+import com.hazard157.lib.core.utils.animkind.*;
+import com.hazard157.prisex24.e4.services.currep.*;
+import com.hazard157.prisex24.e4.services.selsvins.*;
+import com.hazard157.prisex24.glib.frasel.*;
+import com.hazard157.psx.common.stuff.svin.*;
+import com.hazard157.psx.proj3.episodes.*;
+
+/**
+ * Sets up application common behaviour.
+ *
+ * @author hazard157
+ */
+public class AddonPrisex24Behaviour
+ extends MwsAbstractAddon {
+
+ /**
+ * Constructor.
+ */
+ public AddonPrisex24Behaviour() {
+ super( AddonPrisex24Behaviour.class.getSimpleName() );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // implementation
+ //
+
+ // ------------------------------------------------------------------------------------
+ // MwsAbstractAddon
+ //
+
+ @Override
+ protected void initApp( IEclipseContext aAppContext ) {
+ // nop
+ }
+
+ @Override
+ protected void initWin( IEclipseContext aWinContext ) {
+ // on current episode change displays it's animated frames in the shared view
+ ICurrentEpisodeService currEpService = aWinContext.get( ICurrentEpisodeService.class );
+ IPsxSelectedSvinsService selSvinsService = aWinContext.get( IPsxSelectedSvinsService.class );
+ currEpService.addCurrentEntityChangeListener( aCurrent -> {
+ IEpisode currEpisode = currEpService.current();
+ Svin svin = null;
+ if( currEpisode != null ) {
+ svin = new Svin( currEpisode.id() );
+ }
+ selSvinsService.framesSelectionParams().setParams( EAnimationKind.ANIMATED, Boolean.FALSE, IStringList.EMPTY,
+ EFramesPerSvin.SELECTED );
+ selSvinsService.setSvin( svin );
+ } );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/addons/AddonPrisex24Core.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/addons/AddonPrisex24Core.java
index a8842e6..bdceb68 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/addons/AddonPrisex24Core.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/addons/AddonPrisex24Core.java
@@ -27,6 +27,7 @@
import com.hazard157.prisex24.cofs.impl.*;
import com.hazard157.prisex24.e4.services.currep.*;
import com.hazard157.prisex24.e4.services.psx.*;
+import com.hazard157.prisex24.e4.services.selsvins.*;
import com.hazard157.prisex24.m5.episodes.*;
import com.hazard157.prisex24.m5.frames.*;
import com.hazard157.prisex24.m5.tags.*;
@@ -35,7 +36,7 @@
import com.hazard157.psx.proj3.*;
/**
- * Plugin addon.
+ * Plugin addon - initializes all subsystems and modules..
*
* @author hazard157
*/
@@ -72,6 +73,7 @@ protected void initApp( IEclipseContext aAppContext ) {
aAppContext.set( IPsxCofs.class, new PsxCofs() );
// E4 services
aAppContext.set( ICurrentEpisodeService.class, new CurrentEpisodeService( aAppContext ) );
+ aAppContext.set( IPsxSelectedSvinsService.class, new PsxSelectedSvinsService() );
}
@Override
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/services/selsvins/IPsxSelectedSvinsService.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/services/selsvins/IPsxSelectedSvinsService.java
new file mode 100644
index 0000000..902b8e2
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/services/selsvins/IPsxSelectedSvinsService.java
@@ -0,0 +1,66 @@
+package com.hazard157.prisex24.e4.services.selsvins;
+
+import org.toxsoft.core.tslib.bricks.events.change.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.glib.frasel.*;
+import com.hazard157.psx.common.stuff.svin.*;
+
+/**
+ * Service introduces concept of "selected SVINSs to be viewed as frames".
+ *
+ * @author hazard157
+ */
+public interface IPsxSelectedSvinsService {
+
+ /**
+ * Returns list of SVINs.
+ *
+ * @return {@link IList}<{@link Svin}> - list of SVINs
+ */
+ IListnull
+ */
+ void setSvins( IList