listFilms( IOptionSet aParams );
/**
* Returns the GIF-animated summary of the film.
*
* Creates new GIF-animation if there is no one or film was changed after last GIF creation.
*
- * @param aFilmFile {@link OptedFile} - film file
+ * @param aFilmFile {@link IOptedFile} - film file
* @return {@link File} - summary GIF file or null
if can not be created
* @throws TsNullArgumentRtException any argument = null
*/
- File getSummaryGif( OptedFile aFilmFile );
+ File getSummaryGif( IOptedFile aFilmFile );
/**
* Returns the Kdenlive project file without existence check.
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsGazes.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsGazes.java
index 7a72e2f..df9d6a4 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsGazes.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsGazes.java
@@ -5,7 +5,7 @@
import org.toxsoft.core.tslib.coll.*;
import org.toxsoft.core.tslib.utils.errors.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
/**
* COFS - access to the gaze source and output media files.
@@ -21,9 +21,9 @@ public interface ICofsGazes {
*
* @param aDate {@link LocalDate} - the gaze date
* @param aMediaKind {@link EIncidentMediaKind} - the requested media kind
- * @return {@link IList}<{@link OptedFile}> - all files in date directory
+ * @return {@link IList}<{@link IOptedFile}> - all files in date directory
* @throws TsNullArgumentRtException any argument = null
*/
- IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMediaKind );
+ IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMediaKind );
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsMingles.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsMingles.java
index 81887c9..27fc46f 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsMingles.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsMingles.java
@@ -5,7 +5,7 @@
import org.toxsoft.core.tslib.coll.*;
import org.toxsoft.core.tslib.utils.errors.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
/**
* COFS - access to the mingle source and output media files.
@@ -21,9 +21,9 @@ public interface ICofsMingles {
*
* @param aDate {@link LocalDate} - the mingle date
* @param aMediaKind {@link EIncidentMediaKind} - the requested media kind
- * @return {@link IList}<{@link OptedFile}> - all files in date directory
+ * @return {@link IList}<{@link IOptedFile}> - all files in date directory
* @throws TsNullArgumentRtException any argument = null
*/
- IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMediaKind );
+ IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMediaKind );
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsTrailers.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsTrailers.java
index 4c55764..65e0536 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsTrailers.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/ICofsTrailers.java
@@ -5,7 +5,7 @@
import org.toxsoft.core.tslib.coll.*;
import org.toxsoft.core.tslib.utils.errors.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
/**
* COFS - access to the episode trailer files.
@@ -23,28 +23,28 @@ public interface ICofsTrailers {
* @return {@link IList}<{@link File}> - trailer media files with their stored params
* @throws TsNullArgumentRtException any argument = null
*/
- IList listEpisodeTrailerFiles( String aEpisodeId );
+ IList listEpisodeTrailerFiles( String aEpisodeId );
/**
* Finds in {@link #listEpisodeTrailerFiles(String)} specified trailer file.
*
* @param aEpisodeId String - the episode ID
* @param aTrailerName String trailer file name without extension
- * @return {@link OptedFile} - found file or null
+ * @return {@link IOptedFile} - found file or null
* @throws TsNullArgumentRtException any argument = null
*/
- OptedFile findTrailerFile( String aEpisodeId, String aTrailerName );
+ IOptedFile findTrailerFile( String aEpisodeId, String aTrailerName );
/**
* Returns the GIF-animated summary of the trailer.
*
* Creates new GIF-animation if there is no one or trailer was changed after last GIF creation.
*
- * @param aTrailerFile {@link OptedFile} - trailer file
+ * @param aTrailerFile {@link IOptedFile} - trailer file
* @return {@link File} - summary GIF file or null
if can not be created
* @throws TsNullArgumentRtException any argument = null
*/
- File getSummaryGif( OptedFile aTrailerFile );
+ File getSummaryGif( IOptedFile aTrailerFile );
/**
* Returns the Kdenlive project file without existence check.
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/IPsxCofs.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/IPsxCofs.java
index 081d143..6980e55 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/IPsxCofs.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/IPsxCofs.java
@@ -6,7 +6,7 @@
import org.toxsoft.core.tslib.coll.*;
import org.toxsoft.core.tslib.utils.errors.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
/**
* Access to the PRISEX file resources in COFS (Cloud Optimized File System).
@@ -94,15 +94,15 @@ public interface IPsxCofs {
* videos - animated GIF, for other types - just file type icon. For video files creates new GIF-animation if there is
* no one or video file was changed after last GIF creation.
*
- * The parameters {@link OptedFile#params()} may contain additional information about summary file, like which part of
- * video to use for GIF-animation.
+ * The parameters {@link IOptedFile#params()} may contain additional information about summary file, like which part
+ * of video to use for GIF-animation.
*
* Summary files (if specially created) are places in the COFS cache directory.
*
- * @param aMediaFile {@link OptedFile} - the GAZE media file
+ * @param aMediaFile {@link IOptedFile} - the GAZE media file
* @return {@link File} - an existing image file or null
if can not be created
*/
- File ensureSummaryImage( OptedFile aMediaFile );
+ File ensureSummaryImage( IOptedFile aMediaFile );
// ------------------------------------------------------------------------------------
// yet unsorted may be put in some helper interfaces
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsFilms.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsFilms.java
index 6371643..69e7e85 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsFilms.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsFilms.java
@@ -12,7 +12,7 @@
import org.toxsoft.core.tslib.utils.errors.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.cofs.*;
/**
@@ -51,19 +51,19 @@ private static File filmGifFile( File aFilmFile ) {
//
@Override
- public IList listFilms( IOptionSet aParams ) {
+ public IList listFilms( IOptionSet aParams ) {
TsNullArgumentRtException.checkNull( aParams );
- IListBasicEdit result = new SortedElemLinkedBundleList<>();
+ IListBasicEdit result = new SortedElemLinkedBundleList<>();
if( OPDEF_FILMS_QP_INCLUDE_LEGACY.getValue( aParams ).asBool() ) {
File legacyDir = new File( FILMS_ROOT, SUBDIR_LEGACY );
- result.addAll( OptedFile.list( legacyDir, IMediaFileConstants.FF_VIDEOS ) );
+ result.addAll( OptedFileUtils.list( legacyDir, IMediaFileConstants.FF_VIDEOS ) );
}
- result.addAll( OptedFile.list( FILMS_ROOT, IMediaFileConstants.FF_VIDEOS ) );
+ result.addAll( OptedFileUtils.list( FILMS_ROOT, IMediaFileConstants.FF_VIDEOS ) );
return result;
}
@Override
- public File getSummaryGif( OptedFile aFilmFile ) {
+ public File getSummaryGif( IOptedFile aFilmFile ) {
TsNullArgumentRtException.checkNull( aFilmFile );
File gifFile = filmGifFile( aFilmFile.file() );
return PsxCofsUtils.ensureSummaryGif( aFilmFile, gifFile );
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsGazes.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsGazes.java
index e64e55f..d8c76a0 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsGazes.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsGazes.java
@@ -10,7 +10,7 @@
import org.toxsoft.core.tslib.utils.errors.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.cofs.*;
/**
@@ -37,7 +37,7 @@ public CofsGazes() {
//
@Override
- public IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMediaKind ) {
+ public IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMediaKind ) {
TsNullArgumentRtException.checkNulls( aDate, aMediaKind );
File mediaDir;
switch( aMediaKind ) {
@@ -58,7 +58,7 @@ public IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMed
default:
throw new TsNotAllEnumsUsedRtException( aMediaKind.id() );
}
- IListBasicEdit ll = new SortedElemLinkedBundleList<>();
+ IListBasicEdit ll = new SortedElemLinkedBundleList<>();
if( TsFileUtils.isDirReadable( mediaDir ) ) {
IList ff = TsFileUtils1.collectFilesInSubtree( mediaDir, TsFileFilter.FF_FILES );
for( File f : ff ) {
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsMingles.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsMingles.java
index cc8f14d..9f2298a 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsMingles.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsMingles.java
@@ -10,7 +10,7 @@
import org.toxsoft.core.tslib.utils.errors.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.cofs.*;
/**
@@ -37,7 +37,7 @@ public CofsMingles() {
//
@Override
- public IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMediaKind ) {
+ public IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMediaKind ) {
TsNullArgumentRtException.checkNulls( aDate, aMediaKind );
File mediaDir;
switch( aMediaKind ) {
@@ -58,7 +58,7 @@ public IList listMediaFiles( LocalDate aDate, EIncidentMediaKind aMed
default:
throw new TsNotAllEnumsUsedRtException( aMediaKind.id() );
}
- IListBasicEdit ll = new SortedElemLinkedBundleList<>();
+ IListBasicEdit ll = new SortedElemLinkedBundleList<>();
if( TsFileUtils.isDirReadable( mediaDir ) ) {
IList ff = TsFileUtils1.collectFilesInSubtree( mediaDir, TsFileFilter.FF_FILES );
for( File f : ff ) {
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsTrailers.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsTrailers.java
index ff9b0f1..797dbf9 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsTrailers.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/CofsTrailers.java
@@ -12,7 +12,7 @@
import org.toxsoft.core.tslib.utils.errors.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.cofs.*;
import com.hazard157.psx.proj3.incident.*;
@@ -69,7 +69,7 @@ private static File episodeDir( String aEpisodeId ) {
//
@Override
- public IList listEpisodeTrailerFiles( String aEpisodeId ) {
+ public IList listEpisodeTrailerFiles( String aEpisodeId ) {
File epDir = episodeDir( aEpisodeId );
if( epDir == null ) {
return IList.EMPTY;
@@ -79,15 +79,15 @@ public IList listEpisodeTrailerFiles( String aEpisodeId ) {
return IList.EMPTY;
}
// collect video files
- IListBasicEdit result = new SortedElemLinkedBundleList<>();
- result.addAll( OptedFile.list( trDir, IMediaFileConstants.FF_VIDEOS ) );
+ IListBasicEdit result = new SortedElemLinkedBundleList<>();
+ result.addAll( OptedFileUtils.list( trDir, IMediaFileConstants.FF_VIDEOS ) );
return result;
}
@Override
- public OptedFile findTrailerFile( String aEpisodeId, String aTrailerName ) {
+ public IOptedFile findTrailerFile( String aEpisodeId, String aTrailerName ) {
TsNullArgumentRtException.checkNulls( aEpisodeId, aTrailerName );
- for( OptedFile f : listEpisodeTrailerFiles( aEpisodeId ) ) {
+ for( IOptedFile f : listEpisodeTrailerFiles( aEpisodeId ) ) {
String bareName = TsFileUtils.extractBareFileName( f.file().getName() );
if( bareName.equals( aTrailerName ) ) {
return f;
@@ -97,7 +97,7 @@ public OptedFile findTrailerFile( String aEpisodeId, String aTrailerName ) {
}
@Override
- public File getSummaryGif( OptedFile aTrailerFile ) {
+ public File getSummaryGif( IOptedFile aTrailerFile ) {
TsNullArgumentRtException.checkNull( aTrailerFile );
// extract episode date from trailer file path
String episodeId = episodeIdFormTrailerFile( aTrailerFile.file() );
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/IPsxCofsInternalConstants.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/IPsxCofsInternalConstants.java
index 4239386..df545a1 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/IPsxCofsInternalConstants.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/IPsxCofsInternalConstants.java
@@ -16,7 +16,7 @@
import org.toxsoft.core.tslib.coll.primtypes.impl.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
/**
* Constants with persistent values.
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/PsxCofs.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/PsxCofs.java
index 676980e..bc681fd 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/PsxCofs.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/PsxCofs.java
@@ -10,12 +10,11 @@
import org.toxsoft.core.tslib.coll.*;
import org.toxsoft.core.tslib.coll.impl.*;
-import org.toxsoft.core.tslib.coll.primtypes.impl.*;
import org.toxsoft.core.tslib.utils.errors.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
-import com.hazard157.common.utils.mop.*;
+import com.hazard157.common.incub.opfil.*;
+import com.hazard157.common.quants.mop.*;
import com.hazard157.prisex24.cofs.*;
import com.hazard157.psx.common.utils.*;
import com.hazard157.psx.proj3.incident.*;
@@ -80,7 +79,7 @@ public ICofsMingles cofsMingles() {
}
@Override
- public File ensureSummaryImage( OptedFile aMediaFile ) {
+ public File ensureSummaryImage( IOptedFile aMediaFile ) {
TsNullArgumentRtException.checkNull( aMediaFile );
EMediaFileKind fileKind = EMediaFileKind.determineFileKind( aMediaFile.file() );
switch( fileKind ) {
@@ -117,7 +116,7 @@ public IList listEpisodeKdenliveProjects( String aEpisodeId ) {
if( !TsFileUtils.isDirReadable( epDir ) ) {
return IList.EMPTY;
}
- IList allProjFiles = TsFileUtils1.collectFilesInSubtree( epDir, new SingleStringList( KDENLIVE_EXT ) );
+ IList allProjFiles = TsFileUtils1.collectFilesInSubtree( epDir, TsFileFilter.ofFileExt( KDENLIVE_EXT ) );
if( allProjFiles.isEmpty() ) {
return IList.EMPTY;
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/PsxCofsUtils.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/PsxCofsUtils.java
index 911a138..ca902af 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/PsxCofsUtils.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/cofs/impl/PsxCofsUtils.java
@@ -21,7 +21,7 @@
import org.toxsoft.core.tslib.utils.errors.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.psx.common.stuff.frame.*;
/**
@@ -44,14 +44,14 @@ protected boolean doAccept( File aPathName, boolean aIsFile ) {
/**
* Ensures that fresh summary GIF file exists.
*
- * Out-dated or non-existing GIF will be recreated using {@link #createSummaryGif(OptedFile, File)}.
+ * Out-dated or non-existing GIF will be recreated using {@link #createSummaryGif(IOptedFile, File)}.
*
- * @param aVideoFile {@link OptedFile} - the video file
+ * @param aVideoFile {@link IOptedFile} - the video file
* @param aGifFile {@link File} - GIF file to be created
* @return {@link File} - the argument aGifFile
or null
if can't be created
* @throws TsNullArgumentRtException any argument = null
*/
- public static File ensureSummaryGif( OptedFile aVideoFile, File aGifFile ) {
+ public static File ensureSummaryGif( IOptedFile aVideoFile, File aGifFile ) {
TsNullArgumentRtException.checkNulls( aVideoFile, aGifFile );
// out-dated or non-existing GIF will be recreated
if( !aGifFile.exists() || aGifFile.lastModified() < aVideoFile.file().lastModified() ) {
@@ -69,14 +69,14 @@ public static File ensureSummaryGif( OptedFile aVideoFile, File aGifFile ) {
/**
* Creates the summary GIF animation for the specified video file.
*
- * TODO if OptedFile.params() has ClipThumb definition - use it
+ * TODO if IOptedFile.params() has ClipThumb definition - use it
*
- * @param aVideoFile {@link OptedFile} - the video file
+ * @param aVideoFile {@link IOptedFile} - the video file
* @param aGifFile {@link File} - GIF file to be created
* @return {@link ValidationResult} - how the operation was performed
* @throws TsNullArgumentRtException any argument = null
*/
- public static ValidationResult createSummaryGif( OptedFile aVideoFile, File aGifFile ) {
+ public static ValidationResult createSummaryGif( IOptedFile aVideoFile, File aGifFile ) {
TsNullArgumentRtException.checkNulls( aVideoFile, aGifFile );
/**
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 96efb7d..e224227 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
@@ -8,7 +8,6 @@
import org.eclipse.e4.ui.model.application.*;
import org.eclipse.e4.ui.model.application.ui.basic.*;
import org.eclipse.e4.ui.workbench.modeling.*;
-import org.eclipse.swt.graphics.*;
import org.toxsoft.core.tsgui.bricks.ctx.*;
import org.toxsoft.core.tsgui.bricks.ctx.impl.*;
import org.toxsoft.core.tsgui.bricks.quant.*;
@@ -18,7 +17,6 @@
import org.toxsoft.core.tsgui.mws.bases.*;
import org.toxsoft.core.tsgui.rcp.*;
import org.toxsoft.core.tsgui.valed.api.*;
-import org.toxsoft.core.tslib.utils.*;
import org.toxsoft.core.txtproj.lib.*;
import com.hazard157.common.*;
@@ -47,6 +45,7 @@
import com.hazard157.prisex24.m5.plep.*;
import com.hazard157.prisex24.m5.snippet.*;
import com.hazard157.prisex24.m5.srcvideo.*;
+import com.hazard157.prisex24.m5.svin.*;
import com.hazard157.prisex24.m5.tags.*;
import com.hazard157.prisex24.m5.todos.*;
import com.hazard157.prisex24.pdus.snippets.*;
@@ -130,6 +129,7 @@ protected void initWin( IEclipseContext aWinContext ) {
m5.addModel( new PlepM5Model() );
m5.addModel( new GazeM5Model() );
m5.addModel( new MingleM5Model() );
+ m5.addModel( new SvinM5Model() );
// VALEDs
IValedControlFactoriesRegistry vcfReg = aWinContext.get( IValedControlFactoriesRegistry.class );
vcfReg.registerFactory( ValedFrameFactory.FACTORY );
@@ -141,12 +141,12 @@ protected void initWin( IEclipseContext aWinContext ) {
//
aWinContext.set( IWelcomePerspectiveController.class, new WelcomePerspectiveController( ctx ) );
- // DEBUG --- resource tracking
- Resource.setNonDisposeHandler( aT -> {
- TsTestUtils.pl( "ResourseErr: %s", aT.toString() ); //$NON-NLS-1$
- TsTestUtils.p( "" ); //$NON-NLS-1$
- } );
- // ---
+ // // DEBUG --- resource tracking
+ // Resource.setNonDisposeHandler( aT -> {
+ // TsTestUtils.pl( "ResourseErr: %s", aT.toString() ); //$NON-NLS-1$
+ // TsTestUtils.p( "" ); //$NON-NLS-1$
+ // } );
+ // // ---
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/gazes/UipartGazeMediaBase.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/gazes/UipartGazeMediaBase.java
index 1c5ed3f..2d4814a 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/gazes/UipartGazeMediaBase.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/gazes/UipartGazeMediaBase.java
@@ -27,7 +27,7 @@
import org.toxsoft.core.tslib.coll.notifier.basis.*;
import org.toxsoft.core.tslib.utils.errors.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.common.utils.*;
import com.hazard157.prisex24.cofs.*;
import com.hazard157.prisex24.e4.services.gazes.*;
@@ -66,12 +66,12 @@ public class UipartGazeMediaBase
}
};
- private final ITsDoubleClickListener doubleClickListener = ( aSource, aSelectedItem ) -> {
+ private final ITsDoubleClickListener doubleClickListener = ( aSource, aSelectedItem ) -> {
playItem( aSelectedItem );
updateActionsState();
};
- private final ITsSelectionChangeListener selectionListenet =
+ private final ITsSelectionChangeListener selectionListenet =
( aSource, aSelectedItem ) -> updateActionsState();
@Inject
@@ -79,8 +79,8 @@ public class UipartGazeMediaBase
final EIncidentMediaKind incidentMediaKind;
- TsToolbar toolbar;
- IPicsGridViewer pgViewer;
+ TsToolbar toolbar;
+ IPicsGridViewer pgViewer;
protected UipartGazeMediaBase( EIncidentMediaKind aMediaKind ) {
incidentMediaKind = TsNullArgumentRtException.checkNull( aMediaKind );
@@ -119,7 +119,7 @@ protected void doInit( Composite aParent ) {
}
boolean processAction( String aActionId ) {
- OptedFile sel = pgViewer.selectedItem();
+ IOptedFile sel = pgViewer.selectedItem();
switch( aActionId ) {
case AID_THUMB_SIZEABLE_ZOOM_MENU: {
pgViewer.setThumbSize( pgViewer.defaultThumbSize() );
@@ -137,7 +137,7 @@ boolean processAction( String aActionId ) {
}
void updateActionsState() {
- OptedFile sel = pgViewer.selectedItem();
+ IOptedFile sel = pgViewer.selectedItem();
boolean isSel = sel != null;
toolbar.setActionEnabled( ACTID_PLAY, isSel );
}
@@ -147,12 +147,12 @@ void showContentOfGaze( IGaze aGaze ) {
pgViewer.setItems( IList.EMPTY );
return;
}
- IList ll = cofsGazes().listMediaFiles( aGaze.incidentDate(), incidentMediaKind );
+ IList ll = cofsGazes().listMediaFiles( aGaze.incidentDate(), incidentMediaKind );
pgViewer.setItems( ll );
updateActionsState();
}
- void playItem( OptedFile aFile ) {
+ void playItem( IOptedFile aFile ) {
if( aFile != null ) {
HzUtils.runDefaultMediaApp( aFile.file() );
}
@@ -165,7 +165,7 @@ void playItem( OptedFile aFile ) {
@Override
public boolean onKeyDown( Object aSource, int aCode, char aChar, int aState ) {
- OptedFile sel = pgViewer.selectedItem();
+ IOptedFile sel = pgViewer.selectedItem();
switch( aCode ) {
case SWT.CR:
case SWT.KEYPAD_CR:
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/mingles/UipartMingleMediaBase.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/mingles/UipartMingleMediaBase.java
index 6d76c7c..140f735 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/mingles/UipartMingleMediaBase.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/mingles/UipartMingleMediaBase.java
@@ -27,7 +27,7 @@
import org.toxsoft.core.tslib.coll.notifier.basis.*;
import org.toxsoft.core.tslib.utils.errors.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.common.utils.*;
import com.hazard157.prisex24.cofs.*;
import com.hazard157.prisex24.e4.services.gazes.*;
@@ -66,12 +66,12 @@ public class UipartMingleMediaBase
}
};
- private final ITsDoubleClickListener doubleClickListener = ( aSource, aSelectedItem ) -> {
+ private final ITsDoubleClickListener doubleClickListener = ( aSource, aSelectedItem ) -> {
playItem( aSelectedItem );
updateActionsState();
};
- private final ITsSelectionChangeListener selectionListenet =
+ private final ITsSelectionChangeListener selectionListenet =
( aSource, aSelectedItem ) -> updateActionsState();
@Inject
@@ -79,8 +79,8 @@ public class UipartMingleMediaBase
final EIncidentMediaKind incidentMediaKind;
- TsToolbar toolbar;
- IPicsGridViewer pgViewer;
+ TsToolbar toolbar;
+ IPicsGridViewer pgViewer;
protected UipartMingleMediaBase( EIncidentMediaKind aMediaKind ) {
incidentMediaKind = TsNullArgumentRtException.checkNull( aMediaKind );
@@ -119,7 +119,7 @@ protected void doInit( Composite aParent ) {
}
boolean processAction( String aActionId ) {
- OptedFile sel = pgViewer.selectedItem();
+ IOptedFile sel = pgViewer.selectedItem();
switch( aActionId ) {
case AID_THUMB_SIZEABLE_ZOOM_MENU: {
pgViewer.setThumbSize( pgViewer.defaultThumbSize() );
@@ -137,7 +137,7 @@ boolean processAction( String aActionId ) {
}
void updateActionsState() {
- OptedFile sel = pgViewer.selectedItem();
+ IOptedFile sel = pgViewer.selectedItem();
boolean isSel = sel != null;
toolbar.setActionEnabled( ACTID_PLAY, isSel );
}
@@ -147,12 +147,12 @@ void showContentOfMingle( IMingle aMingle ) {
pgViewer.setItems( IList.EMPTY );
return;
}
- IList ll = cofsMingles().listMediaFiles( aMingle.incidentDate(), incidentMediaKind );
+ IList ll = cofsMingles().listMediaFiles( aMingle.incidentDate(), incidentMediaKind );
pgViewer.setItems( ll );
updateActionsState();
}
- void playItem( OptedFile aFile ) {
+ void playItem( IOptedFile aFile ) {
if( aFile != null ) {
HzUtils.runDefaultMediaApp( aFile.file() );
}
@@ -165,7 +165,7 @@ void playItem( OptedFile aFile ) {
@Override
public boolean onKeyDown( Object aSource, int aCode, char aChar, int aState ) {
- OptedFile sel = pgViewer.selectedItem();
+ IOptedFile sel = pgViewer.selectedItem();
switch( aCode ) {
case SWT.CR:
case SWT.KEYPAD_CR:
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/CmdPlayEpisode.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/CmdPlayEpisode.java
index 235ff0c..32d8b6e 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/CmdPlayEpisode.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/CmdPlayEpisode.java
@@ -3,7 +3,7 @@
import org.eclipse.e4.core.di.annotations.*;
import com.hazard157.common.e4.services.mps.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.cofs.*;
import com.hazard157.psx.proj3.episodes.*;
@@ -19,7 +19,7 @@ void exec( IWelcomePerspectiveController aWelcomePerspectiveController, IPsxCofs
IEpisode sel = aWelcomePerspectiveController.uipartEpisodes().selectedItem();
if( sel != null ) {
String traileName = sel.info().defaultTrailerId();
- OptedFile f = aCofs.cofsTrailers().findTrailerFile( sel.id(), traileName );
+ IOptedFile f = aCofs.cofsTrailers().findTrailerFile( sel.id(), traileName );
if( f != null ) {
aMps.playVideoFile( f.file() );
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/CmdPlayFilm.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/CmdPlayFilm.java
index f8e83d4..57202d2 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/CmdPlayFilm.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/CmdPlayFilm.java
@@ -3,7 +3,7 @@
import org.eclipse.e4.core.di.annotations.*;
import com.hazard157.common.e4.services.mps.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
/**
* Command play film selected in {@link UipartWelcomeFilmsThumbs}.
@@ -14,7 +14,7 @@ public class CmdPlayFilm {
@Execute
void exec( IWelcomePerspectiveController aWelcomePerspectiveController, IMediaPlayerService aMps ) {
- OptedFile sel = aWelcomePerspectiveController.uipartFilms().selectedItem();
+ IOptedFile sel = aWelcomePerspectiveController.uipartFilms().selectedItem();
if( sel != null ) {
aMps.playVideoFile( sel.file() );
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartCurrentEpisodeIllustrationsGrid.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartCurrentEpisodeIllustrationsGrid.java
index e75e50b..0202068 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartCurrentEpisodeIllustrationsGrid.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartCurrentEpisodeIllustrationsGrid.java
@@ -1,6 +1,7 @@
package com.hazard157.prisex24.e4.uiparts.welcome;
import static com.hazard157.common.IHzConstants.*;
+import static com.hazard157.prisex24.IPrisex24CoreConstants.*;
import static com.hazard157.prisex24.glib.frview.impl.PgvVisualsProviderFrame.*;
import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
@@ -18,6 +19,7 @@
import com.hazard157.prisex24.e4.uiparts.*;
import com.hazard157.prisex24.glib.frview.*;
import com.hazard157.prisex24.glib.frview.impl.*;
+import com.hazard157.psx.common.stuff.frame.*;
import com.hazard157.psx.common.stuff.svin.*;
import com.hazard157.psx.proj3.episodes.*;
@@ -43,7 +45,8 @@ protected void doInit( Composite aParent ) {
IPicsGridViewerConstants.OPDEF_DEFAULT_THUMB_SIZE.setValue( ctx.params(), avValobj( thumbSize ) );
fgViewer = new FramesGridViewer( aParent, ctx );
fgViewer.setDisplayedInfoFlags( LF_CAM | LF_HMS );
- prefBundle( PBID_HZ_COMMON ).prefs().addCollectionChangeListener( ( s, o, i ) -> whenHzCommonAppPrefsChanged() );
+ prefBundle( PBID_HZ_COMMON ).prefs().addCollectionChangeListener( ( s, o, i ) -> whenAppPrefsChanged() );
+ prefBundle( PBID_WELCOME ).prefs().addCollectionChangeListener( ( s, o, i ) -> whenAppPrefsChanged() );
fgViewer.addTsDoubleClickListener( ( src, sel ) -> {
if( sel != null ) {
int start = sel.secNo() > 5 ? sel.secNo() - 4 : 0;
@@ -51,15 +54,31 @@ protected void doInit( Composite aParent ) {
psxService().playEpisodeVideo( svin );
}
} );
+ whenAppPrefsChanged();
whenCurrEpisodeChanges();
}
- private void whenHzCommonAppPrefsChanged() {
+ private void whenAppPrefsChanged() {
+ preloadImages();
EThumbSize thumbSize = apprefValue( PBID_HZ_COMMON, APPREF_THUMB_SIZE_IN_GRIDS ).asValobj();
+ boolean isForceStill = apprefValue( PBID_WELCOME, APPREF_WELCOME_IS_FORCE_STILL ).asBool();
+ fgViewer.setFocreStill( isForceStill );
fgViewer.thumbSizeManager().setThumbSize( thumbSize );
}
+ private void preloadImages() {
+ IEpisode sel = currentEpisodeService.current();
+ if( sel == null ) {
+ return;
+ }
+ EThumbSize thumbSize = apprefValue( PBID_HZ_COMMON, APPREF_THUMB_SIZE_IN_GRIDS ).asValobj();
+ for( IFrame f : sel.getIllustrations( false ) ) {
+ psxService().findThumb( f, thumbSize );
+ }
+ }
+
protected void whenCurrEpisodeChanges() {
+ preloadImages();
IEpisode sel = currentEpisodeService.current();
String label;
if( sel != null ) {
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartWelcomeEpisodeThumbs.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartWelcomeEpisodeThumbs.java
index d633959..d697b9e 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartWelcomeEpisodeThumbs.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartWelcomeEpisodeThumbs.java
@@ -21,7 +21,7 @@
import org.toxsoft.core.tslib.coll.primtypes.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.e4.services.currep.*;
import com.hazard157.prisex24.e4.uiparts.*;
import com.hazard157.prisex24.glib.*;
@@ -63,13 +63,27 @@ protected void doInit( Composite aParent ) {
//
private void initViewerContent() {
+ preloadImages();
IEpisode sel = pgViewer.selectedItem();
- EThumbSize thumbSize = APPREF_THUMB_SIZE_IN_GRIDS.getValue( prefBundle( PBID_HZ_COMMON ).prefs() ).asValobj();
+ EThumbSize thumbSize = apprefValue( PBID_HZ_COMMON, APPREF_THUMB_SIZE_IN_GRIDS ).asValobj();
+ boolean isForceStill = apprefValue( PBID_WELCOME, APPREF_WELCOME_IS_FORCE_STILL ).asBool();
+ pgViewer.setFocreStill( isForceStill );
pgViewer.setThumbSize( thumbSize );
pgViewer.setItems( unitEpisodes().items() );
pgViewer.setSelectedItem( sel );
}
+ protected void preloadImages() {
+ // TODO add progress dialog
+ EThumbSize thumbSize = apprefValue( PBID_HZ_COMMON, APPREF_THUMB_SIZE_IN_GRIDS ).asValobj();
+ for( IEpisode e : unitEpisodes().items() ) {
+ File ff = cofsFrames().findFrameFile( e.frame() );
+ if( ff != null ) {
+ imageManager().findThumb( ff, thumbSize );
+ }
+ }
+ }
+
private void whenThumbmDoubleClicked( IEpisode aSel ) {
if( aSel != null ) {
mwsLocationService().locate( EpisodePropertyLocator.ofEpisode( aSel ) );
@@ -102,9 +116,9 @@ void updateTrailesDropDownMenuOfViewToolButton( IEpisode aSelectedEpisode ) {
String defIconUri = iconManager().findStdIconBundleUri( ICONID_ARROW_RIGHT, EIconSize.IS_16X16 );
String nonIconUri = iconManager().findStdIconBundleUri( ICONID_TRANSPARENT, EIconSize.IS_16X16 );
// add all known trailers to menu
- IList trailerFiles = cofsTrailers().listEpisodeTrailerFiles( aSelectedEpisode.episodeId() );
+ IList trailerFiles = cofsTrailers().listEpisodeTrailerFiles( aSelectedEpisode.episodeId() );
MMenu menu = MMenuFactory.INSTANCE.createMenu();
- for( OptedFile trOp : trailerFiles ) {
+ for( IOptedFile trOp : trailerFiles ) {
MDirectMenuItem dynamicItem = MMenuFactory.INSTANCE.createDirectMenuItem();
String name = TsFileUtils.extractBareFileName( trOp.file().getName() );
dynamicItem.setLabel( String.format( FMT_T_PLAY_TRAILER, name ) );
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartWelcomeFilmsThumbs.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartWelcomeFilmsThumbs.java
index 644e833..c71a742 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartWelcomeFilmsThumbs.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/e4/uiparts/welcome/UipartWelcomeFilmsThumbs.java
@@ -14,7 +14,7 @@
import org.toxsoft.core.tslib.av.opset.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.e4.uiparts.*;
/**
@@ -24,22 +24,22 @@
*/
public class UipartWelcomeFilmsThumbs
extends PsxAbstractUipart
- implements ITsSelectionProvider {
+ implements ITsSelectionProvider {
- private final ITsVisualsProvider visualsProvider = new ITsVisualsProvider<>() {
+ private final ITsVisualsProvider visualsProvider = new ITsVisualsProvider<>() {
@Override
- public String getName( OptedFile aEntity ) {
+ public String getName( IOptedFile aEntity ) {
return aEntity != null ? TsFileUtils.extractBareFileName( aEntity.file().getName() ) : EMPTY_STRING;
}
@Override
- public String getDescription( OptedFile aEntity ) {
+ public String getDescription( IOptedFile aEntity ) {
return aEntity != null ? aEntity.file().getAbsolutePath() : EMPTY_STRING;
}
@Override
- public TsImage getThumb( OptedFile aEntity, EThumbSize aThumbSize ) {
+ public TsImage getThumb( IOptedFile aEntity, EThumbSize aThumbSize ) {
if( aEntity != null ) {
File f = cofsFilms().getSummaryGif( aEntity );
if( f != null ) {
@@ -51,7 +51,7 @@ public TsImage getThumb( OptedFile aEntity, EThumbSize aThumbSize ) {
};
- IPicsGridViewer pgViewer;
+ IPicsGridViewer pgViewer;
// ------------------------------------------------------------------------------------
// AbstractPsx12Uipart
@@ -76,20 +76,33 @@ protected void doInit( Composite aParent ) {
//
private void initViewerContent() {
- OptedFile sel = pgViewer.selectedItem();
- EThumbSize thumbSize = APPREF_THUMB_SIZE_IN_GRIDS.getValue( prefBundle( PBID_HZ_COMMON ).prefs() ).asValobj();
+ preloadImages();
+ IOptedFile sel = pgViewer.selectedItem();
+ EThumbSize thumbSize = apprefValue( PBID_HZ_COMMON, APPREF_THUMB_SIZE_IN_GRIDS ).asValobj();
+ boolean isForceStill = apprefValue( PBID_WELCOME, APPREF_WELCOME_IS_FORCE_STILL ).asBool();
+ pgViewer.setFocreStill( isForceStill );
pgViewer.setThumbSize( thumbSize );
pgViewer.setItems( cofsFilms().listFilms( IOptionSet.NULL ) );
pgViewer.setSelectedItem( sel );
}
- private void whenFilmDoubleClicked( OptedFile aSel ) {
+ private void preloadImages() {
+ EThumbSize thumbSize = apprefValue( PBID_HZ_COMMON, APPREF_THUMB_SIZE_IN_GRIDS ).asValobj();
+ for( IOptedFile optedFile : cofsFilms().listFilms( IOptionSet.NULL ) ) {
+ File f = cofsFilms().getSummaryGif( optedFile );
+ if( f != null ) {
+ imageManager().findThumb( f, thumbSize );
+ }
+ }
+ }
+
+ private void whenFilmDoubleClicked( IOptedFile aSel ) {
if( aSel != null ) {
mps().playVideoFile( aSel.file() );
}
}
- private void whenFilmSelectionChanges( @SuppressWarnings( "unused" ) OptedFile aSel ) {
+ private void whenFilmSelectionChanges( @SuppressWarnings( "unused" ) IOptedFile aSel ) {
e4Helper().updateHandlersCanExecuteState();
}
@@ -98,22 +111,22 @@ private void whenFilmSelectionChanges( @SuppressWarnings( "unused" ) OptedFile a
//
@Override
- public void addTsSelectionListener( ITsSelectionChangeListener aListener ) {
+ public void addTsSelectionListener( ITsSelectionChangeListener aListener ) {
pgViewer.addTsSelectionListener( aListener );
}
@Override
- public void removeTsSelectionListener( ITsSelectionChangeListener aListener ) {
+ public void removeTsSelectionListener( ITsSelectionChangeListener aListener ) {
pgViewer.addTsSelectionListener( aListener );
}
@Override
- public OptedFile selectedItem() {
+ public IOptedFile selectedItem() {
return pgViewer.selectedItem();
}
@Override
- public void setSelectedItem( OptedFile aItem ) {
+ public void setSelectedItem( IOptedFile aItem ) {
pgViewer.setSelectedItem( aItem );
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/AbstractFilterPanel.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/AbstractFilterPanel.java
new file mode 100644
index 0000000..84c63b6
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/AbstractFilterPanel.java
@@ -0,0 +1,98 @@
+package com.hazard157.prisex24.explorer;
+
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.dialogs.datarec.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.psx.proj3.episodes.*;
+import com.hazard157.psx.proj3.tags.*;
+
+/**
+ * Базовый класс панели настройки (создания параметров) единичного фильтра заданного типа.
+ *
+ * @author hazard157
+ */
+public abstract class AbstractFilterPanel
+ extends AbstractTsDialogPanel {
+
+ private boolean inverted = false;
+
+ /**
+ * Конструктор панели, предназаначенной для использования вне диалога.
+ *
+ * @param aParent {@link Composite} - родительская компонента
+ * @param aData T - начальные данные для отображения, может быть null
+ * @param aContext C - контекст радктирования / показа структры данных T
+ * @param aFlags int - флаги настройки панели, собранные по ИЛИ биты {@link TsDialog}.DF_XXX
+ * @throws TsNullArgumentRtException aParent или aContext = null
+ */
+ public AbstractFilterPanel( Composite aParent, ITsSingleFilterParams aData, ITsGuiContext aContext, int aFlags ) {
+ super( aParent, aContext, aData, aContext, aFlags );
+ }
+
+ /**
+ * Конструктор панели, предназаначенной для вставки в диалог {@link TsDialog}.
+ *
+ * @param aParent {@link Composite} - родительская компонента
+ * @param aOwnerDialog {@link TsDialog} - родительский диалог
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public AbstractFilterPanel( Composite aParent, TsDialog aOwnerDialog ) {
+ super( aParent, aOwnerDialog );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // Для наследников
+ //
+
+ @SuppressWarnings( "javadoc" )
+ public IUnitEpisodes uEpisodes() {
+ return tsContext().get( IUnitEpisodes.class );
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public IUnitTags uTags() {
+ return tsContext().get( IUnitTags.class );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ @SuppressWarnings( "javadoc" )
+ public void setFilterParams( ITsSingleFilterParams aParams ) {
+ if( aParams != null ) {
+ doSetDataRecord( aParams );
+ }
+ else {
+ doSetDataRecord( ITsSingleFilterParams.NONE );
+ }
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public ITsSingleFilterParams getFilterParams() {
+ ITsSingleFilterParams p = doGetDataRecord();
+ if( p != null ) {
+ return p;
+ }
+ return ITsSingleFilterParams.NONE;
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public void setInverted( boolean aInvert ) {
+ inverted = aInvert;
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public boolean isInverted() {
+ return inverted;
+ }
+
+ /**
+ * Сбрасывает фильтр на начальные установки, обычно {@link ITsSingleFilterParams#NONE}.
+ */
+ public abstract void resetFilter();
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/AbstractResultsPanel.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/AbstractResultsPanel.java
new file mode 100644
index 0000000..0904e85
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/AbstractResultsPanel.java
@@ -0,0 +1,103 @@
+package com.hazard157.prisex24.explorer;
+
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.bricks.stdevents.*;
+import org.toxsoft.core.tsgui.bricks.stdevents.impl.*;
+import org.toxsoft.core.tsgui.panels.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.explorer.pq.*;
+import com.hazard157.psx.common.stuff.svin.*;
+
+/**
+ * Базовый класс панели отображения наследниками в разных видах.
+ *
+ * @author hazard157
+ */
+abstract class AbstractResultsPanel
+ extends TsPanel
+ implements ITsSelectionProvider {
+
+ protected final TsSelectionChangeEventHelper selectionChangeEventHelper;
+
+ private PqResultSet results = PqResultSet.EMPTY;
+
+ /**
+ * Constructor.
+ *
+ * Constructor stores reference to the context, does not creates copy.
+ *
+ * @param aParent {@link Composite} - parent component
+ * @param aContext {@link ITsGuiContext} - the context
+ * @throws TsNullArgumentRtException any argument = null
+ */
+ public AbstractResultsPanel( Composite aParent, ITsGuiContext aContext ) {
+ super( aParent, aContext );
+ selectionChangeEventHelper = new TsSelectionChangeEventHelper<>( this );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Возвращает отображаемые результаты
+ *
+ * @return {@link PqResultSet} - отображаемые результаты
+ */
+ public PqResultSet getPqResults() {
+ return results;
+ }
+
+ /**
+ * Задает отображаемые результаты.
+ *
+ * @param aResults {@link PqResultSet} - отображаемые результаты
+ */
+ public void setPqResults( PqResultSet aResults ) {
+ TsNullArgumentRtException.checkNull( aResults );
+ results = aResults;
+ refresh();
+ }
+
+ // ------------------------------------------------------------------------------------
+ // Реализация интерфейса ITsSelectionProvider
+ //
+
+ @Override
+ public void addTsSelectionListener( ITsSelectionChangeListener aListener ) {
+ selectionChangeEventHelper.addTsSelectionListener( aListener );
+ }
+
+ @Override
+ public void removeTsSelectionListener( ITsSelectionChangeListener aListener ) {
+ selectionChangeEventHelper.removeTsSelectionListener( aListener );
+ }
+
+ @Override
+ public abstract Svin selectedItem();
+
+ @Override
+ public abstract void setSelectedItem( Svin aItem );
+
+ // ------------------------------------------------------------------------------------
+ // Для переопределения наследниками
+ //
+
+ protected IList getSelectionSvins() {
+ Svin sel = selectedItem();
+ if( sel != null ) {
+ return new SingleItemList<>( sel );
+ }
+ return IList.EMPTY;
+ }
+
+ public IList getAllSvins() {
+ return results.listAllSvins();
+ }
+
+ protected abstract void refresh();
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/IPsxResources.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/IPsxResources.java
new file mode 100644
index 0000000..7817bc0
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/IPsxResources.java
@@ -0,0 +1,64 @@
+package com.hazard157.prisex24.explorer;
+
+/**
+ * Localizable resources.
+ *
+ * @author hazard157
+ */
+interface IPsxResources {
+
+ String STR_T_AS_LIST = "Список";
+ String STR_P_AS_LIST = "Результаты в виде простого списка";
+ String STR_T_AS_GRID = "Миниатюры";
+ String STR_P_AS_GRID = "Результаты в виде сетки миниатюр";
+ String STR_T_AS_TREE = "Дерево";
+ String STR_P_AS_TREE = "Результаты в виде дерева по эпизодам";
+
+ /**
+ * {@link PanelAllFiltersSet}, {@link PanelAllFiltersSetLadder}
+ */
+ String STR_N_FILTER_EP_IDS = "Выборка по эпизодам";
+ String STR_N_FILTER_ANY_TEXT = "Выборка любого текста";
+ String STR_N_FILTER_TAG_IDS = "Выборка по ярлыкам";
+ String STR_N_CLEAR_FILTER = "Сброс";
+ String STR_D_CLEAR_FILTER = "Сбросить фильтра на начения по умолчанию";
+ String STR_N_INVERT_FILTER = "НЕТ";
+ String STR_D_INVERT_FILTER = "Применить оператор НЕТ к фильтру";
+ String STR_ALL_FP = "Всё";
+ String STR_N_TAB_FILTER_EPISODE_IDS = "Эпизоды";
+ String STR_N_TAB_FILTER_ANY_TEXT = "Текст";
+ String STR_N_TAB_FILTER_TAG_IDS = "Ярлыки";
+
+ /**
+ * {@link PqFilterAnyTextPanel}
+ */
+ String STR_N_TEXT = "Текст";
+ String STR_D_TEXT = "Искомый текст";
+ String STR_N_SEARCH_IN = "Поиск в: ";
+ String STR_D_SEARCH_IN = "Искать вхождение текста в следующих местах";
+ String STR_N_MATCH_MODE = "Режим";
+ String STR_D_MATCH_MODE = "Режим посика текста";
+ String STR_N_CHECK_TAGS = "ярлыках?";
+ String STR_D_CHECK_TAGS = "Поиск текста в пометках ярлыками";
+ String STR_N_CHECK_SCENES = "сценах?";
+ String STR_D_CHECK_SCENES = "Поиск текста в названиях сцен";
+ String STR_N_CHECK_NOTES = "заметках?";
+ String STR_D_CHECK_NOTES = "Поиск текста в заметках к эпизоду";
+ String STR_N_CHECK_PLANES = "планах?";
+ String STR_D_CHECK_PLANES = "Поиск текста в планах съемки";
+
+ /**
+ * {@link PqFilterEpisodeIdsPanel}
+ */
+ String STR_N_EP_IDS = "Эпизоды:";
+ String STR_D_EP_IDS = "Идентификаторы выборанных эпизодов (пусто = все эпизоды)";
+ String STR_T_SEL_EP_IDS_BTN = "...";
+ String STR_P_SEL_EP_IDS_BTN = "Пометка нужных эпизодов в списке всех эпизодов";
+
+ /**
+ * {@link PqFilterTagIdsPanel}
+ */
+ String STR_N_TAGS_IS_ANY = "Ярлыки по ИЛИ";
+ String STR_D_TAGS_IS_ANY = "Признак выбщрки если хотя бы один ярлык есть в интервале, иначе должны быть все ярлыки";
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PanelAllFiltersSet.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PanelAllFiltersSet.java
new file mode 100644
index 0000000..1dbe763
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PanelAllFiltersSet.java
@@ -0,0 +1,291 @@
+package com.hazard157.prisex24.explorer;
+
+import static com.hazard157.prisex24.explorer.IPsxResources.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.bricks.ctx.impl.*;
+import org.toxsoft.core.tsgui.graphics.fonts.*;
+import org.toxsoft.core.tsgui.panels.*;
+import org.toxsoft.core.tsgui.utils.layout.*;
+import org.toxsoft.core.tsgui.widgets.*;
+import org.toxsoft.core.tslib.bricks.events.change.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.explorer.filters.*;
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * Панель фильтров по одному всех типов, которые генерируют один {@link ITsCombiFilterParams}.
+ *
+ * Панель собрает фильтры по AND, имеет возможность любому ставить NOT, и главное, как создает параметры, так и обратно
+ * восстанавливает виджеты из этого {@link ITsCombiFilterParams}.
+ *
+ * При изменении параметров генерирует сообщение {@link IGenericChangeListener#onGenericChangeEvent(Object)}.
+ *
+ * @author hazard157
+ */
+public class PanelAllFiltersSet
+ extends TsPanel
+ implements IGenericChangeEventCapable {
+
+ class FilterHeader
+ extends TsComposite {
+
+ final Button invertButton;
+ final Button clearButton;
+
+ FilterHeader( Composite aParent, String aName ) {
+ super( aParent );
+ this.setLayout( new BorderLayout() );
+ // filter name label font
+ FontData fd = this.getFont().getFontData()[0];
+ fd.setStyle( SWT.BOLD );
+ IFontInfo fontInfo = fontManager().data2info( fd );
+ Font labelFont = fontManager().getFont( fontInfo );
+ // label
+ Label l = new Label( this, SWT.LEFT );
+ l.setFont( labelFont );
+ l.setText( aName );
+ l.setLayoutData( BorderLayout.CENTER );
+ // buttons pane
+ TsComposite buttonPane = new TsComposite( this );
+ RowLayout rowLayout = new RowLayout( SWT.HORIZONTAL );
+ rowLayout.marginBottom = rowLayout.marginLeft = rowLayout.marginRight = rowLayout.marginTop = 0;
+ rowLayout.fill = true;
+ buttonPane.setLayout( rowLayout );
+ buttonPane.setLayoutData( BorderLayout.EAST );
+ // invert button
+ invertButton = new Button( buttonPane, SWT.CHECK );
+ invertButton.setText( STR_N_INVERT_FILTER );
+ invertButton.setToolTipText( STR_D_INVERT_FILTER );
+ // clear button
+ clearButton = new Button( buttonPane, SWT.PUSH | SWT.FLAT );
+ clearButton.setText( STR_N_CLEAR_FILTER );
+ clearButton.setToolTipText( STR_D_CLEAR_FILTER );
+ }
+
+ public void addClearButtonSelectionListener( SelectionListener aListener ) {
+ clearButton.addSelectionListener( aListener );
+ }
+
+ public void addInvertButtonSelectionListener( SelectionListener aListener ) {
+ invertButton.addSelectionListener( aListener );
+ }
+
+ }
+
+ private final IGenericChangeListener anyFilterChamgeListener = new IGenericChangeListener() {
+
+ @Override
+ public void onGenericChangeEvent( Object aSource ) {
+ eventer.fireChangeEvent();
+ }
+ };
+
+ final GenericChangeEventer eventer;
+
+ final FilterHeader pqEpIdsHeader;
+ final PqFilterEpisodeIdsPanel pqEpIds;
+ final FilterHeader pqAnyTextHeader;
+ final PqFilterAnyTextPanel pqAnyText;
+ final FilterHeader pqTagIdsHeader;
+ final PqFilterTagIdsPanel pqTagIds;
+
+ /**
+ * Конструктор панели.
+ *
+ * Конструктор просто запоминает ссылку на контекст, без создания копии.
+ *
+ * @param aParent {@link Composite} - родительская панель
+ * @param aContext {@link ITsGuiContext} - контекст панели
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public PanelAllFiltersSet( Composite aParent, ITsGuiContext aContext ) {
+ super( aParent, aContext );
+ eventer = new GenericChangeEventer( this );
+ this.setLayout( new BorderLayout() );
+ ITsGuiContext ctx;
+
+ // tabFolder
+ TabFolder tabFolder = new TabFolder( this, SWT.TOP );
+ tabFolder.setLayoutData( BorderLayout.CENTER );
+
+ // tagIds
+ TabItem tiTagIds = new TabItem( tabFolder, SWT.NONE );
+ tiTagIds.setText( STR_N_TAB_FILTER_TAG_IDS );
+ Composite boardTagIds = new Composite( tabFolder, SWT.NONE );
+ tiTagIds.setControl( boardTagIds );
+ boardTagIds.setLayout( new BorderLayout() );
+ pqTagIdsHeader = new FilterHeader( boardTagIds, STR_N_FILTER_TAG_IDS );
+ pqTagIdsHeader.setLayoutData( BorderLayout.NORTH );
+ pqTagIdsHeader.addClearButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqTagIds.resetFilter();
+ eventer.fireChangeEvent();
+ }
+ } );
+ pqTagIdsHeader.addInvertButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqTagIds.setInverted( ((Button)aEvent.getSource()).getSelection() );
+ eventer.fireChangeEvent();
+ }
+ } );
+ ctx = new TsGuiContext( tsContext() );
+ pqTagIds = new PqFilterTagIdsPanel( boardTagIds, null, ctx );
+ pqTagIds.setLayoutData( BorderLayout.CENTER );
+ pqTagIds.genericChangeEventer().addListener( anyFilterChamgeListener );
+
+ // anyText
+ TabItem tiAnyText = new TabItem( tabFolder, SWT.NONE );
+ tiAnyText.setText( STR_N_TAB_FILTER_ANY_TEXT );
+ Composite boardAnyText = new Composite( tabFolder, SWT.NONE );
+ tiAnyText.setControl( boardAnyText );
+ boardAnyText.setLayout( new BorderLayout() );
+ pqAnyTextHeader = new FilterHeader( boardAnyText, STR_N_FILTER_ANY_TEXT );
+ pqAnyTextHeader.setLayoutData( BorderLayout.NORTH );
+ pqAnyTextHeader.addClearButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqAnyText.resetFilter();
+ eventer.fireChangeEvent();
+ }
+ } );
+ pqAnyTextHeader.addInvertButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqAnyText.setInverted( ((Button)aEvent.getSource()).getSelection() );
+ eventer.fireChangeEvent();
+ }
+ } );
+ ctx = new TsGuiContext( tsContext() );
+ pqAnyText = new PqFilterAnyTextPanel( boardAnyText, null, ctx );
+ pqAnyText.setLayoutData( BorderLayout.CENTER );
+ pqAnyText.genericChangeEventer().addListener( anyFilterChamgeListener );
+
+ // epIds
+ TabItem tiEpIds = new TabItem( tabFolder, SWT.NONE );
+ tiEpIds.setText( STR_N_TAB_FILTER_EPISODE_IDS );
+ Composite boardEpIds = new Composite( tabFolder, SWT.NONE );
+ tiEpIds.setControl( boardEpIds );
+ boardEpIds.setLayout( new BorderLayout() );
+ pqEpIdsHeader = new FilterHeader( boardEpIds, STR_N_FILTER_EP_IDS );
+ pqEpIdsHeader.setLayoutData( BorderLayout.NORTH );
+ pqEpIdsHeader.addClearButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqEpIds.resetFilter();
+ eventer.fireChangeEvent();
+ }
+ } );
+ pqEpIdsHeader.addInvertButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqEpIds.setInverted( ((Button)aEvent.getSource()).getSelection() );
+ eventer.fireChangeEvent();
+ }
+ } );
+ ctx = new TsGuiContext( tsContext() );
+ Composite b2 = new Composite( boardEpIds, SWT.NONE );
+ b2.setLayout( new BorderLayout() );
+ b2.setLayoutData( BorderLayout.CENTER );
+ pqEpIds = new PqFilterEpisodeIdsPanel( b2, null, ctx );
+ pqEpIds.setLayoutData( BorderLayout.NORTH );
+ pqEpIds.genericChangeEventer().addListener( anyFilterChamgeListener );
+
+ }
+
+ // ------------------------------------------------------------------------------------
+ // Реализация интерфейса IGenericChangeEventProducerEx
+ //
+
+ @Override
+ public IGenericChangeEventer genericChangeEventer() {
+ return eventer;
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Возвращает параметры фильтра, заданные в панели.
+ *
+ * @return {@link InquiryItem} - заданноые в панели параметры фильтра
+ */
+ public InquiryItem getInquiryItem() {
+ InquiryItem item = new InquiryItem();
+ ITsSingleFilterParams spEpIds = pqEpIds.getFilterParams();
+ if( spEpIds != ITsSingleFilterParams.NONE ) {
+ item.fpMap().put( EPqSingleFilterKind.EPISODE_IDS, spEpIds );
+ item.setInverted( EPqSingleFilterKind.EPISODE_IDS, pqEpIds.isInverted() );
+ }
+ ITsSingleFilterParams spAnyText = pqAnyText.getFilterParams();
+ if( spAnyText != ITsSingleFilterParams.NONE ) {
+ item.fpMap().put( EPqSingleFilterKind.ANY_TEXT, spAnyText );
+ item.setInverted( EPqSingleFilterKind.ANY_TEXT, pqAnyText.isInverted() );
+ }
+ ITsSingleFilterParams spTagIds = pqTagIds.getFilterParams();
+ if( spTagIds != ITsSingleFilterParams.NONE ) {
+ item.fpMap().put( EPqSingleFilterKind.TAG_IDS, spTagIds );
+ item.setInverted( EPqSingleFilterKind.TAG_IDS, pqTagIds.isInverted() );
+ }
+ return item;
+ }
+
+ /**
+ * Показывает параметры в виджетах панели.
+ *
+ * @param aItem {@link InquiryItem} - параметры фильтра
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public void setFilterParams( InquiryItem aItem ) {
+ TsNullArgumentRtException.checkNull( aItem );
+ eventer.pauseFiring();
+ // TODO сбросить также NOT виджеты
+ // pqEpIds
+ pqEpIds.resetFilter();
+ if( aItem.fpMap().hasKey( EPqSingleFilterKind.EPISODE_IDS ) ) {
+ pqEpIds.setFilterParams( aItem.fpMap().getByKey( EPqSingleFilterKind.EPISODE_IDS ) );
+ pqEpIds.setInverted( aItem.isInverted( EPqSingleFilterKind.EPISODE_IDS ) );
+ pqEpIdsHeader.invertButton.setSelection( pqEpIds.isInverted() );
+ }
+ // pqAnyText
+ pqAnyText.resetFilter();
+ if( aItem.fpMap().hasKey( EPqSingleFilterKind.ANY_TEXT ) ) {
+ pqAnyText.setFilterParams( aItem.fpMap().getByKey( EPqSingleFilterKind.ANY_TEXT ) );
+ pqAnyText.setInverted( aItem.isInverted( EPqSingleFilterKind.ANY_TEXT ) );
+ pqAnyTextHeader.invertButton.setSelection( pqAnyText.isInverted() );
+ }
+ // pqTagIds
+ pqTagIds.resetFilter();
+ if( aItem.fpMap().hasKey( EPqSingleFilterKind.TAG_IDS ) ) {
+ pqTagIds.setFilterParams( aItem.fpMap().getByKey( EPqSingleFilterKind.TAG_IDS ) );
+ pqTagIds.setInverted( aItem.isInverted( EPqSingleFilterKind.TAG_IDS ) );
+ pqTagIdsHeader.invertButton.setSelection( pqTagIds.isInverted() );
+ }
+ eventer.resumeFiring( true );
+ }
+
+ /**
+ * Сбрасывает все панеи в {@link ITsSingleFilterParams#NONE}.
+ */
+ public void resetFilterParans() {
+ pqEpIds.resetFilter();
+ pqAnyText.resetFilter();
+ pqTagIds.resetFilter();
+ }
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PanelAllFiltersSetLadder.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PanelAllFiltersSetLadder.java
new file mode 100644
index 0000000..8ad90e8
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PanelAllFiltersSetLadder.java
@@ -0,0 +1,218 @@
+package com.hazard157.prisex24.explorer;
+
+import static com.hazard157.prisex24.explorer.IPsxResources.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.bricks.ctx.impl.*;
+import org.toxsoft.core.tsgui.graphics.fonts.*;
+import org.toxsoft.core.tsgui.panels.*;
+import org.toxsoft.core.tsgui.utils.layout.*;
+import org.toxsoft.core.tsgui.widgets.*;
+import org.toxsoft.core.tslib.bricks.events.change.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.explorer.filters.*;
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * Панель фильтров по одному всех типов, которые генерируют один {@link ITsCombiFilterParams}.
+ *
+ * Панель собрает фильтры по AND, имеет возможность любому ставить NOT, и главное, как создает параметры, так и обратно
+ * восстанавливает виджеты из этого {@link ITsCombiFilterParams}.
+ *
+ * При изменении параметров генерирует сообщение {@link IGenericChangeListener#onGenericChangeEvent(Object)}.
+ *
+ * @author hazard157
+ */
+public class PanelAllFiltersSetLadder
+ extends TsPanel
+ implements IGenericChangeEventCapable {
+
+ class FilterHeader
+ extends TsComposite {
+
+ final Button clearButton;
+
+ FilterHeader( Composite aParent, String aName ) {
+ super( aParent );
+ this.setLayout( new BorderLayout() );
+ // filter name label font
+ FontData fd = this.getFont().getFontData()[0];
+ fd.setStyle( SWT.BOLD );
+ IFontInfo fontInfo = fontManager().data2info( fd );
+ Font labelFont = fontManager().getFont( fontInfo );
+ // label
+ Label l = new Label( this, SWT.LEFT );
+ l.setFont( labelFont );
+ l.setText( aName );
+ l.setLayoutData( BorderLayout.CENTER );
+ // buttons pane
+ TsComposite buttonPane = new TsComposite( this );
+ RowLayout rowLayout = new RowLayout( SWT.HORIZONTAL );
+ rowLayout.marginBottom = rowLayout.marginLeft = rowLayout.marginRight = rowLayout.marginTop = 0;
+ buttonPane.setLayout( rowLayout );
+ buttonPane.setLayoutData( BorderLayout.EAST );
+ // clear button
+ clearButton = new Button( buttonPane, SWT.PUSH | SWT.FLAT );
+ clearButton.setText( STR_N_CLEAR_FILTER );
+ clearButton.setToolTipText( STR_D_CLEAR_FILTER );
+ }
+
+ public void addClearButtonSelectionListener( SelectionListener aListener ) {
+ clearButton.addSelectionListener( aListener );
+ }
+
+ }
+
+ private final IGenericChangeListener anyFilterChamgeListener = new IGenericChangeListener() {
+
+ @Override
+ public void onGenericChangeEvent( Object aSource ) {
+ eventer.fireChangeEvent();
+ }
+ };
+
+ final GenericChangeEventer eventer;
+
+ final PqFilterEpisodeIdsPanel pqEpIds;
+ final PqFilterAnyTextPanel pqAnyText;
+ final PqFilterTagIdsPanel pqTagIds;
+
+ /**
+ * Конструктор панели.
+ *
+ * Конструктор просто запоминает ссылку на контекст, без создания копии.
+ *
+ * @param aParent {@link Composite} - родительская панель
+ * @param aContext {@link ITsGuiContext} - контекст панели
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public PanelAllFiltersSetLadder( Composite aParent, ITsGuiContext aContext ) {
+ super( aParent, aContext );
+ eventer = new GenericChangeEventer( this );
+ GridLayout gridLayout = new GridLayout( 1, false );
+ this.setLayout( gridLayout );
+ ITsGuiContext ctx;
+ // epIds
+ FilterHeader h = new FilterHeader( this, STR_N_FILTER_EP_IDS );
+ h.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, false, false ) );
+ h.addClearButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqEpIds.resetFilter();
+ eventer.fireChangeEvent();
+ }
+ } );
+ ctx = new TsGuiContext( tsContext() );
+ pqEpIds = new PqFilterEpisodeIdsPanel( this, null, ctx );
+ pqEpIds.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, false, false, 1, 1 ) );
+ pqEpIds.genericChangeEventer().addListener( anyFilterChamgeListener );
+ // anyText
+ h = new FilterHeader( this, STR_N_FILTER_ANY_TEXT );
+ h.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, false, false ) );
+ h.addClearButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqAnyText.resetFilter();
+ eventer.fireChangeEvent();
+ }
+ } );
+ ctx = new TsGuiContext( tsContext() );
+ pqAnyText = new PqFilterAnyTextPanel( this, null, ctx );
+ pqAnyText.setLayoutData( new GridData( SWT.FILL, SWT.TOP, true, false, 1, 1 ) );
+ pqAnyText.genericChangeEventer().addListener( anyFilterChamgeListener );
+ // tagIds
+ h = new FilterHeader( this, STR_N_FILTER_TAG_IDS );
+ h.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, false, false ) );
+ h.addClearButtonSelectionListener( new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent aEvent ) {
+ pqTagIds.resetFilter();
+ eventer.fireChangeEvent();
+ }
+ } );
+ ctx = new TsGuiContext( tsContext() );
+ pqTagIds = new PqFilterTagIdsPanel( this, null, ctx );
+ pqTagIds.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 1, 1 ) );
+ pqTagIds.genericChangeEventer().addListener( anyFilterChamgeListener );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // Реализация интерфейса IGenericChangeEventProducerEx
+ //
+
+ @Override
+ public IGenericChangeEventer genericChangeEventer() {
+ return eventer;
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Возвращает параметры фильтра, заданные в панели.
+ *
+ * @return {@link InquiryItem} - заданноые в панели параметры фильтра
+ */
+ public InquiryItem getInquiryItem() {
+ InquiryItem item = new InquiryItem();
+ ITsSingleFilterParams spEpIds = pqEpIds.getFilterParams();
+ if( spEpIds != ITsSingleFilterParams.NONE ) {
+ item.fpMap().put( EPqSingleFilterKind.EPISODE_IDS, spEpIds );
+ }
+ ITsSingleFilterParams spAnyText = pqAnyText.getFilterParams();
+ if( spAnyText != ITsSingleFilterParams.NONE ) {
+ item.fpMap().put( EPqSingleFilterKind.ANY_TEXT, spAnyText );
+ }
+ ITsSingleFilterParams spTagIds = pqTagIds.getFilterParams();
+ if( spTagIds != ITsSingleFilterParams.NONE ) {
+ item.fpMap().put( EPqSingleFilterKind.TAG_IDS, spTagIds );
+ }
+ return item;
+ }
+
+ /**
+ * Показывает параметры в виджетах панели.
+ *
+ * @param aItem {@link InquiryItem} - параметры фильтра
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public void setFilterParams( InquiryItem aItem ) {
+ TsNullArgumentRtException.checkNull( aItem );
+ // TODO сбросить также NOT виджеты
+ // pqEpIds
+ pqEpIds.resetFilter();
+ if( aItem.fpMap().hasKey( EPqSingleFilterKind.EPISODE_IDS ) ) {
+ pqEpIds.setFilterParams( aItem.fpMap().getByKey( EPqSingleFilterKind.EPISODE_IDS ) );
+ }
+ // pqAnyText
+ pqAnyText.resetFilter();
+ if( aItem.fpMap().hasKey( EPqSingleFilterKind.ANY_TEXT ) ) {
+ pqAnyText.setFilterParams( aItem.fpMap().getByKey( EPqSingleFilterKind.ANY_TEXT ) );
+ }
+ // pqTagIds
+ pqTagIds.resetFilter();
+ if( aItem.fpMap().hasKey( EPqSingleFilterKind.TAG_IDS ) ) {
+ pqTagIds.setFilterParams( aItem.fpMap().getByKey( EPqSingleFilterKind.TAG_IDS ) );
+ }
+ }
+
+ /**
+ * Сбрасывает все панеи в {@link ITsSingleFilterParams#NONE}.
+ */
+ public void resetFilterParans() {
+ pqEpIds.resetFilter();
+ pqAnyText.resetFilter();
+ pqTagIds.resetFilter();
+ }
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterAnyTextPanel.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterAnyTextPanel.java
new file mode 100644
index 0000000..f9cf9de
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterAnyTextPanel.java
@@ -0,0 +1,158 @@
+package com.hazard157.prisex24.explorer;
+
+import static com.hazard157.prisex24.explorer.IPsxResources.*;
+import static org.toxsoft.core.tsgui.valed.api.IValedControlConstants.*;
+import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.bricks.ctx.impl.*;
+import org.toxsoft.core.tsgui.dialogs.datarec.*;
+import org.toxsoft.core.tsgui.valed.api.*;
+import org.toxsoft.core.tsgui.valed.controls.av.*;
+import org.toxsoft.core.tsgui.valed.controls.basic.*;
+import org.toxsoft.core.tsgui.valed.controls.enums.*;
+import org.toxsoft.core.tsgui.widgets.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+import org.toxsoft.core.tslib.utils.txtmatch.*;
+
+import com.hazard157.prisex24.explorer.filters.*;
+
+/**
+ * Панель настройки фильтра {@link PqFilterAnyText}.
+ *
+ * @author hazard157
+ */
+public class PqFilterAnyTextPanel
+ extends AbstractFilterPanel {
+
+ private ValedAvStringText valedText;
+ private ValedEnumCombo valedMatchMode;
+ private ValedAvBooleanCheck valedCheckTags;
+ private ValedAvBooleanCheck valedCheckScenes;
+ private ValedAvBooleanCheck valedCheckNotes;
+ private ValedAvBooleanCheck valedCheckPlanes;
+
+ /**
+ * Конструктор панели, предназаначенной для использования вне диалога.
+ *
+ * @param aParent {@link Composite} - родительская компонента
+ * @param aData T - начальные данные для отображения, может быть null
+ * @param aContext C - контекст радктирования / показа структры данных T
+ * @throws TsNullArgumentRtException aParent или aContext = null
+ */
+ public PqFilterAnyTextPanel( Composite aParent, ITsSingleFilterParams aData, ITsGuiContext aContext ) {
+ super( aParent, aData, aContext, 0 );
+ init();
+ }
+
+ /**
+ * Конструктор панели, предназаначенной для вставки в диалог {@link TsDialog}.
+ *
+ * @param aParent {@link Composite} - родительская компонента
+ * @param aOwnerDialog {@link TsDialog} - родительский диалог
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public PqFilterAnyTextPanel( Composite aParent, TsDialog aOwnerDialog ) {
+ super( aParent, aOwnerDialog );
+ init();
+ }
+
+ @SuppressWarnings( { "rawtypes", "unchecked" } )
+ private void init() {
+ this.setLayout( new GridLayout( 2, false ) );
+ Label l;
+ ITsGuiContext ctx;
+ // text
+ l = new Label( this, SWT.LEFT );
+ l.setText( STR_N_TEXT );
+ l.setToolTipText( STR_D_TEXT );
+ ctx = new TsGuiContext( tsContext() );
+ OPDEF_TOOLTIP_TEXT.setValue( ctx.params(), avStr( STR_D_TEXT ) );
+ valedText = new ValedAvStringText( ctx );
+ valedText.createControl( this );
+ valedText.getControl().setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false, 1, 1 ) );
+ valedText.eventer().addListener( notificationValedControlChangeListener );
+ // matchMode
+ l = new Label( this, SWT.LEFT );
+ l.setText( STR_N_MATCH_MODE );
+ l.setToolTipText( STR_D_MATCH_MODE );
+ ctx = new TsGuiContext( tsContext() );
+ OPDEF_TOOLTIP_TEXT.setValue( ctx.params(), avStr( STR_D_MATCH_MODE ) );
+ ctx.put( IValedEnumConstants.REFID_ENUM_CLASS, ETextMatchMode.class );
+ valedMatchMode = (ValedEnumCombo)(IValedControl)ValedEnumCombo.FACTORY.createEditor( ctx );
+ valedMatchMode.createControl( this );
+ valedMatchMode.getControl().setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false, 1, 1 ) );
+ valedText.eventer().addListener( notificationValedControlChangeListener );
+ valedMatchMode.setValue( ETextMatchMode.CONTAINS );
+
+ l = new Label( this, SWT.LEFT );
+ l.setText( STR_N_SEARCH_IN );
+
+ // checkboxex board
+ TsComposite chbxBoard = new TsComposite( this );
+ chbxBoard.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false, 1, 1 ) );
+ RowLayout rl = new RowLayout( SWT.HORIZONTAL );
+ rl.fill = true;
+ chbxBoard.setLayout( rl );
+ // inTags inScenes inNotes inPlanes
+ valedCheckTags = addCheckBoxToBoard( chbxBoard, STR_N_CHECK_TAGS, STR_D_CHECK_TAGS );
+ valedCheckScenes = addCheckBoxToBoard( chbxBoard, STR_N_CHECK_SCENES, STR_D_CHECK_SCENES );
+ valedCheckNotes = addCheckBoxToBoard( chbxBoard, STR_N_CHECK_NOTES, STR_D_CHECK_NOTES );
+ valedCheckPlanes = addCheckBoxToBoard( chbxBoard, STR_N_CHECK_PLANES, STR_D_CHECK_PLANES );
+ }
+
+ @SuppressWarnings( "rawtypes" )
+ private ValedAvBooleanCheck addCheckBoxToBoard( Composite aBoard, String aText, String aTooltip ) {
+ ITsGuiContext ctx = new TsGuiContext( tsContext() );
+ OPDEF_TOOLTIP_TEXT.setValue( ctx.params(), avStr( aTooltip ) );
+ ValedBooleanCheck.OPDEF_TEXT.setValue( ctx.params(), avStr( aText ) );
+ ValedAvBooleanCheck valed = (ValedAvBooleanCheck)(IValedControl)ValedAvBooleanCheck.FACTORY.createEditor( ctx );
+ valed.createControl( aBoard );
+ valed.eventer().addListener( notificationValedControlChangeListener );
+ return valed;
+ }
+
+ @Override
+ protected void doSetDataRecord( ITsSingleFilterParams aData ) {
+ if( aData == null || aData == ITsSingleFilterParams.NONE ) {
+ resetFilter();
+ return;
+ }
+ TsIllegalArgumentRtException.checkFalse( aData.typeId().equals( PqFilterAnyText.TYPE_ID ) );
+ valedText.setValue( aData.params().getValue( PqFilterAnyText.OPID_TEXT ) );
+ valedMatchMode.setValue( aData.params().getValobj( PqFilterAnyText.OPID_MATCH_MODE ) );
+ valedCheckTags.setValue( aData.params().getValue( PqFilterAnyText.OPID_IN_TAGS ) );
+ valedCheckScenes.setValue( aData.params().getValue( PqFilterAnyText.OPID_IN_SCENES ) );
+ valedCheckNotes.setValue( aData.params().getValue( PqFilterAnyText.OPID_IN_NOTES ) );
+ valedCheckPlanes.setValue( aData.params().getValue( PqFilterAnyText.OPID_IN_PLANES ) );
+ }
+
+ @Override
+ protected ITsSingleFilterParams doGetDataRecord() {
+ String text = valedText.getValue().asString().trim();
+ if( text.isEmpty() ) {
+ return ITsSingleFilterParams.NONE;
+ }
+ ETextMatchMode matchMode = valedMatchMode.getValue();
+ boolean inTags = valedCheckTags.getValue().asBool();
+ boolean inScenes = valedCheckScenes.getValue().asBool();
+ boolean inNotes = valedCheckNotes.getValue().asBool();
+ boolean inPlanes = valedCheckPlanes.getValue().asBool();
+ return PqFilterAnyText.makeFilterParams( text, matchMode, inTags, inScenes, inNotes, inPlanes );
+ }
+
+ @Override
+ public void resetFilter() {
+ valedText.setValue( AV_STR_EMPTY );
+ valedMatchMode.setValue( ETextMatchMode.CONTAINS );
+ valedCheckTags.setValue( AV_FALSE );
+ valedCheckScenes.setValue( AV_FALSE );
+ valedCheckNotes.setValue( AV_FALSE );
+ valedCheckPlanes.setValue( AV_FALSE );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterEpisodeIdsPanel.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterEpisodeIdsPanel.java
new file mode 100644
index 0000000..066bc21
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterEpisodeIdsPanel.java
@@ -0,0 +1,151 @@
+package com.hazard157.prisex24.explorer;
+
+import static com.hazard157.prisex24.explorer.IPsxResources.*;
+import static org.toxsoft.core.tsgui.valed.api.IValedControlConstants.*;
+import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.bricks.ctx.impl.*;
+import org.toxsoft.core.tsgui.dialogs.datarec.*;
+import org.toxsoft.core.tsgui.utils.layout.*;
+import org.toxsoft.core.tsgui.valed.controls.av.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.coll.primtypes.*;
+import org.toxsoft.core.tslib.utils.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.explorer.filters.*;
+import com.hazard157.prisex24.glib.dialogs.*;
+
+/**
+ * Панель настройки фильтра {@link PqFilterAnyText}.
+ *
+ * @author hazard157
+ */
+public class PqFilterEpisodeIdsPanel
+ extends AbstractFilterPanel {
+
+ private final SelectionAdapter btnSelectEpisodeIdsListener = new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected( SelectionEvent e ) {
+ whenEpisodeIdsSelectionButtonPressed();
+ }
+ };
+
+ private ValedAvStringText valedEpisodeIds;
+ private Button btnSelectEpisodeIds;
+
+ private IStringListBasicEdit episodeIds = new SortedStringLinkedBundleList();
+
+ /**
+ * Конструктор панели, предназаначенной для использования вне диалога.
+ *
+ * @param aParent {@link Composite} - родительская компонента
+ * @param aData T - начальные данные для отображения, может быть null
+ * @param aContext C - контекст радктирования / показа структры данных T
+ * @throws TsNullArgumentRtException aParent или aContext = null
+ */
+ public PqFilterEpisodeIdsPanel( Composite aParent, ITsSingleFilterParams aData, ITsGuiContext aContext ) {
+ super( aParent, aData, aContext, 0 );
+ init();
+ }
+
+ /**
+ * Конструктор панели, предназаначенной для вставки в диалог {@link TsDialog}.
+ *
+ * @param aParent {@link Composite} - родительская компонента
+ * @param aOwnerDialog {@link TsDialog} - родительский диалог
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public PqFilterEpisodeIdsPanel( Composite aParent, TsDialog aOwnerDialog ) {
+ super( aParent, aOwnerDialog );
+ init();
+ }
+
+ private void init() {
+ this.setLayout( new BorderLayout() );
+ // label
+ Label l = new Label( this, SWT.LEFT );
+ l.setText( STR_N_EP_IDS );
+ l.setToolTipText( STR_D_EP_IDS );
+ l.setLayoutData( BorderLayout.WEST );
+ // valedEpisodeIds
+ ITsGuiContext ctx = new TsGuiContext( tsContext() );
+ OPDEF_TOOLTIP_TEXT.setValue( ctx.params(), avStr( STR_D_EP_IDS ) );
+ valedEpisodeIds = new ValedAvStringText( ctx );
+ valedEpisodeIds.createControl( this );
+ valedEpisodeIds.getControl().setLayoutData( BorderLayout.CENTER );
+ valedEpisodeIds.eventer().addListener( notificationValedControlChangeListener );
+ // btnSelectEpisodeIds
+ btnSelectEpisodeIds = new Button( this, SWT.PUSH );
+ btnSelectEpisodeIds.setText( TsLibUtils.EMPTY_STRING );
+ btnSelectEpisodeIds.setText( STR_T_SEL_EP_IDS_BTN );
+ btnSelectEpisodeIds.setToolTipText( STR_P_SEL_EP_IDS_BTN );
+ btnSelectEpisodeIds.setLayoutData( BorderLayout.EAST );
+ btnSelectEpisodeIds.addSelectionListener( btnSelectEpisodeIdsListener );
+ }
+
+ @Override
+ protected void doSetDataRecord( ITsSingleFilterParams aData ) {
+ if( aData == null || aData == ITsSingleFilterParams.NONE ) {
+ resetFilter();
+ return;
+ }
+ TsIllegalArgumentRtException.checkFalse( aData.typeId().equals( PqFilterEpisodeIds.TYPE_ID ) );
+ episodeIds.setAll( (IStringList)aData.params().getValobj( PqFilterEpisodeIds.OPID_EPISODE_IDS ) );
+ valedEpisodeIds.setValue( avStr( makeEpisodeIdstext() ) );
+ }
+
+ private String makeEpisodeIdstext() {
+ StringBuilder sb = new StringBuilder();
+ if( episodeIds.size() <= 3 ) {
+ for( int i = 0; i < episodeIds.size(); i++ ) {
+ sb.append( episodeIds.get( i ) );
+ if( i < episodeIds.size() - 1 ) {
+ sb.append( ", " ); //$NON-NLS-1$
+ }
+ }
+ return sb.toString();
+ }
+ for( int i = 0; i < 2; i++ ) {
+ sb.append( episodeIds.get( i ) );
+ if( i < 1 ) {
+ sb.append( ", " ); //$NON-NLS-1$
+ }
+ }
+ sb.append( " ... " ); //$NON-NLS-1$
+ sb.append( episodeIds.last() );
+ return sb.toString();
+ }
+
+ void whenEpisodeIdsSelectionButtonPressed() {
+ IStringList sel = DialogSelectEpisodeIds.select( tsContext(), episodeIds );
+ if( sel == null ) {
+ return;
+ }
+ episodeIds.setAll( sel );
+ valedEpisodeIds.setValue( avStr( makeEpisodeIdstext() ) );
+ fireContentChangeEvent();
+ }
+
+ @Override
+ protected ITsSingleFilterParams doGetDataRecord() {
+ String text = valedEpisodeIds.getValue().asString().trim();
+ if( text.isEmpty() ) {
+ return ITsSingleFilterParams.NONE;
+ }
+ return PqFilterEpisodeIds.makeFilterParams( episodeIds );
+ }
+
+ @Override
+ public void resetFilter() {
+ valedEpisodeIds.setValue( AV_STR_EMPTY );
+ episodeIds.clear();
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterTagIdsPanel.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterTagIdsPanel.java
new file mode 100644
index 0000000..c661321
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/PqFilterTagIdsPanel.java
@@ -0,0 +1,151 @@
+package com.hazard157.prisex24.explorer;
+
+import static com.hazard157.prisex24.explorer.IPsxResources.*;
+import static org.toxsoft.core.tsgui.m5.gui.mpc.IMultiPaneComponentConstants.*;
+import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
+
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.bricks.ctx.impl.*;
+import org.toxsoft.core.tsgui.dialogs.datarec.*;
+import org.toxsoft.core.tsgui.m5.*;
+import org.toxsoft.core.tsgui.m5.gui.panels.*;
+import org.toxsoft.core.tsgui.m5.model.*;
+import org.toxsoft.core.tsgui.utils.layout.*;
+import org.toxsoft.core.tsgui.valed.controls.av.*;
+import org.toxsoft.core.tsgui.valed.controls.basic.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.coll.primtypes.*;
+import org.toxsoft.core.tslib.coll.primtypes.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.explorer.filters.*;
+import com.hazard157.prisex24.m5.*;
+import com.hazard157.psx.proj3.tags.*;
+
+/**
+ * Панель настройки фильтра {@link PqFilterTagIds}.
+ *
+ * @author hazard157
+ */
+public class PqFilterTagIdsPanel
+ extends AbstractFilterPanel {
+
+ private final ValedAvBooleanCheck valedIsAny;
+ private final IM5CollectionPanel panel;
+
+ /**
+ * Конструктор панели, предназаначенной для использования вне диалога.
+ *
+ * @param aParent {@link Composite} - родительская компонента
+ * @param aData T - начальные данные для отображения, может быть null
+ * @param aContext C - контекст радктирования / показа структры данных T
+ * @throws TsNullArgumentRtException aParent или aContext = null
+ */
+ public PqFilterTagIdsPanel( Composite aParent, ITsSingleFilterParams aData, ITsGuiContext aContext ) {
+ super( aParent, aData, aContext, 0 );
+ this.setLayout( new BorderLayout() );
+ // valedIsAny
+ ITsGuiContext ctx = new TsGuiContext( tsContext() );
+ ValedBooleanCheck.OPDEF_TEXT.setValue( ctx.params(), avStr( STR_N_TAGS_IS_ANY ) );
+ valedIsAny = new ValedAvBooleanCheck( ctx );
+ valedIsAny.setValue( AV_FALSE );
+ valedIsAny.createControl( this );
+ valedIsAny.getControl().setLayoutData( BorderLayout.NORTH );
+ valedIsAny.eventer().addListener( notificationValedControlChangeListener );
+ // panel
+ ctx = new TsGuiContext( tsContext() );
+ IM5Model model = m5().getModel( IPsxM5Constants.MID_TAG, ITag.class );
+ IRootTag rootTag = tsContext().get( IRootTag.class );
+ IM5LifecycleManager lm = model.getLifecycleManager( rootTag );
+ OPDEF_IS_DETAILS_PANE.setValue( ctx.params(), AV_FALSE );
+ OPDEF_IS_COLUMN_HEADER.setValue( ctx.params(), AV_FALSE );
+ OPDEF_IS_SUPPORTS_CHECKS.setValue( ctx.params(), AV_TRUE );
+ panel = model.panelCreator().createCollChecksPanel( ctx, lm.itemsProvider() );
+ panel.createControl( this );
+ panel.getControl().setLayoutData( BorderLayout.CENTER );
+ panel.checkSupport().checksChangeEventer().addListener( notificationGenericChangeListener );
+ setMinHeightDisplayRelative( 60 );
+ }
+
+ /**
+ * Конструктор панели, предназаначенной для вставки в диалог {@link TsDialog}.
+ *
+ * @param aParent {@link Composite} - родительская компонента
+ * @param aOwnerDialog {@link TsDialog} - родительский диалог
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public PqFilterTagIdsPanel( Composite aParent, TsDialog aOwnerDialog ) {
+ super( aParent, aOwnerDialog );
+ // panel
+ ITsGuiContext ctx = new TsGuiContext( tsContext() );
+ IM5Model model = m5().getModel( IPsxM5Constants.MID_TAG, ITag.class );
+ IRootTag rootTag = tsContext().get( IRootTag.class );
+ IM5LifecycleManager lm = model.getLifecycleManager( rootTag );
+ // OPDEF_IS_DETAILS_PANE.setValue( ctx.params(), AV_FALSE );
+ // OPDEF_IS_COLUMN_HEADER.setValue( ctx.params(), AV_FALSE );
+ OPDEF_IS_SUPPORTS_CHECKS.setValue( ctx.params(), AV_TRUE );
+ panel = model.panelCreator().createCollChecksPanel( ctx, lm.itemsProvider() );
+ panel.createControl( this );
+ panel.getControl().setLayoutData( BorderLayout.CENTER );
+ panel.checkSupport().checksChangeEventer().addListener( notificationGenericChangeListener );
+ // valedIsAny
+ ctx = new TsGuiContext( tsContext() );
+ ValedBooleanCheck.OPDEF_TEXT.setValue( ctx.params(), avStr( STR_N_TAGS_IS_ANY ) );
+ valedIsAny = new ValedAvBooleanCheck( ctx );
+ valedIsAny.setValue( AV_FALSE );
+ valedIsAny.createControl( this );
+ valedIsAny.getControl().setLayoutData( BorderLayout.NORTH );
+ valedIsAny.eventer().addListener( notificationValedControlChangeListener );
+ }
+
+ IRootTag rootTag() {
+ return tsContext().get( IRootTag.class );
+ }
+
+ @Override
+ protected void doSetDataRecord( ITsSingleFilterParams aData ) {
+ if( aData == null || aData == ITsSingleFilterParams.NONE ) {
+ resetFilter();
+ return;
+ }
+ TsIllegalArgumentRtException.checkFalse( aData.typeId().equals( PqFilterTagIds.TYPE_ID ) );
+ boolean isAny = aData.params().getBool( PqFilterTagIds.OPID_IS_ANY, false );
+ valedIsAny.setValue( avBool( isAny ) );
+ IStringList tagIds = aData.params().getValobj( PqFilterTagIds.OPID_TAG_IDS, IStringList.EMPTY );
+ try {
+ panel.checkSupport().checksChangeEventer().pauseFiring();
+ panel.checkSupport().setAllItemsCheckState( false );
+ for( ITag t : rootTag().allLeafsBelow() ) {
+ if( tagIds.hasElem( t.id() ) ) {
+ panel.checkSupport().setItemCheckState( t, true );
+ }
+ }
+ }
+ finally {
+ panel.checkSupport().checksChangeEventer().resumeFiring( true );
+ }
+ }
+
+ @Override
+ protected ITsSingleFilterParams doGetDataRecord() {
+ IStringListEdit tagIds = new StringLinkedBundleList();
+ for( ITag t : rootTag().allLeafsBelow() ) {
+ if( panel.checkSupport().getItemCheckState( t ) ) {
+ tagIds.add( t.id() );
+ }
+ }
+ if( tagIds.isEmpty() ) {
+ return ITsSingleFilterParams.NONE;
+ }
+ boolean isAny = valedIsAny.getValue().asBool();
+ return PqFilterTagIds.makeFilterParams( tagIds, isAny );
+ }
+
+ @Override
+ public void resetFilter() {
+ panel.checkSupport().setAllItemsCheckState( false );
+ valedIsAny.setValue( AV_FALSE );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/ResultsPanelAsSimpleList.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/ResultsPanelAsSimpleList.java
new file mode 100644
index 0000000..1fea411
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/ResultsPanelAsSimpleList.java
@@ -0,0 +1,79 @@
+package com.hazard157.prisex24.explorer;
+
+import static com.hazard157.prisex24.m5.IPsxM5Constants.*;
+import static org.toxsoft.core.tsgui.m5.gui.mpc.IMultiPaneComponentConstants.*;
+import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
+
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.bricks.ctx.impl.*;
+import org.toxsoft.core.tsgui.graphics.icons.*;
+import org.toxsoft.core.tsgui.m5.*;
+import org.toxsoft.core.tsgui.utils.layout.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.psx.common.stuff.svin.*;
+
+/**
+ * Отображение результатов как простого списка (таблицы) элементов типа {@link Svin}.
+ *
+ * @author hazard157
+ */
+public class ResultsPanelAsSimpleList
+ extends AbstractResultsPanel {
+
+ // private final IM5ItemsProvider itemsProvider = () -> getPqResults().listAllSvins();
+ //
+ // private final SvinM5Mpc panel;
+
+ /**
+ * Constructor.
+ *
+ * Constructor stores reference to the context, does not creates copy.
+ *
+ * @param aParent {@link Composite} - parent component
+ * @param aContext {@link ITsGuiContext} - the context
+ * @throws TsNullArgumentRtException any argument = null
+ */
+ public ResultsPanelAsSimpleList( Composite aParent, ITsGuiContext aContext ) {
+ super( aParent, aContext );
+ this.setLayout( new BorderLayout() );
+ IM5Model model = m5().getModel( MID_SVIN, Svin.class );
+ ITsGuiContext ctx = new TsGuiContext( aContext );
+ OPDEF_IS_DETAILS_PANE.setValue( ctx.params(), AV_FALSE );
+ OPDEF_IS_SUMMARY_PANE.setValue( ctx.params(), AV_TRUE );
+ OPDEF_IS_ACTIONS_CRUD.setValue( ctx.params(), AV_FALSE );
+ OPDEF_IS_SUPPORTS_TREE.setValue( ctx.params(), AV_TRUE );
+ OPDEF_NODE_ICON_SIZE.setValue( ctx.params(), avValobj( EIconSize.IS_64X64 ) );
+ // panel = new SvinM5Mpc( ctx, model, itemsProvider, null );
+ // panel.createControl( this );
+ // panel.getControl().setLayoutData( BorderLayout.CENTER );
+ // panel.addTsSelectionListener( selectionChangeEventHelper );
+ }
+
+ @Override
+ protected void refresh() {
+ // panel.refresh();
+ // panel.tree().columnManager().columns().values().get( 0 ).pack();
+ // panel.tree().columnManager().columns().values().get( 1 ).pack();
+ }
+
+ @Override
+ public Svin selectedItem() {
+ // return panel.selectedItem();
+ return null;
+ }
+
+ @Override
+ public void setSelectedItem( Svin aItem ) {
+ // panel.setSelectedItem( aItem );
+ }
+
+ @Override
+ public IList getSelectionSvins() {
+ // return panel.getSelectedNodeSvins();
+ return IList.EMPTY;
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/EPqSingleFilterKind.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/EPqSingleFilterKind.java
new file mode 100644
index 0000000..217d5ed
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/EPqSingleFilterKind.java
@@ -0,0 +1,164 @@
+package com.hazard157.prisex24.explorer.filters;
+
+import static com.hazard157.prisex24.explorer.filters.IPsxResources.*;
+
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.bricks.keeper.*;
+import org.toxsoft.core.tslib.bricks.keeper.std.*;
+import org.toxsoft.core.tslib.bricks.strid.*;
+import org.toxsoft.core.tslib.bricks.strid.coll.*;
+import org.toxsoft.core.tslib.bricks.strid.coll.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.psx.proj3.episodes.*;
+
+/**
+ * The kind of the single PSX filter..
+ *
+ * @author hazard157
+ */
+public enum EPqSingleFilterKind
+ implements IStridable {
+
+ /**
+ * Search text in various places.
+ */
+ ANY_TEXT( PqFilterAnyText.TYPE_ID, STR_N_ANY_TEXT, STR_D_ANY_TEXT, PqFilterAnyText.FACTORY ),
+
+ /**
+ * Search for tag marks.
+ */
+ TAG_IDS( PqFilterTagIds.TYPE_ID, STR_N_TAG_IDS, STR_D_TAG_IDS, PqFilterTagIds.FACTORY ),
+
+ /**
+ * Select episodes.
+ */
+ EPISODE_IDS( PqFilterEpisodeIds.TYPE_ID, STR_N_EPISODE_IDS, STR_D_EPISODE_IDS, PqFilterEpisodeIds.FACTORY ),
+
+ ;
+
+ /**
+ * Registered keeper ID.
+ */
+ public static final String KEEPER_ID = "EPqSingleFilterKind"; //$NON-NLS-1$
+
+ /**
+ * The keeper singleton.
+ */
+ public static final IEntityKeeper KEEPER =
+ new StridableEnumKeeper<>( EPqSingleFilterKind.class );
+
+ private static IStridablesListEdit list = null;
+
+ private final String id;
+ private final String name;
+ private final String description;
+ private final ITsSingleFilterFactory factory;
+
+ EPqSingleFilterKind( String aId, String aName, String aDescription, ITsSingleFilterFactory aFactory ) {
+ id = aId;
+ name = aName;
+ description = aDescription;
+ factory = aFactory;
+ }
+
+ // --------------------------------------------------------------------------
+ // IStridable
+ //
+
+ @Override
+ public String id() {
+ return id;
+ }
+
+ @Override
+ public String nmName() {
+ return name;
+ }
+
+ @Override
+ public String description() {
+ return description;
+ }
+
+ // ----------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Returns the filter factory.
+ *
+ * @return {@link ITsSingleFilterFactory}<{@link SecondSlice}> - the filter factory
+ */
+ public ITsSingleFilterFactory factory() {
+ return factory;
+ }
+
+ /**
+ * Returns a human-readable string of filter options.
+ *
+ * @param aParams {@link ITsSingleFilterParams} - the filter parameters
+ * @return String - single-line text
+ * @throws TsNullArgumentRtException any argument = null
+ * @throws TsIllegalArgumentRtException arguemnt is a parameters of an unknown filter
+ */
+ public static final String makeHumanReadableString( ITsSingleFilterParams aParams ) {
+ TsNullArgumentRtException.checkNull( aParams );
+ EPqSingleFilterKind kind = asList().getByKey( aParams.typeId() );
+ return switch( kind ) {
+ case ANY_TEXT -> PqFilterAnyText.makeHumanReadableString( aParams );
+ case TAG_IDS -> PqFilterTagIds.makeHumanReadableString( aParams );
+ case EPISODE_IDS -> PqFilterEpisodeIds.makeHumanReadableString( aParams );
+ default -> throw new TsNotAllEnumsUsedRtException();
+ };
+ }
+
+ /**
+ * Returns all constant as a list/.
+ *
+ * @return {@link IStridablesList}< {@link EPqSingleFilterKind} > - the list of constants.
+ */
+ public static IStridablesList asList() {
+ if( list == null ) {
+ list = new StridablesList<>( values() );
+ }
+ return list;
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public static boolean isItemById( String aId ) {
+ return findById( aId ) != null;
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public static EPqSingleFilterKind findById( String aId ) {
+ return asList().findByKey( aId );
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public static EPqSingleFilterKind getById( String aId ) {
+ return asList().getByKey( aId );
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public static boolean isItemByName( String aName ) {
+ return findByName( aName ) != null;
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public static EPqSingleFilterKind findByName( String aName ) {
+ TsNullArgumentRtException.checkNull( aName );
+ for( EPqSingleFilterKind item : values() ) {
+ if( item.name.equals( aName ) ) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ @SuppressWarnings( "javadoc" )
+ public static EPqSingleFilterKind getByName( String aName ) {
+ return TsItemNotFoundRtException.checkNull( findByName( aName ) );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/IPsxResources.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/IPsxResources.java
new file mode 100644
index 0000000..afe038a
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/IPsxResources.java
@@ -0,0 +1,20 @@
+package com.hazard157.prisex24.explorer.filters;
+
+/**
+ * Localizable resources.
+ *
+ * @author hazard157
+ */
+interface IPsxResources {
+
+ /**
+ * {@link EPqSingleFilterKind}
+ */
+ String STR_N_ANY_TEXT = "Поиск текста";
+ String STR_D_ANY_TEXT = "Поиск любого текста в во всей информации об эпизодах";
+ String STR_N_TAG_IDS = "Пометки ярлыками";
+ String STR_D_TAG_IDS = "Поиск в эпизодах по пометкам ярлыками";
+ String STR_N_EPISODE_IDS = "Выбор эпизодов";
+ String STR_D_EPISODE_IDS = "Отбор эпизодов для выборки";
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterAnyText.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterAnyText.java
new file mode 100644
index 0000000..eb5ec86
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterAnyText.java
@@ -0,0 +1,162 @@
+package com.hazard157.prisex24.explorer.filters;
+
+import org.toxsoft.core.tslib.av.opset.*;
+import org.toxsoft.core.tslib.av.opset.impl.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.bricks.filter.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+import org.toxsoft.core.tslib.utils.txtmatch.*;
+
+import com.hazard157.psx.proj3.episodes.*;
+import com.hazard157.psx.proj3.episodes.story.*;
+
+/**
+ * Filter of kind {@link EPqSingleFilterKind#ANY_TEXT}.
+ *
+ * @author hazard157
+ */
+@SuppressWarnings( "javadoc" )
+public class PqFilterAnyText
+ implements ITsFilter {
+
+ /**
+ * The filter type ID.
+ */
+ public static final String TYPE_ID = "pq.filter.Text"; //$NON-NLS-1$
+
+ /**
+ * The filter factory.
+ */
+ public static final ITsSingleFilterFactory FACTORY =
+ new AbstractTsSingleFilterFactory<>( TYPE_ID, SecondSlice.class ) {
+
+ @Override
+ protected ITsFilter doCreateFilter( IOptionSet aParams ) {
+ String text = aParams.getStr( OPID_TEXT );
+ ETextMatchMode matchMode = aParams.getValobj( OPID_MATCH_MODE );
+ boolean inTags = aParams.getBool( OPID_IN_TAGS );
+ boolean inScenes = aParams.getBool( OPID_IN_SCENES );
+ boolean inPlanes = aParams.getBool( OPID_IN_PLANES );
+ boolean inNotes = aParams.getBool( OPID_IN_NOTES );
+ return new PqFilterAnyText( text, matchMode, inTags, inScenes, inNotes, inPlanes );
+ }
+ };
+
+ public static final String OPID_TEXT = "text"; //$NON-NLS-1$
+ public static final String OPID_MATCH_MODE = "matchMode"; //$NON-NLS-1$
+ public static final String OPID_IN_TAGS = "inTags"; //$NON-NLS-1$
+ public static final String OPID_IN_SCENES = "inScenes"; //$NON-NLS-1$
+ public static final String OPID_IN_NOTES = "inNotes"; //$NON-NLS-1$
+ public static final String OPID_IN_PLANES = "inPlanes"; //$NON-NLS-1$
+
+ private final String text;
+ private final ETextMatchMode matchMode;
+ private final TextMatcher textMatcher;
+ private final boolean checkTags;
+ private final boolean checkScenes;
+ private final boolean checkNotes;
+ private final boolean checkPlanes;
+
+ /**
+ * Constructor.
+ *
+ * @param aText String - the search text, the left operand of the comparison
+ * @param aMatchMode {@link ETextMatchMode} - comparison operation
+ * @param aInTags boolean - the sign to search in the tags
+ * @param aInScenes boolean - the sign to search in the scenes names
+ * @param aInNotes boolean - the sign to search in the notes
+ * @param aInPlanes boolean - the sign to search in the plane names
+ * @throws TsNullArgumentRtException any argument = null
+ * @throws TsIllegalArgumentRtException text is an empty string
+ * @throws TsIllegalArgumentRtException all signs are false
+ */
+ public PqFilterAnyText( String aText, ETextMatchMode aMatchMode, boolean aInTags, boolean aInScenes, boolean aInNotes,
+ boolean aInPlanes ) {
+ TsErrorUtils.checkNonEmpty( aText );
+ TsNullArgumentRtException.checkNull( aMatchMode );
+ TsErrorUtils.checkNonEmpty( aText );
+ TsNullArgumentRtException.checkNull( aMatchMode );
+ text = aText;
+ matchMode = aMatchMode;
+ textMatcher = new TextMatcher( matchMode, text );
+ checkTags = aInTags;
+ checkScenes = aInScenes;
+ checkNotes = aInNotes;
+ checkPlanes = aInPlanes;
+ }
+
+ /**
+ * Creates filter parameters.
+ *
+ * @param aText String - the search text, the left operand of the comparison
+ * @param aMatchMode {@link ETextMatchMode} - comparison operation
+ * @param aInTags boolean - the sign to search in the tags
+ * @param aInScenes boolean - the sign to search in the scenes names
+ * @param aInNotes boolean - the sign to search in the notes
+ * @param aInPlanes boolean - the sign to search in the plane names
+ * @return {@link IOptionSet} - created parameters
+ * @throws TsNullArgumentRtException any argument = null
+ * @throws TsIllegalArgumentRtException text is an empty string
+ * @throws TsIllegalArgumentRtException all signs are false
+ */
+ public static ITsSingleFilterParams makeFilterParams( String aText, ETextMatchMode aMatchMode, boolean aInTags,
+ boolean aInScenes, boolean aInNotes, boolean aInPlanes ) {
+ TsErrorUtils.checkNonEmpty( aText );
+ TsNullArgumentRtException.checkNull( aMatchMode );
+ IOptionSetEdit p = new OptionSet();
+ p.setStr( OPID_TEXT, aText );
+ p.setValobj( OPID_MATCH_MODE, aMatchMode );
+ p.setBool( OPID_IN_TAGS, aInTags );
+ p.setBool( OPID_IN_SCENES, aInScenes );
+ p.setBool( OPID_IN_NOTES, aInNotes );
+ p.setBool( OPID_IN_PLANES, aInPlanes );
+ return new TsSingleFilterParams( TYPE_ID, p );
+ }
+
+ /**
+ * Returns a human-readable string of filter options.
+ *
+ * @param aParams {@link ITsSingleFilterParams} - the filter parameters
+ * @return String - single-line text
+ * @throws TsNullArgumentRtException any argument = null
+ * @throws TsIllegalArgumentRtException the parameters if not of this filter
+ */
+ @SuppressWarnings( "nls" )
+ public static final String makeHumanReadableString( ITsSingleFilterParams aParams ) {
+ TsNullArgumentRtException.checkNull( aParams );
+ TsIllegalArgumentRtException.checkFalse( aParams.typeId().equals( TYPE_ID ) );
+ return String.format( "Text: '%s'", aParams.params().getStr( OPID_TEXT ) );
+ }
+
+ @Override
+ public boolean accept( SecondSlice aObj ) {
+ if( checkTags ) {
+ for( String tagId : aObj.tagIds() ) {
+ if( textMatcher.match( tagId ) ) {
+ return true;
+ }
+ }
+ }
+ if( checkScenes ) {
+ for( IScene scene : aObj.scenes() ) {
+ if( textMatcher.match( scene.info().name() ) ) {
+ return true;
+ }
+ }
+ }
+ if( checkPlanes ) {
+ if( textMatcher.match( aObj.plane().name() ) ) {
+ return true;
+ }
+ }
+ if( checkNotes ) {
+ for( String note : aObj.notes() ) {
+ if( textMatcher.match( note ) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterEpisodeIds.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterEpisodeIds.java
new file mode 100644
index 0000000..9e07353
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterEpisodeIds.java
@@ -0,0 +1,96 @@
+package com.hazard157.prisex24.explorer.filters;
+
+import org.toxsoft.core.tslib.av.opset.*;
+import org.toxsoft.core.tslib.av.opset.impl.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.bricks.filter.impl.*;
+import org.toxsoft.core.tslib.bricks.strid.impl.*;
+import org.toxsoft.core.tslib.coll.primtypes.*;
+import org.toxsoft.core.tslib.coll.primtypes.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.psx.proj3.episodes.*;
+
+/**
+ * Filter of kind {@link EPqSingleFilterKind#EPISODE_IDS}.
+ *
+ * @author hazard157
+ */
+@SuppressWarnings( "javadoc" )
+public class PqFilterEpisodeIds
+ implements ITsFilter {
+
+ /**
+ * The filter type ID.
+ */
+ public static final String TYPE_ID = "pq.filter.EpisodeIds"; //$NON-NLS-1$
+
+ /**
+ * The filter factory.
+ */
+ public static final ITsSingleFilterFactory FACTORY =
+ new AbstractTsSingleFilterFactory<>( TYPE_ID, SecondSlice.class ) {
+
+ @Override
+ protected ITsFilter doCreateFilter( IOptionSet aParams ) {
+ IStringList episodeIds = aParams.getValobj( OPID_EPISODE_IDS );
+ return new PqFilterEpisodeIds( episodeIds );
+ }
+ };
+
+ public static final String OPID_EPISODE_IDS = "episodeIds"; //$NON-NLS-1$
+
+ private final IStringList episodeIds;
+
+ /**
+ * Constructor.
+ *
+ * @param aEpisodeIds {@link IStringList} - the episode IDs
+ */
+ public PqFilterEpisodeIds( IStringList aEpisodeIds ) {
+ episodeIds = new StringArrayList( aEpisodeIds );
+ }
+
+ /**
+ * Creates filter parameters.
+ *
+ * @param aEpisodeIds {@link IStringList} - the episode IDs
+ * @return {@link ITsSingleFilterParams} - the filter parameters
+ * @throws TsNullArgumentRtException any argument = null
+ */
+ public static ITsSingleFilterParams makeFilterParams( IStringList aEpisodeIds ) {
+ IOptionSetEdit p = new OptionSet();
+ p.setValobj( OPID_EPISODE_IDS, aEpisodeIds );
+ return new TsSingleFilterParams( TYPE_ID, p );
+ }
+
+ /**
+ * Returns a human-readable string of filter options.
+ *
+ * @param aParams {@link ITsSingleFilterParams} - the filter parameters
+ * @return String - single-line text
+ * @throws TsNullArgumentRtException any argument = null
+ * @throws TsIllegalArgumentRtException the parameters if not of this filter
+ */
+ @SuppressWarnings( "nls" )
+ public static final String makeHumanReadableString( ITsSingleFilterParams aParams ) {
+ TsNullArgumentRtException.checkNull( aParams );
+ TsIllegalArgumentRtException.checkFalse( aParams.typeId().equals( TYPE_ID ) );
+ StringBuilder sb = new StringBuilder();
+ IStringList episodeIds = aParams.params().getValobj( PqFilterEpisodeIds.OPID_EPISODE_IDS );
+ for( int i = 0, n = episodeIds.size(); i < n; i++ ) {
+ sb.append( StridUtils.getLast( episodeIds.get( i ) ) );
+ sb.append( ' ' );
+ }
+ return String.format( "Episodes: %s", sb.toString() );
+ }
+
+ @Override
+ public boolean accept( SecondSlice aObj ) {
+ if( episodeIds.isEmpty() ) {
+ return true;
+ }
+ return episodeIds.hasElem( aObj.episode().id() );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterTagIds.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterTagIds.java
new file mode 100644
index 0000000..f0a605a
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/filters/PqFilterTagIds.java
@@ -0,0 +1,110 @@
+package com.hazard157.prisex24.explorer.filters;
+
+import org.toxsoft.core.tslib.av.opset.*;
+import org.toxsoft.core.tslib.av.opset.impl.*;
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.bricks.filter.impl.*;
+import org.toxsoft.core.tslib.bricks.strid.impl.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.coll.primtypes.*;
+import org.toxsoft.core.tslib.coll.primtypes.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.psx.proj3.episodes.*;
+
+/**
+ * Filter of kind {@link EPqSingleFilterKind#TAG_IDS}.
+ *
+ * @author hazard157
+ */
+@SuppressWarnings( "javadoc" )
+public class PqFilterTagIds
+ implements ITsFilter {
+
+ /**
+ * The filter type ID.
+ */
+ public static final String TYPE_ID = "pq.filter.TagIds"; //$NON-NLS-1$
+
+ /**
+ * The filter factory.
+ */
+ public static final ITsSingleFilterFactory FACTORY =
+ new AbstractTsSingleFilterFactory<>( TYPE_ID, SecondSlice.class ) {
+
+ @Override
+ protected ITsFilter doCreateFilter( IOptionSet aParams ) {
+ IStringList tagIds = aParams.getValobj( OPID_TAG_IDS );
+ boolean iaAny = aParams.getBool( OPID_IS_ANY );
+ return new PqFilterTagIds( tagIds, iaAny );
+ }
+ };
+
+ public static final String OPID_TAG_IDS = "tagIds"; //$NON-NLS-1$
+
+ public static final String OPID_IS_ANY = "isAny"; //$NON-NLS-1$
+
+ private final IStringList tagIds;
+ private final boolean any;
+
+ /**
+ * Constructor.
+ *
+ * @param aTagIds {@link IStringList} - the tag IDs
+ * @param aIsAny boolean - sign that at least one tag must match, not all tags
+ */
+ public PqFilterTagIds( IStringList aTagIds, boolean aIsAny ) {
+ tagIds = new StringArrayList( aTagIds );
+ any = aIsAny;
+ }
+
+ /**
+ * Creates filter parameters.
+ *
+ * @param aTagIds {@link IStringList} - the tag IDs
+ * @param aIsAny boolean - sign that at least one tag must match, not all tags
+ * @return {@link ITsSingleFilterParams} - the filter parameters
+ * @throws TsNullArgumentRtException any argument = null
+ */
+ public static ITsSingleFilterParams makeFilterParams( IStringList aTagIds, boolean aIsAny ) {
+ IOptionSetEdit p = new OptionSet();
+ p.setValobj( OPID_TAG_IDS, aTagIds );
+ p.setBool( OPID_IS_ANY, aIsAny );
+ return new TsSingleFilterParams( TYPE_ID, p );
+ }
+
+ /**
+ * Returns a human-readable string of filter options.
+ *
+ * @param aParams {@link ITsSingleFilterParams} - the filter parameters
+ * @return String - single-line text
+ * @throws TsNullArgumentRtException any argument = null
+ * @throws TsIllegalArgumentRtException the parameters if not of this filter
+ */
+ @SuppressWarnings( "nls" )
+ public static final String makeHumanReadableString( ITsSingleFilterParams aParams ) {
+ TsNullArgumentRtException.checkNull( aParams );
+ TsIllegalArgumentRtException.checkFalse( aParams.typeId().equals( TYPE_ID ) );
+ StringBuilder sb = new StringBuilder();
+ IStringList tagIds = aParams.params().getValobj( PqFilterTagIds.OPID_TAG_IDS );
+ for( int i = 0, n = tagIds.size(); i < n; i++ ) {
+ sb.append( StridUtils.getLast( tagIds.get( i ) ) );
+ sb.append( ' ' );
+ }
+ if( tagIds.size() > 1 ) {
+ boolean isAny = aParams.params().getBool( PqFilterTagIds.OPID_IS_ANY );
+ String strIsAny = isAny ? "ANY" : "ALL";
+ return String.format( "Tags: %s %s", strIsAny, sb.toString() );
+ }
+ return String.format( "Tags: %s", sb.toString() );
+ }
+
+ @Override
+ public boolean accept( SecondSlice aObj ) {
+ if( any ) {
+ return TsCollectionsUtils.intersects( aObj.tagIds(), tagIds );
+ }
+ return TsCollectionsUtils.contains( aObj.tagIds(), tagIds );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/IPsxResources.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/IPsxResources.java
new file mode 100644
index 0000000..341987b
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/IPsxResources.java
@@ -0,0 +1,20 @@
+package com.hazard157.prisex24.explorer.m5;
+
+/**
+ * Localizable resources.
+ *
+ * @author hazard157
+ */
+@SuppressWarnings( "nls" )
+interface IPsxResources {
+
+ String STR_N_INQUIRY_ITEM_FP = "Фильтр";
+ String STR_D_INQUIRY_ITEM_FP = "Парамтры фильтра";
+ String MSG_ERR_NO_FILTER = "Надо задать хоть какие-нибудь параметры выборки";
+
+ String STR_N_COPY_INQUIRY = "Копировать";
+ String STR_D_COPY_INQUIRY = "Скопировать запрос с изменением идентификатора";
+ String STR_N_TMI_BY_ID = "По идентификаторам";
+ String STR_D_TMI_BY_ID = "Группировка в дерево по компонентам ИД-имени идентификатора";
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemEntityPanel.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemEntityPanel.java
new file mode 100644
index 0000000..346ab87
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemEntityPanel.java
@@ -0,0 +1,47 @@
+package com.hazard157.prisex24.explorer.m5;
+
+import org.eclipse.swt.widgets.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.m5.*;
+import org.toxsoft.core.tsgui.m5.gui.panels.impl.*;
+import org.toxsoft.core.tslib.bricks.validator.*;
+
+import com.hazard157.prisex24.explorer.*;
+import com.hazard157.prisex24.explorer.pdu.*;
+
+class InquiryItemEntityPanel
+ extends M5AbstractEntityPanel {
+
+ PanelAllFiltersSet panel = null;
+
+ public InquiryItemEntityPanel( ITsGuiContext aContext, IM5Model aModel, boolean aViewer ) {
+ super( aContext, aModel, aViewer );
+ }
+
+ @Override
+ protected Control doCreateControl( Composite aParent ) {
+ panel = new PanelAllFiltersSet( aParent, tsContext() );
+ panel.genericChangeEventer().addListener( aSource -> fireChangeEvent() );
+ return panel;
+ }
+
+ @Override
+ protected void doSetValues( IM5Bunch aBunch ) {
+ if( panel == null ) {
+ return;
+ }
+ if( aBunch != null ) {
+ panel.setFilterParams( aBunch.get( InquiryItemM5Model.FP ) );
+ }
+ else {
+ panel.resetFilterParans();
+ }
+ }
+
+ @Override
+ protected ValidationResult doCollectValues( IM5BunchEdit aBunch ) {
+ aBunch.set( InquiryItemM5Model.FP, panel.getInquiryItem() );
+ return ValidationResult.SUCCESS;
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemLifecycleManager.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemLifecycleManager.java
new file mode 100644
index 0000000..45b30aa
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemLifecycleManager.java
@@ -0,0 +1,46 @@
+package com.hazard157.prisex24.explorer.m5;
+
+import org.toxsoft.core.tsgui.m5.*;
+import org.toxsoft.core.tsgui.m5.model.impl.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.explorer.pdu.*;
+
+class InquiryItemLifecycleManager
+ extends M5LifecycleManager {
+
+ public InquiryItemLifecycleManager( IM5Model aModel, Inquiry aMaster ) {
+ super( aModel, true, true, true, true, aMaster );
+ TsNullArgumentRtException.checkNull( aMaster );
+ }
+
+ @Override
+ protected InquiryItem doCreate( IM5Bunch aValues ) {
+ InquiryItem fp = InquiryItemM5Model.FP.getFieldValue( aValues );
+ master().items().add( fp );
+ return fp;
+ }
+
+ @Override
+ protected InquiryItem doEdit( IM5Bunch aValues ) {
+ int index = master().items().indexOf( aValues.originalEntity() );
+ if( index >= 0 ) {
+ InquiryItem fp = InquiryItemM5Model.FP.getFieldValue( aValues );
+ master().items().set( index, fp );
+ return fp;
+ }
+ return null;
+ }
+
+ @Override
+ protected void doRemove( InquiryItem aEntity ) {
+ master().items().remove( aEntity );
+ }
+
+ @Override
+ protected IList doListEntities() {
+ return master().items();
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemM5Model.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemM5Model.java
new file mode 100644
index 0000000..9ce965c
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryItemM5Model.java
@@ -0,0 +1,92 @@
+package com.hazard157.prisex24.explorer.m5;
+
+import static com.hazard157.common.quants.secint.gui.ISecintM5Constants.*;
+import static com.hazard157.prisex24.explorer.m5.IPsxResources.*;
+import static org.toxsoft.core.tsgui.m5.IM5Constants.*;
+import static org.toxsoft.core.tsgui.m5.gui.mpc.IMultiPaneComponentConstants.*;
+import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
+
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.m5.*;
+import org.toxsoft.core.tsgui.m5.gui.mpc.impl.*;
+import org.toxsoft.core.tsgui.m5.gui.panels.*;
+import org.toxsoft.core.tsgui.m5.gui.panels.impl.*;
+import org.toxsoft.core.tsgui.m5.model.*;
+import org.toxsoft.core.tsgui.m5.model.impl.*;
+
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * Модель элементов {@link Inquiry#items()} типа {@link InquiryItem}.
+ *
+ * @author hazard157
+ */
+public class InquiryItemM5Model
+ extends M5Model {
+
+ /**
+ * Идентификатор модели.
+ */
+ public static final String MODEL_ID = PSX_ID_PREFIX + "InquiryItem"; //$NON-NLS-1$
+
+ /**
+ * Идентификатор поля {@link #FP}.
+ */
+ public static final String FID_FP = "fp"; //$NON-NLS-1$
+
+ /**
+ * Поле, содержащее саму сущность.
+ */
+ public static IM5FieldDef FP = new M5FieldDef<>( FID_FP, InquiryItem.class ) {
+
+ @Override
+ protected void doInit() {
+ setNameAndDescription( STR_N_INQUIRY_ITEM_FP, STR_D_INQUIRY_ITEM_FP );
+ setDefaultValue( new InquiryItem() );
+ setFlags( M5FF_COLUMN );
+ }
+
+ @Override
+ protected InquiryItem doGetFieldValue( InquiryItem aEntity ) {
+ return aEntity;
+ }
+
+ @Override
+ protected String doGetFieldValueName( InquiryItem aEntity ) {
+ return aEntity.toString();
+ }
+
+ };
+
+ /**
+ * Конструктор.
+ */
+ public InquiryItemM5Model() {
+ super( MODEL_ID, InquiryItem.class );
+ addFieldDefs( FP );
+ setPanelCreator( new M5DefaultPanelCreator() {
+
+ @Override
+ protected IM5EntityPanel doCreateEntityEditorPanel( ITsGuiContext aContext,
+ IM5LifecycleManager aLifecycleManager ) {
+ return new InquiryItemEntityPanel( aContext, model(), false );
+ }
+
+ @Override
+ protected IM5CollectionPanel doCreateCollEditPanel( ITsGuiContext aContext,
+ IM5ItemsProvider aItemsProvider, IM5LifecycleManager aLifecycleManager ) {
+ OPDEF_IS_ACTIONS_CRUD.setValue( aContext.params(), AV_TRUE );
+ MultiPaneComponentModown mpc =
+ new MultiPaneComponentModown<>( aContext, model(), aItemsProvider, aLifecycleManager );
+ return new M5CollectionPanelMpcModownWrapper<>( mpc, false );
+ }
+
+ } );
+ }
+
+ @Override
+ protected IM5LifecycleManager doCreateLifecycleManager( Object aMaster ) {
+ return new InquiryItemLifecycleManager( this, Inquiry.class.cast( aMaster ) );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryLifecycleManager.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryLifecycleManager.java
new file mode 100644
index 0000000..aa7c53b
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryLifecycleManager.java
@@ -0,0 +1,72 @@
+package com.hazard157.prisex24.explorer.m5;
+
+import static com.hazard157.prisex24.explorer.m5.InquiryM5Model.*;
+
+import org.toxsoft.core.tsgui.m5.*;
+import org.toxsoft.core.tsgui.m5.model.impl.*;
+import org.toxsoft.core.tslib.bricks.validator.*;
+import org.toxsoft.core.tslib.coll.*;
+
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * Менеджер ЖЦ сущностей {@link Inquiry}.
+ *
+ * @author hazard157
+ */
+class InquiryLifecycleManager
+ extends M5LifecycleManager {
+
+ public InquiryLifecycleManager( IM5Model aModel, IUnitExplorer aMaster ) {
+ super( aModel, true, true, true, true, aMaster );
+ }
+
+ private static final InquiryInfo makeInfo( IM5Bunch aValues ) {
+ String name = NAME.getFieldValue( aValues ).asString();
+ String descr = DESCRIPTION.getFieldValue( aValues ).asString();
+ return new InquiryInfo( name, descr );
+ }
+
+ @Override
+ protected ValidationResult doBeforeCreate( IM5Bunch aValues ) {
+ String id = ID.getFieldValue( aValues ).asString();
+ InquiryInfo info = makeInfo( aValues );
+ return master().canCreateItem( id, info );
+ }
+
+ @Override
+ protected Inquiry doCreate( IM5Bunch aValues ) {
+ String id = ID.getFieldValue( aValues ).asString();
+ InquiryInfo info = makeInfo( aValues );
+ return master().createItem( id, info );
+ }
+
+ @Override
+ protected ValidationResult doBeforeEdit( IM5Bunch aValues ) {
+ InquiryInfo info = makeInfo( aValues );
+ return master().canEditItem( aValues.originalEntity().id(), aValues.originalEntity().id(), info );
+ }
+
+ @Override
+ protected Inquiry doEdit( IM5Bunch aValues ) {
+ InquiryInfo info = makeInfo( aValues );
+ aValues.originalEntity().setInfo( info );
+ return aValues.originalEntity();
+ }
+
+ @Override
+ protected ValidationResult doBeforeRemove( Inquiry aEntity ) {
+ return master().canRemoveItem( aEntity.id() );
+ }
+
+ @Override
+ protected void doRemove( Inquiry aEntity ) {
+ master().removeItem( aEntity.id() );
+ }
+
+ @Override
+ protected IList doListEntities() {
+ return master().items();
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryM5Model.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryM5Model.java
new file mode 100644
index 0000000..37ebeee
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryM5Model.java
@@ -0,0 +1,101 @@
+package com.hazard157.prisex24.explorer.m5;
+
+import static com.hazard157.common.quants.secint.gui.ISecintM5Constants.*;
+import static org.toxsoft.core.tsgui.m5.IM5Constants.*;
+import static org.toxsoft.core.tsgui.m5.gui.mpc.IMultiPaneComponentConstants.*;
+import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
+
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.m5.gui.mpc.impl.*;
+import org.toxsoft.core.tsgui.m5.gui.panels.*;
+import org.toxsoft.core.tsgui.m5.gui.panels.impl.*;
+import org.toxsoft.core.tsgui.m5.model.*;
+import org.toxsoft.core.tsgui.m5.model.impl.*;
+import org.toxsoft.core.tsgui.m5.std.fields.*;
+import org.toxsoft.core.tslib.bricks.strid.impl.*;
+
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * Модель {@link Inquiry} для отображения в списках
+ *
+ * @author hazard157
+ */
+public class InquiryM5Model
+ extends M5Model {
+
+ /**
+ * The model ID.
+ */
+ public static final String MODEL_ID = PSX_ID_PREFIX + "Inquiry"; //$NON-NLS-1$
+
+ /**
+ * Field {@link Inquiry#id()}
+ */
+ public static final M5AttributeFieldDef ID = new M5StdFieldDefId<>() {
+
+ protected String doGetFieldValueName( Inquiry aEntity ) {
+ return StridUtils.getLast( aEntity.id() );
+ }
+
+ };
+
+ /**
+ * Field {@link Inquiry#nmName()}
+ */
+ public static final M5AttributeFieldDef NAME = new M5StdFieldDefName<>() {
+
+ @Override
+ protected void doInit() {
+ super.doInit();
+ setFlags( M5FF_COLUMN );
+ }
+
+ };
+
+ /**
+ * Field {@link Inquiry#description()}
+ */
+ public static final M5AttributeFieldDef DESCRIPTION = new M5StdFieldDefDescription<>() {
+
+ @Override
+ protected void doInit() {
+ super.doInit();
+ setFlags( M5FF_COLUMN );
+ }
+
+ };
+
+ /**
+ * Конструктор.
+ */
+ public InquiryM5Model() {
+ super( MODEL_ID, Inquiry.class );
+ addFieldDefs( ID, NAME, DESCRIPTION );
+ setPanelCreator( new M5DefaultPanelCreator() {
+
+ @Override
+ protected IM5CollectionPanel doCreateCollEditPanel( ITsGuiContext aContext,
+ IM5ItemsProvider aItemsProvider, IM5LifecycleManager aLifecycleManager ) {
+ OPDEF_IS_ACTIONS_CRUD.setValue( aContext.params(), AV_TRUE );
+ OPDEF_IS_SUPPORTS_TREE.setValue( aContext.params(), AV_TRUE );
+ OPDEF_IS_COLUMN_HEADER.setValue( aContext.params(), AV_FALSE );
+ MultiPaneComponentModown mpc = new InquiryMpc( aContext, model(), aItemsProvider, aLifecycleManager );
+ return new M5CollectionPanelMpcModownWrapper<>( mpc, false );
+ }
+
+ } );
+ }
+
+ @Override
+ protected IM5LifecycleManager doCreateDefaultLifecycleManager() {
+ IUnitExplorer unitExplorer = tsContext().get( IUnitExplorer.class );
+ return new InquiryLifecycleManager( this, unitExplorer );
+ }
+
+ @Override
+ protected IM5LifecycleManager doCreateLifecycleManager( Object aMaster ) {
+ return new InquiryLifecycleManager( this, IUnitExplorer.class.cast( aMaster ) );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryMpc.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryMpc.java
new file mode 100644
index 0000000..8062a83
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/m5/InquiryMpc.java
@@ -0,0 +1,183 @@
+package com.hazard157.prisex24.explorer.m5;
+
+import static com.hazard157.prisex24.IPrisex24CoreConstants.*;
+import static com.hazard157.prisex24.explorer.m5.IPsxResources.*;
+import static org.toxsoft.core.tsgui.bricks.actions.ITsStdActionDefs.*;
+import static org.toxsoft.core.tsgui.graphics.icons.ITsStdIconIds.*;
+import static org.toxsoft.core.tsgui.m5.IM5Constants.*;
+import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
+
+import org.toxsoft.core.tsgui.bricks.actions.*;
+import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.bricks.tsnodes.*;
+import org.toxsoft.core.tsgui.bricks.tstree.tmm.*;
+import org.toxsoft.core.tsgui.dialogs.datarec.*;
+import org.toxsoft.core.tsgui.graphics.icons.*;
+import org.toxsoft.core.tsgui.m5.*;
+import org.toxsoft.core.tsgui.m5.gui.*;
+import org.toxsoft.core.tsgui.m5.gui.mpc.impl.*;
+import org.toxsoft.core.tsgui.m5.model.*;
+import org.toxsoft.core.tsgui.m5.model.impl.*;
+import org.toxsoft.core.tsgui.panels.toolbar.*;
+import org.toxsoft.core.tslib.bricks.strid.coll.*;
+import org.toxsoft.core.tslib.bricks.strid.coll.impl.*;
+import org.toxsoft.core.tslib.bricks.strid.impl.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.coll.primtypes.*;
+import org.toxsoft.core.tslib.coll.primtypes.impl.*;
+
+import com.hazard157.prisex24.explorer.pdu.*;
+
+class InquiryMpc
+ extends MultiPaneComponentModown {
+
+ private static final String COPIED_INQUIRY_ID_SUFFIX = ".copy"; //$NON-NLS-1$
+
+ private static final String AID_COPY_INQUIRY = PSX_ACT_ID + ".CopyInquiry"; //$NON-NLS-1$
+
+ private static final ITsActionDef AI_COPY_INQUIRY = TsActionDef.ofPush2( AID_COPY_INQUIRY, //
+ STR_N_COPY_INQUIRY, STR_D_COPY_INQUIRY, ICONID_EDIT_COPY );
+
+ public static final ITsNodeKind NK_GROUP = new TsNodeKind<>( "IdGroup", String.class, true ); //$NON-NLS-1$
+ public static final ITsNodeKind NK_INQ = new TsNodeKind<>( "Inquiry", Inquiry.class, true ); //$NON-NLS-1$
+
+ static class TreeMakerByIds
+ implements ITsTreeMaker {
+
+ private DefaultTsNode> ensureGroupNode( String aId, IStridablesList aItems,
+ IStringMapEdit> aGroupNodes, ITsNode aRootNode, IListEdit aTopLevelNodes ) {
+ // если узел группы уже есть, выходим
+ DefaultTsNode> gn = aGroupNodes.findByKey( aId );
+ if( gn != null ) {
+ return gn;
+ }
+ ITsNode parent = aRootNode;
+ if( StridUtils.isIdAPath( aId ) ) {
+ String grandpaId = StridUtils.removeTailingIdNames( aId, 1 );
+ parent = ensureGroupNode( grandpaId, aItems, aGroupNodes, aRootNode, aTopLevelNodes );
+ }
+ Inquiry inq = aItems.findByKey( aId );
+ if( inq != null ) { // создаем группирующий узел с запросом
+ gn = new DefaultTsNode<>( NK_INQ, parent, inq );
+ }
+ else { // создаем группирующий узел со строкой идентификатора
+ gn = new DefaultTsNode<>( NK_GROUP, parent, aId );
+ gn.setName( StridUtils.getLast( aId ) );
+ }
+ if( parent == aRootNode ) {
+ aTopLevelNodes.add( gn );
+ }
+ else {
+ ((DefaultTsNode>)parent).addNode( gn );
+ }
+ aGroupNodes.put( aId, gn );
+ return gn;
+ }
+
+ @Override
+ public IList makeRoots( ITsNode aRootNode, IList aItems2 ) {
+ IListEdit topLevelNodes = new ElemArrayList<>();
+ // делаем сортированный список
+ IStridablesListBasicEdit items = new SortedStridablesList<>();
+ items.addAll( aItems2 );
+ // сформируем карту групповых узлов
+ IStringMapEdit> groupNodes = new StringMap<>();
+ for( Inquiry i : items ) {
+ int compsCount = StridUtils.getComponents( i.id() ).size();
+ // запросы с ИД-именем пропускаем
+ if( compsCount == 1 ) {
+ continue;
+ }
+ // создаем групповой узел
+ String parentId = StridUtils.removeTailingIdNames( i.id(), 1 );
+ ensureGroupNode( parentId, items, groupNodes, aRootNode, topLevelNodes );
+ }
+ // теперь создаем листья
+ for( Inquiry i : items ) {
+ // запросы с ИД-именем пока пропускаем
+ if( !StridUtils.isIdAPath( i.id() ) ) {
+ continue;
+ }
+ // создаем узлы, которых пока нет
+ if( !groupNodes.hasKey( i.id() ) ) {
+ String parentId = StridUtils.removeTailingIdNames( i.id(), 1 );
+ DefaultTsNode> parent = groupNodes.getByKey( parentId );
+ DefaultTsNode node = new DefaultTsNode<>( NK_INQ, parent, i );
+ parent.addNode( node );
+ }
+ }
+ // в конце - запросы с одним ИД-именем
+ for( Inquiry i : items ) {
+ if( !StridUtils.isIdAPath( i.id() ) && !groupNodes.hasKey( i.id() ) ) {
+ DefaultTsNode n = new DefaultTsNode<>( NK_INQ, aRootNode, i );
+ topLevelNodes.add( n );
+ continue;
+ }
+ }
+ return topLevelNodes;
+ }
+
+ @Override
+ public boolean isItemNode( ITsNode aNode ) {
+ return aNode.kind() == NK_INQ;
+ }
+
+ }
+
+ InquiryMpc( ITsGuiContext aContext, IM5Model aModel, IM5ItemsProvider aItemsProvider,
+ IM5LifecycleManager aLifecycleManager ) {
+ super( aContext, aModel, aItemsProvider, aLifecycleManager );
+ TreeModeInfo tmById = new TreeModeInfo<>( "ById", //$NON-NLS-1$
+ STR_N_TMI_BY_ID, STR_D_TMI_BY_ID, null, new TreeMakerByIds() );
+ treeModeManager().addTreeMode( tmById );
+ treeModeManager().setCurrentMode( tmById.id() );
+ }
+
+ @Override
+ protected ITsToolbar doCreateToolbar( ITsGuiContext aContext, String aName, EIconSize aIconSize,
+ IListEdit aActs ) {
+ int index = aActs.indexOf( ACDEF_ADD );
+ if( index >= 0 ) {
+ aActs.insert( index + 1, AI_COPY_INQUIRY );
+ }
+ else {
+ aActs.add( ACDEF_SEPARATOR );
+ aActs.add( AI_COPY_INQUIRY );
+ }
+ return super.doCreateToolbar( aContext, aName, aIconSize, aActs );
+ }
+
+ @Override
+ protected void doProcessAction( String aActionId ) {
+ switch( aActionId ) {
+ case AID_COPY_INQUIRY:
+ Inquiry sel = selectedItem();
+ if( sel == null ) {
+ return;
+ }
+ ITsDialogInfo cdi = TsDialogInfo.forCreateEntity( tsContext() );
+ IM5BunchEdit initVals = new M5BunchEdit<>( model() );
+ initVals.set( FID_ID, avStr( sel.id() + COPIED_INQUIRY_ID_SUFFIX ) );
+ initVals.set( FID_NAME, avStr( sel.nmName() ) );
+ initVals.set( FID_DESCRIPTION, avStr( sel.description() ) );
+ Inquiry inq = M5GuiUtils.askCreate( tsContext(), model(), initVals, cdi, lifecycleManager() );
+ if( inq != null ) {
+ for( InquiryItem i : sel.items() ) {
+ inq.items().add( new InquiryItem( i ) );
+ }
+ fillViewer( inq );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ protected void doUpdateActionsState( boolean aIsAlive, boolean aIsSel, Inquiry aSel ) {
+ toolbar().setActionEnabled( AID_COPY_INQUIRY, aIsSel );
+ tree().columnManager().columns().getByKey( FID_ID ).pack();
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/IPsxResources.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/IPsxResources.java
new file mode 100644
index 0000000..4e26907
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/IPsxResources.java
@@ -0,0 +1,15 @@
+package com.hazard157.prisex24.explorer.pdu;
+
+/**
+ * Localizable resources.
+ *
+ * @author hazard157
+ */
+@SuppressWarnings( "nls" )
+interface IPsxResources {
+
+ String STR_ALL_FP = "Всё";
+
+ String STR_EMPTY_INQUIRY = "Пустая выборка";
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/IUnitExplorer.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/IUnitExplorer.java
new file mode 100644
index 0000000..a083295
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/IUnitExplorer.java
@@ -0,0 +1,15 @@
+package com.hazard157.prisex24.explorer.pdu;
+
+import org.toxsoft.core.txtproj.lib.sinent.*;
+
+/**
+ * Explorer saved inquiries.
+ *
+ * @author hazard157
+ */
+public interface IUnitExplorer
+ extends ISinentManager {
+
+ // nop
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/Inquiry.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/Inquiry.java
new file mode 100644
index 0000000..753f2dc
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/Inquiry.java
@@ -0,0 +1,89 @@
+package com.hazard157.prisex24.explorer.pdu;
+
+import static com.hazard157.prisex24.explorer.pdu.IPsxResources.*;
+
+import org.toxsoft.core.tslib.bricks.validator.impl.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.coll.notifier.*;
+import org.toxsoft.core.tslib.coll.notifier.basis.*;
+import org.toxsoft.core.tslib.coll.notifier.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+import org.toxsoft.core.txtproj.lib.sinent.*;
+
+/**
+ * Explorer selection -a sequence of filters applied to episodes.
+ *
+ * @author hazard157
+ */
+public class Inquiry
+ extends AbstractSinentity {
+
+ private final ITsCollectionChangeListener collectionChangeListener =
+ ( aSource, aOp, aItem ) -> changeHelper().fireChangeEvent();
+
+ private final INotifierListEdit fpList =
+ new NotifierListEditWrapper<>( new ElemLinkedBundleList() );
+
+ /**
+ * Constructor.
+ *
+ * @param aId String - the episode ID
+ * @param aInfo {@link InquiryInfo} - info about inquiry
+ * @throws TsNullArgumentRtException any argument = null
+ * @throws TsValidationFailedRtException ID is not an IDpath
+ */
+ public Inquiry( String aId, InquiryInfo aInfo ) {
+ super( aId, aInfo );
+ fpList.addCollectionChangeListener( collectionChangeListener );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // IStridable
+ //
+
+ @Override
+ public String nmName() {
+ return info().name();
+ }
+
+ @Override
+ public String description() {
+ return info().description();
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Returns a list of filter parameters in the order they are applied.
+ *
+ * @return {@link INotifierListEdit}<{@link InquiryItem}> - editable list of filter options
+ */
+ public INotifierListEdit items() {
+ return fpList;
+ }
+
+ // ------------------------------------------------------------------------------------
+ // Object
+ //
+
+ @SuppressWarnings( "nls" )
+ @Override
+ public String toString() {
+ if( fpList.isEmpty() ) {
+ return STR_EMPTY_INQUIRY;
+ }
+ StringBuilder sb = new StringBuilder();
+ for( int i = 0, n = fpList.size(); i < n; i++ ) {
+ sb.append( "(" );
+ sb.append( fpList.get( i ).toString() );
+ sb.append( ")" );
+ if( i < n - 1 ) {
+ sb.append( " && " );
+ }
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/InquiryInfo.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/InquiryInfo.java
new file mode 100644
index 0000000..79a87e7
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/InquiryInfo.java
@@ -0,0 +1,50 @@
+package com.hazard157.prisex24.explorer.pdu;
+
+import org.toxsoft.core.tslib.utils.errors.*;
+
+/**
+ * Description of {@link Inquiry}.
+ *
+ * @author hazard157
+ */
+public final class InquiryInfo {
+
+ private final String name;
+ private final String description;
+
+ /**
+ * Constructor.
+ *
+ * @param aName String - the name
+ * @param aDescription String - the description
+ * @throws TsNullArgumentRtException any argument = null
+ */
+ public InquiryInfo( String aName, String aDescription ) {
+ TsNullArgumentRtException.checkNulls( aName, aDescription );
+ name = aName;
+ description = aDescription;
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Returns the inquiry name.
+ *
+ * @return String - the inquiry name
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns the inquiry description.
+ *
+ * @return String - the inquiry description
+ */
+ public String description() {
+ return description;
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/InquiryItem.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/InquiryItem.java
new file mode 100644
index 0000000..0399716
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/InquiryItem.java
@@ -0,0 +1,151 @@
+package com.hazard157.prisex24.explorer.pdu;
+
+import static com.hazard157.prisex24.explorer.pdu.IPsxResources.*;
+
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.bricks.filter.impl.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.math.logicop.*;
+import org.toxsoft.core.tslib.utils.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.prisex24.explorer.filters.*;
+
+/**
+ * Filter selection from episodes.
+ *
+ * These are the parameters for one filter of all types, combined by AND.
+ *
+ * @author hazard157
+ */
+public final class InquiryItem {
+
+ private final IMapEdit fpMap = new ElemMap<>();
+ private final IMapEdit notMap = new ElemMap<>();
+
+ /**
+ * Creates item corresponding to {@link ITsCombiFilterParams#ALL}.
+ */
+ public InquiryItem() {
+ for( EPqSingleFilterKind k : EPqSingleFilterKind.asList() ) {
+ notMap.put( k, Boolean.FALSE );
+ }
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param aSource {@link InquiryItem} - the source
+ * @throws TsNullArgumentRtException any argument = null
+ */
+ public InquiryItem( InquiryItem aSource ) {
+ this();
+ TsNullArgumentRtException.checkNull( aSource );
+ for( EPqSingleFilterKind k : aSource.fpMap.keys() ) {
+ fpMap.put( k, aSource.fpMap.getByKey( k ) );
+ setInverted( k, aSource.isInverted( k ) );
+ }
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Returns all filters making this item.
+ *
+ * @return {@link IMapEdit}<{@link EPqSingleFilterKind},{@link ITsSingleFilterParams}> - the filters map
+ */
+ public IMapEdit fpMap() {
+ return fpMap;
+ }
+
+ /**
+ * Determines if filter of the specified kind is inverted.
+ *
+ * @param aKind {@link EPqSingleFilterKind} - the filter kind
+ * @return boolean - inverted sign
+ * @throws TsNullArgumentRtException any argument = null
+ */
+ public boolean isInverted( EPqSingleFilterKind aKind ) {
+ return notMap.getByKey( aKind ).booleanValue();
+ }
+
+ /**
+ * Sets the {@link #isInverted(EPqSingleFilterKind)} sign.
+ *
+ * @param aKind {@link EPqSingleFilterKind} - the filter kind
+ * @param aInverted boolean - inverted sign
+ * @throws TsNullArgumentRtException any argument = null
+ */
+ public void setInverted( EPqSingleFilterKind aKind, boolean aInverted ) {
+ notMap.put( aKind, Boolean.valueOf( aInverted ) );
+ }
+
+ /**
+ * Creates and returns the parameters for {@link ITsFilter} creation..
+ *
+ * For an empty item returns {@link ITsCombiFilterParams#NONE}.
+ *
+ * @return {@link ITsCombiFilterParams} - parameters to create {@link ITsFilter}
+ */
+ public ITsCombiFilterParams getFilterParams() {
+ ITsCombiFilterParams result = ITsCombiFilterParams.ALL;
+ for( EPqSingleFilterKind kind : EPqSingleFilterKind.asList() ) {
+ ITsSingleFilterParams sp = fpMap.findByKey( kind );
+ if( sp != null ) {
+ // first, from a single filter, we create a combi-filter, taking into account the inversion
+ boolean isInverted = isInverted( kind );
+ ITsCombiFilterParams cp = TsCombiFilterParams.createSingle( sp, isInverted );
+ // add to resulting params
+ result = TsCombiFilterParams.createCombi( result, ELogicalOp.AND, cp );
+ }
+ }
+ return result;
+ }
+
+ // ------------------------------------------------------------------------------------
+ // Object
+ //
+
+ @SuppressWarnings( "nls" )
+ @Override
+ public String toString() {
+ if( fpMap.isEmpty() ) {
+ return STR_ALL_FP;
+ }
+ StringBuilder fpSb = new StringBuilder();
+ for( int i = 0; i < fpMap.size(); i++ ) {
+ EPqSingleFilterKind k = fpMap.keys().get( i );
+ String s = EPqSingleFilterKind.makeHumanReadableString( fpMap.getByKey( k ) );
+ if( isInverted( k ) ) {
+ s = "NOT(" + s + ")";
+ }
+ fpSb.append( s );
+ if( i < fpMap.size() - 1 ) {
+ fpSb.append( " && " );
+ }
+ }
+ return fpSb.toString();
+ }
+
+ @Override
+ public boolean equals( Object aThat ) {
+ if( aThat == this ) {
+ return true;
+ }
+ if( aThat instanceof InquiryItem that ) {
+ return fpMap.equals( that.fpMap );
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = TsLibUtils.INITIAL_HASH_CODE;
+ result = TsLibUtils.PRIME * result + fpMap.hashCode();
+ return result;
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryInfoKeeper.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryInfoKeeper.java
new file mode 100644
index 0000000..d5e1b33
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryInfoKeeper.java
@@ -0,0 +1,58 @@
+package com.hazard157.prisex24.explorer.pdu.impl;
+
+import static org.toxsoft.core.tslib.bricks.strio.IStrioHardConstants.*;
+
+import org.toxsoft.core.tslib.bricks.keeper.*;
+import org.toxsoft.core.tslib.bricks.strio.*;
+
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * Keeper of the {@link InquiryInfo}.
+ *
+ * @author hazard157
+ */
+public class InquiryInfoKeeper
+ extends AbstractEntityKeeper {
+
+ private static final String KW_INFO = "Info"; //$NON-NLS-1$
+
+ /**
+ * The keeper singleton.
+ */
+ public static final IEntityKeeper KEEPER = new InquiryInfoKeeper();
+
+ private InquiryInfoKeeper() {
+ super( InquiryInfo.class, EEncloseMode.ENCLOSES_KEEPER_IMPLEMENTATION, null );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // AbstractEntityKeeper
+ //
+
+ @Override
+ protected void doWrite( IStrioWriter aSw, InquiryInfo aEntity ) {
+ aSw.writeAsIs( KW_INFO );
+ aSw.writeChars( CHAR_SPACE, CHAR_EQUAL, CHAR_SPACE, CHAR_SET_BEGIN );
+ aSw.writeSpace();
+ aSw.writeQuotedString( aEntity.name() );
+ aSw.writeSeparatorChar();
+ aSw.writeSpace();
+ aSw.writeQuotedString( aEntity.description() );
+ aSw.writeSpace();
+ aSw.writeChar( CHAR_SET_END );
+ }
+
+ @Override
+ protected InquiryInfo doRead( IStrioReader aSr ) {
+ aSr.ensureString( KW_INFO );
+ aSr.ensureChar( CHAR_EQUAL );
+ aSr.readSetBegin();
+ String name = aSr.readQuotedString();
+ aSr.ensureSeparatorChar();
+ String description = aSr.readQuotedString();
+ aSr.readSetNext();
+ return new InquiryInfo( name, description );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryItemKeeper.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryItemKeeper.java
new file mode 100644
index 0000000..86c2cad
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryItemKeeper.java
@@ -0,0 +1,73 @@
+package com.hazard157.prisex24.explorer.pdu.impl;
+
+import static org.toxsoft.core.tslib.bricks.strio.IStrioHardConstants.*;
+
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.bricks.filter.impl.*;
+import org.toxsoft.core.tslib.bricks.keeper.*;
+import org.toxsoft.core.tslib.bricks.strio.*;
+
+import com.hazard157.prisex24.explorer.filters.*;
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * Keeper of the {@link InquiryItem}.
+ *
+ * @author hazard157
+ */
+class InquiryItemKeeper
+ extends AbstractEntityKeeper {
+
+ /**
+ * Keeper singleton.
+ */
+ public static final IEntityKeeper KEEPER = new InquiryItemKeeper();
+
+ private InquiryItemKeeper() {
+ super( InquiryItem.class, EEncloseMode.ENCLOSES_KEEPER_IMPLEMENTATION, null );
+ }
+
+ @Override
+ protected void doWrite( IStrioWriter sw, InquiryItem aEntity ) {
+ sw.writeChar( CHAR_ARRAY_BEGIN );
+ if( aEntity.fpMap().isEmpty() ) {
+ sw.writeChar( CHAR_ARRAY_END );
+ return;
+ }
+ sw.incNewLine();
+ for( int i = 0; i < aEntity.fpMap().size(); i++ ) {
+ sw.writeChars( CHAR_SET_BEGIN, CHAR_SPACE );
+ EPqSingleFilterKind k = aEntity.fpMap().keys().get( i );
+ TsSingleFilterParamsKeeper.KEEPER.write( sw, aEntity.fpMap().getByKey( k ) );
+ sw.writeSeparatorChar();
+ sw.writeSpace();
+ sw.writeBoolean( aEntity.isInverted( k ) );
+ sw.writeChars( CHAR_SPACE, CHAR_SET_END );
+ if( i < aEntity.fpMap().size() - 1 ) {
+ sw.writeSeparatorChar();
+ sw.writeEol();
+ }
+ }
+ sw.decNewLine();
+ sw.writeChar( CHAR_ARRAY_END );
+ }
+
+ @Override
+ protected InquiryItem doRead( IStrioReader sr ) {
+ InquiryItem item = new InquiryItem();
+ if( sr.readArrayBegin() ) {
+ do {
+ sr.ensureChar( CHAR_SET_BEGIN );
+ ITsSingleFilterParams p = TsSingleFilterParamsKeeper.KEEPER.read( sr );
+ EPqSingleFilterKind k = EPqSingleFilterKind.getById( p.typeId() );
+ sr.ensureSeparatorChar();
+ boolean isInverted = sr.readBoolean();
+ item.fpMap().put( k, p );
+ item.setInverted( k, isInverted );
+ sr.ensureChar( CHAR_SET_END );
+ } while( sr.readArrayNext() );
+ }
+ return item;
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryKeeper.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryKeeper.java
new file mode 100644
index 0000000..2232d35
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/InquiryKeeper.java
@@ -0,0 +1,60 @@
+package com.hazard157.prisex24.explorer.pdu.impl;
+
+import org.toxsoft.core.tslib.bricks.keeper.*;
+import org.toxsoft.core.tslib.bricks.strio.*;
+import org.toxsoft.core.tslib.bricks.strio.impl.*;
+import org.toxsoft.core.tslib.coll.*;
+
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * Keeper of the {@link Inquiry}.
+ *
+ * @author hazard157
+ */
+public class InquiryKeeper
+ extends AbstractEntityKeeper {
+
+ /**
+ * The keeper singleton.
+ */
+ public static final IEntityKeeper KEEPER = new InquiryKeeper();
+
+ private static final String KW_INQUIRY_PARAMS = "InquiryParams"; //$NON-NLS-1$
+
+ private InquiryKeeper() {
+ super( Inquiry.class, EEncloseMode.ENCLOSES_BASE_CLASS, null );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // AbstractEntityKeeper
+ //
+
+ @Override
+ protected void doWrite( IStrioWriter sw, Inquiry aEntity ) {
+ sw.incNewLine();
+ // id()
+ sw.writeAsIs( aEntity.id() );
+ sw.writeSeparatorChar();
+ sw.writeEol();
+ // info();
+ InquiryInfoKeeper.KEEPER.write( sw, aEntity.info() );
+ sw.writeEol();
+ // fpList()
+ StrioUtils.writeCollection( sw, KW_INQUIRY_PARAMS, aEntity.items(), InquiryItemKeeper.KEEPER, true );
+ sw.writeEol();
+ sw.decNewLine();
+ }
+
+ @Override
+ protected Inquiry doRead( IStrioReader sr ) {
+ String id = sr.readIdPath();
+ sr.ensureSeparatorChar();
+ InquiryInfo info = InquiryInfoKeeper.KEEPER.read( sr );
+ Inquiry es = new Inquiry( id, info );
+ IList ll = StrioUtils.readCollection( sr, KW_INQUIRY_PARAMS, InquiryItemKeeper.KEEPER );
+ es.items().setAll( ll );
+ return es;
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/UnitExplorer.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/UnitExplorer.java
new file mode 100644
index 0000000..0738c57
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pdu/impl/UnitExplorer.java
@@ -0,0 +1,37 @@
+package com.hazard157.prisex24.explorer.pdu.impl;
+
+import org.toxsoft.core.tslib.utils.*;
+import org.toxsoft.core.txtproj.lib.sinent.*;
+
+import com.hazard157.prisex24.explorer.pdu.*;
+
+/**
+ * {@link IUnitExplorer} implementation.
+ *
+ * @author hazard157
+ */
+public class UnitExplorer
+ extends AbstractSinentManager
+ implements IUnitExplorer {
+
+ /**
+ * Constructor.
+ */
+ public UnitExplorer() {
+ super( TsLibUtils.EMPTY_STRING, InquiryKeeper.KEEPER );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // AbstractSinentManager
+ //
+
+ @Override
+ protected Inquiry doCreateItem( String aId, InquiryInfo aInfo ) {
+ return new Inquiry( aId, aInfo );
+ }
+
+ // ------------------------------------------------------------------------------------
+ // IUnitExplorer
+ //
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/IPsxResources.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/IPsxResources.java
new file mode 100644
index 0000000..1aa1e50
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/IPsxResources.java
@@ -0,0 +1,16 @@
+package com.hazard157.prisex24.explorer.pq;
+
+/**
+ * Localizable resources.
+ *
+ * @author hazard157
+ */
+@SuppressWarnings( "nls" )
+interface IPsxResources {
+
+ /**
+ * {@link PqQueryProcessor}
+ */
+ String FMT_WARN_UNKNOWN_EPISODE_IN_QUERY = "В запросе участвет неизвестный эпизод '%s'";
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/PqQueryProcessor.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/PqQueryProcessor.java
new file mode 100644
index 0000000..d9c7208
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/PqQueryProcessor.java
@@ -0,0 +1,152 @@
+package com.hazard157.prisex24.explorer.pq;
+
+import static com.hazard157.prisex24.explorer.pq.IPsxResources.*;
+
+import org.toxsoft.core.tslib.bricks.filter.*;
+import org.toxsoft.core.tslib.bricks.filter.impl.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.coll.primtypes.*;
+import org.toxsoft.core.tslib.coll.primtypes.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+import org.toxsoft.core.tslib.utils.logs.impl.*;
+
+import com.hazard157.common.quants.secint.*;
+import com.hazard157.prisex24.explorer.filters.*;
+import com.hazard157.psx.common.stuff.svin.*;
+import com.hazard157.psx.proj3.episodes.*;
+
+/**
+ * Процессор (исполнитель) запросов.
+ *
+ * Процессор выдает результат запроса {@link #queryData(ITsCombiFilterParams)} над входными данными
+ * {@link #inputData()}.
+ *
+ * @author hazard157
+ */
+public class PqQueryProcessor {
+
+ private final PqResultSet inputData;
+
+ /**
+ * Набор посекундных срезов, соответствующий входным данным.
+ *
+ * Набор представляь из собой сложную струтуру:
+ *
+ * - сначала это карта, ключи в которых - идентификатор эпизода, а значения посекундные срезы эпизода;
+ * - посекундные срезы эпизода организованы в виде списка, который содержит в себе карту срезов, соответствующие
+ * {@link Svin}-ам входных данных. Список сортирован по времени, поскольку {@link PqResultSet} содержит сортированные
+ * списки {@link Svin}-ов;
+ * - срез {@link Svin}-а это карта "секунда" - {@link SecondSlice}.
+ *
+ */
+ private final IStringMapEdit>> secondSlices = new StringMap<>();
+
+ private final ITsFilterFactoriesRegistry ffReg = new TsFilterFactoriesRegistry<>( SecondSlice.class );
+
+ /**
+ * Конструктор с инвариантами.
+ *
+ * @param aInputData {@link PqResultSet} - входные данные
+ * @param aEpMan {@link IUnitEpisodes} - менеджер эпизодов
+ * @throws TsNullArgumentRtException любой аргумент = null
+ */
+ public PqQueryProcessor( PqResultSet aInputData, IUnitEpisodes aEpMan ) {
+ TsNullArgumentRtException.checkNull( aInputData );
+ inputData = aInputData;
+ for( EPqSingleFilterKind k : EPqSingleFilterKind.asList() ) {
+ ffReg.register( k.factory() );
+ }
+ if( !inputData.isEmpty() ) {
+ for( String epId : inputData.epinsMap().keys() ) {
+ // проверка корректности (существования эпизода)
+ IEpisode e = aEpMan.items().findByKey( epId );
+ if( e == null ) {
+ LoggerUtils.errorLogger().warning( FMT_WARN_UNKNOWN_EPISODE_IN_QUERY, epId );
+ continue;
+ }
+ // создаем список карт
+ IListEdit> list = new ElemArrayList<>();
+ secondSlices.put( epId, list );
+ // формирует для каждоко эпизода посекундный срез состояний QpFilterInput
+ for( Svin svin : inputData.epinsMap().getByKey( epId ) ) {
+ IIntMapEdit ssMap = new IntMap<>( 157 );
+ list.add( ssMap );
+ for( int sec = svin.interval().start(); sec <= svin.interval().end(); sec++ ) {
+ SecondSlice fin = e.slices().get( sec );
+ ssMap.put( sec, fin );
+ }
+ }
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Возвращает набор входных данных, над которыми будет осуществлена выборка.
+ *
+ * Входные данные задаются один раз в конструкторе процессора.
+ *
+ * @return {@link PqResultSet} - входные данные
+ */
+ public PqResultSet inputData() {
+ return inputData;
+ }
+
+ /**
+ * Выполняет запрос - выбирает данные из {@link #inputData()} по критериям аргумента - параметров запроса.
+ *
+ * Если входные данные пустые, то возвращает пустой набор.
+ *
+ * @param aFilterParams {@link ITsCombiFilterParams} - параметры запроса
+ * @return {@link PqResultSet} - результаты запроса
+ * @throws TsNullArgumentRtException аргумент = null
+ */
+ public PqResultSet queryData( ITsCombiFilterParams aFilterParams ) {
+ TsNullArgumentRtException.checkNull( aFilterParams );
+ if( inputData.isEmpty() ) {
+ return PqResultSet.EMPTY;
+ }
+ if( aFilterParams == ITsCombiFilterParams.NONE ) {
+ return PqResultSet.EMPTY;
+ }
+ if( aFilterParams == ITsCombiFilterParams.ALL ) {
+ return inputData;
+ }
+ IListBasicEdit svins = new ElemLinkedBundleList<>();
+ ITsFilter filter = TsCombiFilter.create( aFilterParams, ffReg );
+ for( String epId : secondSlices.keys() ) {
+ IListEdit> list = secondSlices.getByKey( epId );
+ for( IIntMap ssMap : list ) {
+ int startSec = -1;
+ int prevSec = -1;
+ for( int i = 0; i < ssMap.size(); i++ ) {
+ int sec = ssMap.keys().getValue( i );
+ SecondSlice ss = ssMap.values().get( i );
+ boolean accepted = filter.accept( ss );
+ if( accepted ) {
+ if( startSec == -1 ) {
+ startSec = sec;
+ }
+ prevSec = sec;
+ }
+ else {
+ if( startSec != -1 ) {
+ svins.add( new Svin( epId, new Secint( startSec, prevSec ) ) );
+ startSec = -1;
+ prevSec = -1;
+ }
+ }
+ }
+ if( startSec >= 0 ) {
+ svins.add( new Svin( epId, new Secint( startSec, prevSec ) ) );
+ }
+ }
+ }
+ return new PqResultSet( svins );
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/PqResultSet.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/PqResultSet.java
new file mode 100644
index 0000000..7ebe992
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/explorer/pq/PqResultSet.java
@@ -0,0 +1,114 @@
+package com.hazard157.prisex24.explorer.pq;
+
+import org.toxsoft.core.tslib.bricks.strid.*;
+import org.toxsoft.core.tslib.coll.*;
+import org.toxsoft.core.tslib.coll.impl.*;
+import org.toxsoft.core.tslib.coll.primtypes.*;
+import org.toxsoft.core.tslib.coll.primtypes.impl.*;
+import org.toxsoft.core.tslib.utils.errors.*;
+
+import com.hazard157.common.quants.secint.*;
+import com.hazard157.psx.common.stuff.svin.*;
+import com.hazard157.psx.proj3.episodes.*;
+
+/**
+ * Набор результатов запроса.
+ *
+ * Набор используется и как вход для процессора запросов {@link PqQueryProcessor}, так и возвращается результат запроса.
+ * Таким образом, можно делать запросы к результатам запроса.
+ *
+ * Для создания начального набора (сождержащего все интерваы всех эпизодов) используйте
+ * {@link #createFull(IUnitEpisodes)}.
+ *
+ * Это неизменяемый класс.
+ *
+ * @author hazard157
+ */
+public class PqResultSet {
+
+ /**
+ * Всегда пустой набор.
+ */
+ public static final PqResultSet EMPTY = new PqResultSet();
+
+ private final IStringMapEdit> epinsMap = new StringMap<>();
+
+ /**
+ * Конструктор со всеми инвариантами.
+ *
+ * @param aEpins {@link IList}<{@link Svin}> - список интервалов эпизодов
+ * @throws TsNullArgumentRtException аргумент = null
+ */
+ public PqResultSet( IList aEpins ) {
+ TsNullArgumentRtException.checkNull( aEpins );
+ for( Svin epin : aEpins ) {
+ IListBasicEdit list = (IListBasicEdit)epinsMap.findByKey( epin.episodeId() );
+ if( list == null ) {
+ list = new SortedElemLinkedBundleList<>();
+ epinsMap.put( epin.episodeId(), list );
+ }
+ list.add( epin );
+ }
+ }
+
+ /**
+ * Создает набор, содержащий все интервалы всех эпизодов.
+ *
+ * @param aEpMan {@link IUnitEpisodes} - менеджер эпизодов
+ * @return {@link PqResultSet} - "корневой" набор, откуда пойдет первый запрос
+ * @throws TsNullArgumentRtException аргумент = null
+ */
+ public static PqResultSet createFull( IUnitEpisodes aEpMan ) {
+ IListEdit list = new ElemLinkedBundleList<>();
+ for( IEpisode e : aEpMan.items() ) {
+ Svin svin = new Svin( e.id(), IStridable.NONE_ID, new Secint( 0, e.info().duration() - 1 ) );
+ list.add( svin );
+ }
+ return new PqResultSet( list );
+ }
+
+ private PqResultSet() {
+ // nop
+ }
+
+ // ------------------------------------------------------------------------------------
+ // API
+ //
+
+ /**
+ * Определяет, содержится ли что-нибудь в результате.
+ *
+ * На данный момент равнозначно проверке на пустоту списка {@link #epinsMap()}. Сделан с учтотом возможности
+ * добавления полей к класс.
+ *
+ * @return boolean - признак непустого сожержимого
+ */
+ public boolean isEmpty() {
+ return epinsMap.isEmpty();
+ }
+
+ /**
+ * Возвращает всю выборку в виде карты "ИД эпизода" - "список интервалов эпизода".
+ *
+ * Списки в карте сортированы по правилам {@link Svin#compareTo(Svin)}.
+ *
+ * @return IStringMap<IList<{@link Svin}>> - карта "ИД эпизода" - "список интервалов эпизода"
+ */
+ public IStringMap> epinsMap() {
+ return epinsMap;
+ }
+
+ /**
+ * Возвращает все интервалы в виде одного сортированного списка.
+ *
+ * @return IList<{@link Svin}> - список всех интервалов в результате
+ */
+ public IList listAllSvins() {
+ IListBasicEdit result = new SortedElemLinkedBundleList<>();
+ for( IList ll : epinsMap.values() ) {
+ result.addAll( ll );
+ }
+ return result;
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/EpisodeVisualsProvider.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/EpisodeVisualsProvider.java
index ddcdc35..600207f 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/EpisodeVisualsProvider.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/EpisodeVisualsProvider.java
@@ -77,18 +77,14 @@ public String getDescription( IEpisode aItem ) {
@Override
public TsImage getThumb( IEpisode aItem, EThumbSize aThumbSize ) {
- boolean isStillForced = APPREF_WELCOME_IS_FORCE_STILL.getValue( prefBundle.prefs() ).asBool();
- File ff = cofsFrames().findFrameFile( aItem.frame() );
+ File f = cofsFrames().findFrameFile( aItem.frame() );
TsImage mi = null;
- if( ff != null ) {
- mi = imageManager().findThumb( ff, aThumbSize );
+ if( f != null ) {
+ mi = imageManager().findThumb( f, aThumbSize );
}
if( mi == null ) {
mi = getNoneImageForEpisode( aThumbSize );
}
- if( mi.isAnimated() && isStillForced ) {
- mi = TsImage.create( mi.image() ); // SWT image will be disposed when anumated mi disposes
- }
return mi;
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/fravisum/IPsxFrameVisumplesProviderConstants.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/fravisum/IPsxFrameVisumplesProviderConstants.java
index dbad09b..ce8b7e5 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/fravisum/IPsxFrameVisumplesProviderConstants.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/fravisum/IPsxFrameVisumplesProviderConstants.java
@@ -33,8 +33,8 @@ public interface IPsxFrameVisumplesProviderConstants {
*/
IDataDef OPDEF_VP_FRAME = DataDef.create( OPID_VP_FRAME, VALOBJ, //
TSID_IS_MANDATORY, AV_TRUE, //
- TSID_KEEPER_ID, FrameKeeper.KEEPER_ID, //
- TSID_DEFAULT_VALUE, FrameKeeper.AV_FRAME_NONE //
+ TSID_KEEPER_ID, Frame.KEEPER_ID, //
+ TSID_DEFAULT_VALUE, Frame.AV_FRAME_NONE //
);
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/frview/IFramesGridViewer.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/frview/IFramesGridViewer.java
index 4ca12df..652eb2a 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/frview/IFramesGridViewer.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/frview/IFramesGridViewer.java
@@ -79,6 +79,27 @@ public interface IFramesGridViewer
*/
void setDisplayedInfoFlags( int aPgvLfFlags );
+ /**
+ * Determines if still image display is forced.
+ *
+ * When "force still" mode is activated for all animated images the still image {@link TsImage#image()} is displayed,
+ * as soon as mode is deactivated image animation continues.
+ *
+ * Initially the mode is deactiveted, so animations are turned on.
+ *
+ * @return boolean - true
no animation, still images are displayed, false
- animation is on
+ */
+ boolean isForceStill();
+
+ /**
+ * Sets {@link #isForceStill()} mode.
+ *
+ * The changes are applied immediately.
+ *
+ * @param aForceStill boolean - true
to turn off animation
+ */
+ void setFocreStill( boolean aForceStill );
+
/**
* Returns viewer implementing SWT control.
*
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/frview/impl/FramesGridViewer.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/frview/impl/FramesGridViewer.java
index 8bddf9b..824fb39 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/frview/impl/FramesGridViewer.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/glib/frview/impl/FramesGridViewer.java
@@ -137,6 +137,16 @@ public void setDisplayedInfoFlags( int aPgvLfFlags ) {
}
}
+ @Override
+ public boolean isForceStill() {
+ return pgViewer.isForceStill();
+ }
+
+ @Override
+ public void setFocreStill( boolean aForceStill ) {
+ pgViewer.setFocreStill( aForceStill );
+ }
+
@Override
public TsComposite getControl() {
return this;
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/episodes/EpisodeEditPanelController.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/episodes/EpisodeEditPanelController.java
index 018394d..d24852a 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/episodes/EpisodeEditPanelController.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/episodes/EpisodeEditPanelController.java
@@ -13,7 +13,7 @@
import org.toxsoft.core.tslib.coll.impl.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.m5.std.*;
import com.hazard157.prisex24.valeds.frames.*;
import com.hazard157.psx.proj3.episodes.*;
@@ -46,9 +46,9 @@ private void updateFrameSelectionCriteria() {
private void updateDefaultTrailerSelectionCombo() {
ValedComboSelector trailerIdCombo = getEditor( FID_DEF_TRAILER_ID, ValedComboSelector.class );
String episodeId = lastValues().get( EpisodeM5Model.EPISODE_ID );
- IList allTrailers = cofsTrailers().listEpisodeTrailerFiles( episodeId );
+ IList allTrailers = cofsTrailers().listEpisodeTrailerFiles( episodeId );
IListEdit avTraIds = new ElemArrayList<>();
- for( OptedFile trailer : allTrailers ) {
+ for( IOptedFile trailer : allTrailers ) {
String name = TsFileUtils.extractBareFileName( trailer.file().getName() );
avTraIds.add( avStr( name ) );
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/episodes/EpisodeViewerPanelController.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/episodes/EpisodeViewerPanelController.java
index 9231c67..4217ed6 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/episodes/EpisodeViewerPanelController.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/episodes/EpisodeViewerPanelController.java
@@ -12,7 +12,7 @@
import org.toxsoft.core.tslib.coll.impl.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.*;
import com.hazard157.prisex24.m5.std.*;
import com.hazard157.psx.common.utils.*;
@@ -51,9 +51,9 @@ private void updateDefaultTrailerSelectionCombo( String aEpisodeId ) {
trailerIdCombo.setItems( EMPTY_IDS_LIST );
return;
}
- IList allTrailers = cofsTrailers().listEpisodeTrailerFiles( e.id() );
+ IList allTrailers = cofsTrailers().listEpisodeTrailerFiles( e.id() );
IListEdit avTraIds = new ElemArrayList<>();
- for( OptedFile trailer : allTrailers ) {
+ for( IOptedFile trailer : allTrailers ) {
String name = TsFileUtils.extractBareFileName( trailer.file().getName() );
avTraIds.add( avStr( name ) );
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/plep/StirM5Model.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/plep/StirM5Model.java
index 71494eb..221ad8c 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/plep/StirM5Model.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/plep/StirM5Model.java
@@ -13,6 +13,7 @@
import static org.toxsoft.core.tslib.av.metainfo.IAvMetaConstants.*;
import org.toxsoft.core.tsgui.bricks.ctx.*;
+import org.toxsoft.core.tsgui.graphics.*;
import org.toxsoft.core.tsgui.m5.gui.mpc.impl.*;
import org.toxsoft.core.tsgui.m5.gui.panels.*;
import org.toxsoft.core.tsgui.m5.gui.panels.impl.*;
@@ -180,6 +181,7 @@ protected IAtomicValue doGetFieldValue( IStir aEntity ) {
TSID_NAME, STR_STIR_NUM_VISUMPLES, //
TSID_DESCRIPTION, STR_STIR_NUM_VISUMPLES_D, //
M5_OPDEF_FLAGS, avInt( M5FF_READ_ONLY | M5FF_COLUMN ), //
+ M5_OPDEF_COLUMN_ALIGN, avValobj( EHorAlignment.CENTER ), //
TSID_DEFAULT_VALUE, AV_0 //
) {
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/plep/messages_ka_GE.properties b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/plep/messages_ka_GE.properties
index 1ed2f33..37bf963 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/plep/messages_ka_GE.properties
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/plep/messages_ka_GE.properties
@@ -34,7 +34,7 @@ STR_SONG_NAME = სახელი
STR_SONG_NAME_D = სიმღერის სახელი
STR_STIR_DESCRIPTION = აღწერა
STR_STIR_DESCRIPTION_D = სვლის აღწერა
-STR_STIR_DURATION = ხანგრძლივობა
+STR_STIR_DURATION = დრო
STR_STIR_DURATION_D = სვლის ხანგრძლივობა წამებში
STR_STIR_NAME = სახელი
STR_STIR_NAME_D = სვლის სახელი
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/svin/SvinM5Model.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/svin/SvinM5Model.java
new file mode 100644
index 0000000..4e689fa
--- /dev/null
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/m5/svin/SvinM5Model.java
@@ -0,0 +1,75 @@
+package com.hazard157.prisex24.m5.svin;
+
+import static com.hazard157.prisex24.m5.IPsxM5Constants.*;
+import static org.toxsoft.core.tsgui.m5.IM5Constants.*;
+
+import org.toxsoft.core.tsgui.m5.model.*;
+import org.toxsoft.core.tsgui.m5.model.impl.*;
+
+import com.hazard157.common.quants.secint.*;
+import com.hazard157.prisex24.*;
+import com.hazard157.prisex24.m5.std.*;
+import com.hazard157.psx.common.stuff.frame.*;
+import com.hazard157.psx.common.stuff.svin.*;
+import com.hazard157.psx.proj3.episodes.*;
+import com.hazard157.psx.proj3.episodes.story.*;
+
+/**
+ * M5-model of {@link Svin}.
+ *
+ * @author hazard157
+ */
+public class SvinM5Model
+ extends M5Model
+ implements IPsxGuiContextable {
+
+ /**
+ * Field {@link Svin#episodeId()}.
+ */
+ public static final M5FieldDef EPISODE_ID = new PsxM5EpisodeIdFieldDef<>();
+
+ /**
+ * Field {@link Svin#cameraId()}.
+ */
+ public static final M5FieldDef CAM_ID = new PsxM5CameraIdFieldDef<>();
+
+ /**
+ * Field {@link Svin#interval()}.
+ */
+ public static final M5FieldDef INTERVAL = new PsxM5IntervalFieldDef<>();
+
+ /**
+ * Field {@link Svin#frame()}.
+ */
+ public final IM5SingleLookupFieldDef FRAME = new PsxM5FrameFieldDef<>() {
+
+ @Override
+ protected void doInit() {
+ addFlags( M5FF_COLUMN );
+ }
+
+ protected IFrame doGetFieldValue( Svin aEntity ) {
+ IFrame frame = super.doGetFieldValue( aEntity );
+ if( frame == null || frame == IFrame.NONE ) {
+ IEpisode e = unitEpisodes().items().findByKey( aEntity.episodeId() );
+ if( e != null ) {
+ IScene bestScene = e.story().findBestSceneFor( aEntity.interval(), true );
+ if( bestScene != null ) {
+ frame = bestScene.frame();
+ }
+ }
+ }
+ return frame;
+ }
+
+ };
+
+ /**
+ * Constructor.
+ */
+ public SvinM5Model() {
+ super( MID_SVIN, Svin.class );
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/messages.properties b/com.hazard157.prisex24/src/com/hazard157/prisex24/messages.properties
index d5b2e0e..8aafbb4 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/messages.properties
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/messages.properties
@@ -21,7 +21,7 @@ STR_PB_PSX24_COMMON_D = Preferences common for all Prisex24 application
STR_PB_WELCOME = Welcome
STR_PB_WELCOME_D = Welcome perspective preferences
STR_WELCOME_IS_FORCE_STILL = Force still?
-STR_WELCOME_IS_FORCE_STILL_D = Force to show still frames even if episode frame is animated one
+STR_WELCOME_IS_FORCE_STILL_D = Force to show still frames even if image is animated one
STR_WELCOME_IS_LABEL_AS_YMD = Label as 'YYYY-MM_DD'
STR_WELCOME_IS_LABEL_AS_YMD_D = Show episode date as 'YYYY-MM_DD' rather than 'DD mmm YYYY'
STR_WELCOME_IS_STARTUP_GIF = Startup GIF?
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/messages_ka_GE.properties b/com.hazard157.prisex24/src/com/hazard157/prisex24/messages_ka_GE.properties
index f58a000..791b164 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/messages_ka_GE.properties
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/messages_ka_GE.properties
@@ -21,7 +21,7 @@ STR_PB_PSX24_COMMON_D = საერთო პრეფერენც
STR_PB_WELCOME = გამარჯობა
STR_PB_WELCOME_D = მისალმების ეკრანი ეპიზოდების მინიატურებით
STR_WELCOME_IS_FORCE_STILL = აიძულე უძრავი?
-STR_WELCOME_IS_FORCE_STILL_D = აიძულე უძრავი კადრების ჩვენება მაშინაც კი, თუ ეპიზოდის კადრი არის ანიმაციური
+STR_WELCOME_IS_FORCE_STILL_D = აიძულე უძრავი კადრების ჩვენება მაშინაც კი, თუ სურათი არის ანიმაციური
STR_WELCOME_IS_LABEL_AS_YMD = ლეიბლი "წწწწ-თთ-დდ"
STR_WELCOME_IS_LABEL_AS_YMD_D = ეპიზოდის თარიღის ჩვენება, როგორც "წწწწ-თთ-დდ" და არა „დდ თთთ წწწწ“
STR_WELCOME_IS_STARTUP_GIF = მისალმების GIF?
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/messages_ru_RU.properties b/com.hazard157.prisex24/src/com/hazard157/prisex24/messages_ru_RU.properties
index ff8348e..c7a53ce 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/messages_ru_RU.properties
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/messages_ru_RU.properties
@@ -21,7 +21,7 @@ STR_PB_PSX24_COMMON_D = Настройки общие для всех ч
STR_PB_WELCOME = Приветствие
STR_PB_WELCOME_D = Приветственный экран с миниатюрами эпизодов
STR_WELCOME_IS_FORCE_STILL = Заставлять неподвижно?
-STR_WELCOME_IS_FORCE_STILL_D = Принудительно показывать неподвижные кадры, даже если кадр эпизода является анимированным.
+STR_WELCOME_IS_FORCE_STILL_D = Принудительно показывать неподвижные кадры, даже если изображение является анимированным.
STR_WELCOME_IS_LABEL_AS_YMD = Пометить как «ГГГГ-ММ-ДД»
STR_WELCOME_IS_LABEL_AS_YMD_D = Показывать дату выпуска в формате «ГГГГ-ММ ДД», а не «ДД ммм ГГГГ».
STR_WELCOME_IS_STARTUP_GIF = Стартовый GIF?
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/utils/GazeMediaFileVisualsProvider.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/utils/GazeMediaFileVisualsProvider.java
index 85529fb..0a4734f 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/utils/GazeMediaFileVisualsProvider.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/utils/GazeMediaFileVisualsProvider.java
@@ -15,16 +15,16 @@
import org.toxsoft.core.tslib.utils.errors.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.*;
/**
- * Gaze media as {@link OptedFile} visuals provider for {@link IPicsGridViewer}.
+ * Gaze media as {@link IOptedFile} visuals provider for {@link IPicsGridViewer}.
*
* @author hazard157
*/
public class GazeMediaFileVisualsProvider
- implements ITsVisualsProvider, IPsxGuiContextable {
+ implements ITsVisualsProvider, IPsxGuiContextable {
private final ITsGuiContext tsContext;
@@ -122,7 +122,7 @@ private TsImage getUnknwonThumb( EThumbSize aThumbSize ) {
//
@Override
- public TsImage getThumb( OptedFile aEntity, EThumbSize aThumbSize ) {
+ public TsImage getThumb( IOptedFile aEntity, EThumbSize aThumbSize ) {
File file = aEntity.file();
String ext = TsFileUtils.extractExtension( aEntity.file().getName() ).toLowerCase();
// image file
@@ -148,13 +148,13 @@ public TsImage getThumb( OptedFile aEntity, EThumbSize aThumbSize ) {
}
@Override
- public String getName( OptedFile aEntity ) {
+ public String getName( IOptedFile aEntity ) {
String bareName = TsFileUtils.extractBareFileName( aEntity.file().getName() );
return bareName;
}
@Override
- public String getDescription( OptedFile aEntity ) {
+ public String getDescription( IOptedFile aEntity ) {
return aEntity.file().getAbsolutePath();
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/utils/MingleMediaFileVisualsProvider.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/utils/MingleMediaFileVisualsProvider.java
index 3d4fb5b..02daf6b 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/utils/MingleMediaFileVisualsProvider.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/utils/MingleMediaFileVisualsProvider.java
@@ -15,16 +15,16 @@
import org.toxsoft.core.tslib.utils.errors.*;
import org.toxsoft.core.tslib.utils.files.*;
-import com.hazard157.common.incub.fs.*;
+import com.hazard157.common.incub.opfil.*;
import com.hazard157.prisex24.*;
/**
- * Mingle media as {@link OptedFile} visuals provider for {@link IPicsGridViewer}.
+ * Mingle media as {@link IOptedFile} visuals provider for {@link IPicsGridViewer}.
*
* @author hazard157
*/
public class MingleMediaFileVisualsProvider
- implements ITsVisualsProvider, IPsxGuiContextable {
+ implements ITsVisualsProvider, IPsxGuiContextable {
private final ITsGuiContext tsContext;
@@ -122,7 +122,7 @@ private TsImage getUnknwonThumb( EThumbSize aThumbSize ) {
//
@Override
- public TsImage getThumb( OptedFile aEntity, EThumbSize aThumbSize ) {
+ public TsImage getThumb( IOptedFile aEntity, EThumbSize aThumbSize ) {
File file = aEntity.file();
String ext = TsFileUtils.extractExtension( aEntity.file().getName() ).toLowerCase();
// image file
@@ -148,13 +148,13 @@ public TsImage getThumb( OptedFile aEntity, EThumbSize aThumbSize ) {
}
@Override
- public String getName( OptedFile aEntity ) {
+ public String getName( IOptedFile aEntity ) {
String bareName = TsFileUtils.extractBareFileName( aEntity.file().getName() );
return bareName;
}
@Override
- public String getDescription( OptedFile aEntity ) {
+ public String getDescription( IOptedFile aEntity ) {
return aEntity.file().getAbsolutePath();
}
diff --git a/com.hazard157.prisex24/src/com/hazard157/prisex24/valeds/frames/ValedAvValobjFrameEditor.java b/com.hazard157.prisex24/src/com/hazard157/prisex24/valeds/frames/ValedAvValobjFrameEditor.java
index ceb0ead..ab6d0a4 100644
--- a/com.hazard157.prisex24/src/com/hazard157/prisex24/valeds/frames/ValedAvValobjFrameEditor.java
+++ b/com.hazard157.prisex24/src/com/hazard157/prisex24/valeds/frames/ValedAvValobjFrameEditor.java
@@ -45,7 +45,7 @@ protected IValedControl doCreateEditor( ITsGuiContext aContext ) {
@Override
protected boolean isSuitableAvEditor( EAtomicType aAtomicType, String aKeeperId, ITsGuiContext aEditorContext ) {
if( aAtomicType == EAtomicType.VALOBJ && aKeeperId != null ) {
- return aKeeperId.equals( FrameKeeper.KEEPER_ID );
+ return aKeeperId.equals( Frame.KEEPER_ID );
}
return false;
}
diff --git a/com.hazard157.prisex30.pre/.classpath b/com.hazard157.prisex30.pre/.classpath
deleted file mode 100644
index 81fe078..0000000
--- a/com.hazard157.prisex30.pre/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/com.hazard157.prisex30.pre/.gitignore b/com.hazard157.prisex30.pre/.gitignore
deleted file mode 100644
index ae3c172..0000000
--- a/com.hazard157.prisex30.pre/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/bin/
diff --git a/com.hazard157.prisex30.pre/.project b/com.hazard157.prisex30.pre/.project
deleted file mode 100644
index 1d91f31..0000000
--- a/com.hazard157.prisex30.pre/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
- com.hazard157.prisex30.pre
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.pde.ManifestBuilder
-
-
-
-
- org.eclipse.pde.SchemaBuilder
-
-
-
-
-
- org.eclipse.pde.PluginNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/com.hazard157.prisex30.pre/.settings/org.eclipse.core.resources.prefs b/com.hazard157.prisex30.pre/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/com.hazard157.prisex30.pre/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/com.hazard157.prisex30.pre/.settings/org.eclipse.jdt.core.prefs b/com.hazard157.prisex30.pre/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 62ef348..0000000
--- a/com.hazard157.prisex30.pre/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,9 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
-org.eclipse.jdt.core.compiler.compliance=17
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
-org.eclipse.jdt.core.compiler.release=enabled
-org.eclipse.jdt.core.compiler.source=17
diff --git a/com.hazard157.prisex30.pre/META-INF/MANIFEST.MF b/com.hazard157.prisex30.pre/META-INF/MANIFEST.MF
deleted file mode 100644
index 32d18b5..0000000
--- a/com.hazard157.prisex30.pre/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,30 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Preliminary implementation of PRISEX v30 Aniversary 10th September edition
-Bundle-SymbolicName: com.hazard157.prisex30.pre
-Bundle-Version: 1.0.0.qualifier
-Export-Package: com.hazard157.prisex30.pre
-Bundle-Activator: com.hazard157.prisex30.pre.Activator
-Bundle-Vendor: HAZARD157
-Require-Bundle: javax.annotation,
- javax.inject,
- org.eclipse.core.runtime,
- org.eclipse.ui,
- org.eclipse.e4.core.contexts,
- org.eclipse.e4.core.di,
- org.eclipse.e4.ui.model.workbench,
- org.eclipse.e4.ui.workbench,
- org.eclipse.pde.ds.lib,
- org.toxsoft.core.tslib,
- org.toxsoft.core.txtproj.lib,
- org.toxsoft.core.txtproj.gui,
- org.toxsoft.core.txtproj.mws,
- org.toxsoft.core.singlesrc.rcp,
- org.toxsoft.core.tsgui.rcp,
- org.toxsoft.core.tsgui,
- org.toxsoft.core.tsgui.mws,
- com.hazard157.common,
- com.hazard157.porn.common
-Bundle-RequiredExecutionEnvironment: JavaSE-17
-Automatic-Module-Name: com.hazard157.prisex30.pre
-Bundle-ActivationPolicy: lazy
diff --git a/com.hazard157.prisex30.pre/build.properties b/com.hazard157.prisex30.pre/build.properties
deleted file mode 100644
index 34d2e4d..0000000
--- a/com.hazard157.prisex30.pre/build.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- .
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/Activator.java b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/Activator.java
deleted file mode 100644
index 4e608a0..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/Activator.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.hazard157.prisex30.pre;
-
-import static com.hazard157.prisex30.pre.IPrisex30CoreConstants.*;
-import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
-import static org.toxsoft.core.txtproj.mws.IUnitTxtprojMwsConstants.*;
-
-import java.io.*;
-
-import org.eclipse.osgi.service.environment.*;
-import org.toxsoft.core.tsgui.mws.bases.*;
-import org.toxsoft.core.tsgui.mws.osgi.*;
-import org.toxsoft.core.tslib.bricks.apprefs.impl.*;
-import org.toxsoft.core.tslib.utils.progargs.*;
-
-import com.hazard157.prisex30.pre.proj30.*;
-
-/**
- * The plugin activator.
- *
- * @author hazard157
- */
-public class Activator
- extends MwsActivator {
-
- /**
- * The plugin ID (for Java static imports).
- */
- public static final String PLUGIN_ID = "com.hazard157.prisex30.pre"; //$NON-NLS-1$
-
- /**
- * Command line argument with configuration file name.
- */
- public static final String CMDLINE_ARG_CFG_FILE_NAME = "config"; //$NON-NLS-1$
-
- /**
- * Default configuration file name (located in the startup directory).
- */
- public static final String DEFAULT_CFG_FILE_NAME = APP_ALIAS + ".cfg"; //$NON-NLS-1$
-
- private static Activator instance = null;
-
- /**
- * Constructor.
- */
- public Activator() {
- super( PLUGIN_ID );
- checkInstance( instance );
- instance = this;
- }
-
- @Override
- protected void doStart() {
- IMwsOsgiService mws = findOsgiService( IMwsOsgiService.class );
- mws.setAppInfo( APP_INFO );
- // configure TsProject plugin
- OPDEF_SHOW_CMD_IN_TOOLBAR.setValue( mws.context().params(), AV_TRUE );
- OPDEF_SHOW_CMD_IN_MENU.setValue( mws.context().params(), AV_TRUE );
- OPDEF_ALWAYS_USE_FILE_MENU.setValue( mws.context().params(), AV_TRUE );
- OPDEF_IMMEDIATE_LOAD_PROJ.setValue( mws.context().params(), AV_TRUE );
- OPDEF_PROJECT_FILE_FORMAT_INFO.setValue( mws.context().params(),
- avValobj( QuantPrisex30Project.PROJECT_FILE_FORMAT_INFO ) );
- // application preferences will be stored in the config file
- EnvironmentInfo envInfo = getOsgiService( EnvironmentInfo.class );
- ProgramArgs pa = new ProgramArgs( envInfo.getCommandLineArgs() );
- String cfgFileName = pa.getArgValue( CMDLINE_ARG_CFG_FILE_NAME, DEFAULT_CFG_FILE_NAME );
- File cfgFile = new File( cfgFileName );
- AbstractAppPreferencesStorage apStorage = new AppPreferencesConfigIniStorage( cfgFile );
- mws.context().put( AbstractAppPreferencesStorage.class, apStorage );
- }
-
- /**
- * Returns the reference to the activator singleton.
- *
- * @return {@link Activator} - the activator singleton
- */
- public static Activator getInstance() {
- return instance;
- }
-
-}
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPrisex30CoreConstants.java b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPrisex30CoreConstants.java
deleted file mode 100644
index 9071ede..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPrisex30CoreConstants.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package com.hazard157.prisex30.pre;
-
-import static com.hazard157.prisex30.pre.IPsxResources.*;
-import static org.toxsoft.core.tslib.av.EAtomicType.*;
-import static org.toxsoft.core.tslib.av.impl.AvUtils.*;
-import static org.toxsoft.core.tslib.av.metainfo.IAvMetaConstants.*;
-
-import java.time.*;
-
-import org.eclipse.e4.core.contexts.*;
-import org.toxsoft.core.tsgui.bricks.actions.*;
-import org.toxsoft.core.tsgui.graphics.icons.*;
-import org.toxsoft.core.tsgui.graphics.image.*;
-import org.toxsoft.core.tsgui.mws.appinf.*;
-import org.toxsoft.core.tslib.av.impl.*;
-import org.toxsoft.core.tslib.av.metainfo.*;
-import org.toxsoft.core.tslib.av.opset.impl.*;
-import org.toxsoft.core.tslib.bricks.apprefs.*;
-import org.toxsoft.core.tslib.bricks.strid.coll.*;
-import org.toxsoft.core.tslib.bricks.strid.coll.impl.*;
-import org.toxsoft.core.tslib.utils.*;
-
-/**
- * Application common constants.
- *
- * @author hazard157
- */
-@SuppressWarnings( "javadoc" )
-public interface IPrisex30CoreConstants {
-
- // ------------------------------------------------------------------------------------
- // Application info
-
- String APP_ID = "com.hazard157.prisex30"; //$NON-NLS-1$
- String APP_ALIAS = "prisex30"; //$NON-NLS-1$
- TsVersion APP_VERSION = new TsVersion( 30, 0, 2023, Month.SEPTEMBER, 10 );
-
- ITsApplicationInfo APP_INFO = new TsApplicationInfo( APP_ID, STR_APP_INFO, STR_APP_INFO_D, APP_ALIAS, APP_VERSION );
-
- // ------------------------------------------------------------------------------------
- // PRISEX30
-
- String PSX_ID = "psx30"; //$NON-NLS-1$
- String PSX_FULL_ID = "com.hazard157.prisex30"; //$NON-NLS-1$
- String PSX_M5_ID = PSX_ID + ".m5"; //$NON-NLS-1$
- String PSX_ACT_ID = PSX_ID + ".act"; //$NON-NLS-1$
-
- // ------------------------------------------------------------------------------------
- // E4
-
- String PERSPID_XXX = "com.hazard157.prisex30.persp.xxx"; //$NON-NLS-1$
- String PARTID_XXX = "com.hazard157.prisex30.part.xxx"; //$NON-NLS-1$
- String TOOLITEMID_XXX = "com.hazard157.prisex30.toolitem.xxx"; //$NON-NLS-1$
- String CMDID_XXX = "com.hazard157.prisex30.cmd.xxx"; //$NON-NLS-1$
-
- // ------------------------------------------------------------------------------------
- // Icons
-
- String PREFIX_OF_ICON_FIELD_NAME = "ICONID_"; //$NON-NLS-1$
- String ICONID_APP_ICON = "app-icon"; //$NON-NLS-1$
- String ICONID_PORNICON = "pornicon"; //$NON-NLS-1$
-
- // ------------------------------------------------------------------------------------
- // Actions
-
- String ACTID_XXX = PSX_ACT_ID + ".xxx"; //$NON-NLS-1$
-
- ITsActionDef ACDEF_XXX = TsActionDef.ofPush2( ACTID_XXX, //
- STR_APP_INFO, STR_APP_INFO_D, ICONID_APP_ICON );
-
- // ------------------------------------------------------------------------------------
- // Application preferences
-
- String PBID_PSX30_COMMON = APP_ID;
-
- IDataDef APPREF_XXX = DataDef.create( PSX_ID + "xxx", BOOLEAN, //$NON-NLS-1$
- TSID_DEFAULT_VALUE, AV_TRUE, //
- TSID_NAME, STR_APP_INFO, //
- TSID_DESCRIPTION, STR_APP_INFO_D //
- );
-
- IStridablesList ALL_APREFS = new StridablesList<>( //
- APPREF_XXX //
- );
-
- // ------------------------------------------------------------------------------------
- // Misc settings
-
- /**
- * Minimal frame thumb size, restricted due to prepared image files size.
- */
- EThumbSize PSX_MIN_FRAME_THUMB_SIZE = EThumbSize.SZ64;
-
- /**
- * Maximal frame thumb size, restricted due to prepared image files size.
- */
- EThumbSize PSX_MAX_FRAME_THUMB_SIZE = EThumbSize.SZ512;
-
- /**
- * Constants registration.
- *
- * @param aWinContext {@link IEclipseContext} - windows level context
- */
- static void init( IEclipseContext aWinContext ) {
- ITsIconManager iconManager = aWinContext.get( ITsIconManager.class );
- iconManager.registerStdIconByIds( Activator.PLUGIN_ID, IPrisex30CoreConstants.class, PREFIX_OF_ICON_FIELD_NAME );
- //
- IAppPreferences aprefs = aWinContext.get( IAppPreferences.class );
- IPrefBundle pb = aprefs.defineBundle( PBID_PSX30_COMMON, OptionSetUtils.createOpSet( //
- TSID_NAME, STR_APP_INFO, //
- TSID_DESCRIPTION, STR_APP_INFO_D, //
- TSID_ICON_ID, ICONID_APP_ICON //
- ) );
- for( IDataDef dd : ALL_APREFS ) {
- pb.defineOption( dd );
- }
- }
-
-}
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPsxGuiContextable.java b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPsxGuiContextable.java
deleted file mode 100644
index b6deace..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPsxGuiContextable.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.hazard157.prisex30.pre;
-
-import org.toxsoft.core.tsgui.bricks.ctx.*;
-
-import com.hazard157.common.*;
-
-/**
- * Extending {@link ITsGuiContextable} with PSX services.
- *
- * @author hazard157
- */
-public interface IPsxGuiContextable
- extends IHzGuiContextable {
-
- // nop
-
-}
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPsxResources.java b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPsxResources.java
deleted file mode 100644
index 7a7baf0..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/IPsxResources.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.hazard157.prisex30.pre;
-
-/**
- * Localizable resources.
- *
- * @author hazard157
- */
-interface IPsxResources {
-
- String STR_APP_INFO = Messages.getString( "STR_APP_INFO" ); //$NON-NLS-1$
- String STR_APP_INFO_D = Messages.getString( "STR_APP_INFO_D" ); //$NON-NLS-1$
-
- String STR_PB_PSX30_COMMON = Messages.getString( "STR_PB_PSX30_COMMON" ); //$NON-NLS-1$
- String STR_PB_PSX30_COMMON_D = Messages.getString( "STR_PB_PSX30_COMMON_D" ); //$NON-NLS-1$
-
-}
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/Messages.java b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/Messages.java
deleted file mode 100644
index 7dbad4e..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/Messages.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.hazard157.prisex30.pre;
-
-import java.util.*;
-
-@SuppressWarnings( "javadoc" )
-public class Messages {
-
- private static final String BUNDLE_NAME = Messages.class.getName().toLowerCase();
-
- private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME );
-
- private Messages() {
- }
-
- public static String getString( String key ) {
- try {
- return RESOURCE_BUNDLE.getString( key );
- }
- catch( @SuppressWarnings( "unused" ) MissingResourceException e ) {
- return '!' + key + '!';
- }
- }
-
-}
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages.properties b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages.properties
deleted file mode 100644
index 40c9dc4..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-STR_APP_INFO = Prisex v30
-STR_APP_INFO_D = Private sex application, version 30
-STR_PB_PSX30_COMMON = Prisex30 Common
-STR_PB_PSX30_COMMON_D = Preferences common for all Prisex30 application parts
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages_ka_GE.properties b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages_ka_GE.properties
deleted file mode 100644
index 743423f..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages_ka_GE.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-STR_APP_INFO = Prisex v30
-STR_APP_INFO_D = პირადი სექსის აპლიკაცია, ვერსია 30
-STR_PB_PSX30_COMMON = Prisex30 საერთო
-STR_PB_PSX30_COMMON_D = საერთო პრეფერენციები Prisex30 აპლიკაციის ყველა ნაწილისთვის
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages_ru_RU.properties b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages_ru_RU.properties
deleted file mode 100644
index 849960b..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/messages_ru_RU.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-STR_APP_INFO = Prisex v30
-STR_APP_INFO_D = Приложение приватного секса, версия 30
-STR_PB_PSX30_COMMON = Prisex30 Общие
-STR_PB_PSX30_COMMON_D = Настройки общие для всех частей приложения Prisex30
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/IPrisexProject30Constants.java b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/IPrisexProject30Constants.java
deleted file mode 100644
index 921c3b3..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/IPrisexProject30Constants.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.hazard157.prisex30.pre.proj30;
-
-import org.eclipse.e4.core.contexts.*;
-import org.toxsoft.core.tsgui.graphics.icons.*;
-
-import com.hazard157.prisex30.pre.*;
-
-/**
- * Plugin constants.
- *
- * @author hazard157
- */
-@SuppressWarnings( "javadoc" )
-public interface IPrisexProject30Constants {
-
- // ------------------------------------------------------------------------------------
- // icons
- //
-
- String PREFIX_OF_ICON_FIELD_NAME = "ICONID_"; //$NON-NLS-1$
- String ICONID_XXX = "xxx"; //$NON-NLS-1$
-
- /**
- * Constants registration.
- *
- * @param aWinContext {@link IEclipseContext} - windows level context
- */
- static void init( IEclipseContext aWinContext ) {
- ITsIconManager iconManager = aWinContext.get( ITsIconManager.class );
- iconManager.registerStdIconByIds( Activator.PLUGIN_ID, IPrisexProject30Constants.class, PREFIX_OF_ICON_FIELD_NAME );
- }
-
-}
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/QuantPrisex30Project.java b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/QuantPrisex30Project.java
deleted file mode 100644
index d9abaaf..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/QuantPrisex30Project.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.hazard157.prisex30.pre.proj30;
-
-import java.io.*;
-
-import org.eclipse.e4.core.contexts.*;
-import org.toxsoft.core.tsgui.bricks.quant.*;
-import org.toxsoft.core.tslib.av.opset.*;
-import org.toxsoft.core.tslib.utils.errors.*;
-import org.toxsoft.core.tslib.utils.logs.impl.*;
-import org.toxsoft.core.tslib.utils.progargs.*;
-import org.toxsoft.core.txtproj.lib.*;
-import org.toxsoft.core.txtproj.lib.bound.*;
-import org.toxsoft.core.txtproj.lib.impl.*;
-
-/**
- * PRISEX project quant.
- *
- * @author hazard157
- */
-@SuppressWarnings( "javadoc" )
-public class QuantPrisex30Project
- extends AbstractQuant {
-
- /**
- * Command line argument name for {@link ProgramArgs} to specify PSXv3 textual project file path.
- */
- public static final String CMDLINE_ARG_PROJECT_FILE_PATH = "project"; //$NON-NLS-1$
-
- private static final String DEFAULT_PROJ_FILE_PATH = "/home/hmade/data/projects/ver30/prisex30.txt"; //$NON-NLS-1$
- private static final String PROJ_FILE_APP_ID = "com.hazard157.prisex30"; //$NON-NLS-1$
- private static final int PROJ_FILE_FORMAT_VERSTION = 30;
-
- /**
- * Information about project file v30.
- */
- public static final TsProjectFileFormatInfo PROJECT_FILE_FORMAT_INFO =
- new TsProjectFileFormatInfo( PROJ_FILE_APP_ID, PROJ_FILE_FORMAT_VERSTION );
-
- public static final String UNITID_XXX = "Xxx"; //$NON-NLS-1$
-
- /**
- * Constructor.
- */
- public QuantPrisex30Project() {
- super( QuantPrisex30Project.class.getSimpleName() );
- }
-
- @Override
- protected void doInitApp( IEclipseContext aAppContext ) {
- ITsProject proj = aAppContext.get( ITsProject.class );
- if( proj == null ) {
- proj = new TsProject( PROJECT_FILE_FORMAT_INFO );
- aAppContext.set( ITsProject.class, proj );
- ITsProjectFileBound bound = new TsProjectFileBound( proj, IOptionSet.NULL );
- aAppContext.set( ITsProjectFileBound.class, bound );
- ProgramArgs programArgs = aAppContext.get( ProgramArgs.class );
- String path = programArgs.getArgValue( CMDLINE_ARG_PROJECT_FILE_PATH, DEFAULT_PROJ_FILE_PATH );
- File projectFile = new File( path );
- bound.open( projectFile );
- }
- initProject( aAppContext );
- ITsProjectFileBound bound = aAppContext.get( ITsProjectFileBound.class );
- if( bound.hasFileBound() ) {
- LoggerUtils.defaultLogger().info( "OK loading project %s", bound.getFile().getAbsolutePath() ); //$NON-NLS-1$
- }
- }
-
- /**
- * Fills project (references from context) and context with PDUs.
- *
- * @param aAppContext {@link IEclipseContext} - the application level context
- * @throws TsNullArgumentRtException любой аргумент = null
- */
- public static void initProject( IEclipseContext aAppContext ) {
- TsNullArgumentRtException.checkNull( aAppContext );
- ITsProject proj = aAppContext.get( ITsProject.class );
- TsInternalErrorRtException.checkNull( proj );
- //
- // IUnitXxx unitXxx = new UnitXxx();
- // proj.registerUnit( UNITID_XXX, unitXxx, true );
- // aAppContext.set( IUnitXxx.class, unitXxx );
- }
-
- @Override
- protected void doInitWin( IEclipseContext aWinContext ) {
- IPrisexProject30Constants.init( aWinContext );
- }
-
-}
diff --git a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/incs/IEpisode.java b/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/incs/IEpisode.java
deleted file mode 100644
index a64c782..0000000
--- a/com.hazard157.prisex30.pre/src/com/hazard157/prisex30/pre/proj30/incs/IEpisode.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package com.hazard157.prisex30.pre.proj30.incs;
-
-import org.toxsoft.core.tslib.coll.*;
-
-import com.hazard157.common.quants.secint.*;
-import com.hazard157.prisex30.pre.psx.*;
-import com.hazard157.psx.common.stuff.*;
-import com.hazard157.psx.common.stuff.frame.*;
-import com.hazard157.psx.common.stuff.svin.*;
-import com.hazard157.psx.common.utils.*;
-import com.hazard157.psx.proj3.episodes.proplines.*;
-import com.hazard157.psx.proj3.episodes.story.*;
-import com.hazard157.psx.proj3.incident.*;
-
-/**
- * Incident of type {@link EPsxIncidentKind#EPISODE }.
- *
- * @author hazard157
- */
-public interface IEpisode
- extends IPsxIncident, IEpisodeIdable, IFrameable {
-
- /**
- * Возвращает сюжет эпизода.
- *
- * @return {@link IStory} - сюжет эпизода
- */
- IStory story();
-
- /**
- * Возвращает заметки к эпизоду.
- *
- * @return {@link INoteLine} - заметки
- */
- INoteLine noteLine();
-
- /**
- * Возвращает длительность эпизода.
- *
- * @return int - длительность эпизода в секундах
- */
- int duration();
-
- /**
- * Возвращает теглайн - редактируемый набор пометок эпизода ярлыками.
- *
- * @return {@link ITagLine} - теглайн эпизода
- */
- ITagLine tagLine();
-
- /**
- * Возвращает планы съемки.
- *
- * @return {@link IMlPlaneGuide} - линия отметки планов
- */
- IMlPlaneGuide planesLine();
-
- /**
- * Возвращает иллюстрации к сюжету эпизода.
- *
- * Иллюстрациями служат кадры, иллюстрирующие сцены первого уровня (то есть, дети сюжета -
- * {@link IStory#childScenes()}), а в случае запроса детальных иллюстрации (Detailed = true
), кадры к
- * сценам, дочерным к дочкам сюжета.
- *
- * @param aDetailed boolean - выдать более детальные (больше) иллюстрации
- * @return {@link IList}<{@link IFrame}> - отсортированный список иллюстрации
- */
- IList