OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 80 | Rev 90 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 80 Rev 83
Line 19... Line 19...
19
import org.openconcerto.sql.model.SQLSelect;
19
import org.openconcerto.sql.model.SQLSelect;
20
import org.openconcerto.sql.model.SQLTable;
20
import org.openconcerto.sql.model.SQLTable;
21
import org.openconcerto.sql.model.SQLTableEvent;
21
import org.openconcerto.sql.model.SQLTableEvent;
22
import org.openconcerto.sql.model.SQLTableModifiedListener;
22
import org.openconcerto.sql.model.SQLTableModifiedListener;
23
import org.openconcerto.sql.request.ComboSQLRequest;
23
import org.openconcerto.sql.request.ComboSQLRequest;
-
 
24
import org.openconcerto.sql.request.ComboSQLRequest.KeepMode;
24
import org.openconcerto.sql.view.search.SearchSpec;
25
import org.openconcerto.sql.view.search.SearchSpec;
25
import org.openconcerto.sql.view.search.SearchSpecUtils;
26
import org.openconcerto.sql.view.search.SearchSpecUtils;
26
import org.openconcerto.ui.SwingThreadUtils;
27
import org.openconcerto.ui.SwingThreadUtils;
27
import org.openconcerto.ui.component.combo.Log;
28
import org.openconcerto.ui.component.combo.Log;
28
import org.openconcerto.utils.RTInterruptedException;
29
import org.openconcerto.utils.RTInterruptedException;
Line 31... Line 32...
31
import org.openconcerto.utils.checks.EmptyChangeSupport;
32
import org.openconcerto.utils.checks.EmptyChangeSupport;
32
import org.openconcerto.utils.checks.EmptyListener;
33
import org.openconcerto.utils.checks.EmptyListener;
33
import org.openconcerto.utils.checks.EmptyObj;
34
import org.openconcerto.utils.checks.EmptyObj;
34
import org.openconcerto.utils.checks.MutableValueObject;
35
import org.openconcerto.utils.checks.MutableValueObject;
35
import org.openconcerto.utils.model.DefaultIMutableListModel;
36
import org.openconcerto.utils.model.DefaultIMutableListModel;
-
 
37
import org.openconcerto.utils.model.ISearchable;
36
import org.openconcerto.utils.model.NewSelection;
38
import org.openconcerto.utils.model.NewSelection;
37
 
39
 
38
import java.beans.PropertyChangeEvent;
40
import java.beans.PropertyChangeEvent;
39
import java.beans.PropertyChangeListener;
41
import java.beans.PropertyChangeListener;
40
import java.beans.PropertyChangeSupport;
42
import java.beans.PropertyChangeSupport;
Line 56... Line 58...
56
 * can also be reloaded by calling {@link #fillCombo()}. It can be searched using
58
 * can also be reloaded by calling {@link #fillCombo()}. It can be searched using
57
 * {@link #search(SearchSpec)}. Like all Swing model, it ought too be manipulated in the EDT.
59
 * {@link #search(SearchSpec)}. Like all Swing model, it ought too be manipulated in the EDT.
58
 * 
60
 * 
59
 * @author Sylvain CUAZ
61
 * @author Sylvain CUAZ
60
 */
62
 */
61
public class IComboModel extends DefaultIMutableListModel<IComboSelectionItem> implements SQLTableModifiedListener, MutableValueObject<IComboSelectionItem>, EmptyObj {
63
public class IComboModel extends DefaultIMutableListModel<IComboSelectionItem> implements SQLTableModifiedListener, MutableValueObject<IComboSelectionItem>, EmptyObj, ISearchable {
62
 
64
 
63
    private final ComboSQLRequest req;
65
    private final ComboSQLRequest req;
64
 
66
 
65
    private boolean filledOnce = false;
67
    private boolean filledOnce = false;
66
    private ITransformer<List<IComboSelectionItem>, IComboSelectionItem> firstFillTransf = null;
68
    private ITransformer<List<IComboSelectionItem>, IComboSelectionItem> firstFillTransf = null;
67
    private boolean isADirtyDrityGirl = true;
69
    private boolean isADirtyDrityGirl = true;
68
    private boolean isOnScreen = false;
70
    private boolean isOnScreen = false;
69
    private boolean sleepAllowed = true;
71
    private boolean sleepAllowed = true;
-
 
72
    @GuardedBy("this")
-
 
73
    private int requestDelay = 50;
70
 
74
 
71
    // supports
75
    // supports
72
    private final EmptyChangeSupport emptySupp;
76
    private final EmptyChangeSupport emptySupp;
73
    private final PropertyChangeSupport propSupp;
77
    private final PropertyChangeSupport propSupp;
74
 
78
 
Line 190... Line 194...
190
 
194
 
191
        super.fireContentsChanged(source, index0, index1);
195
        super.fireContentsChanged(source, index0, index1);
192
    }
196
    }
193
 
197
 
194
    void setRunning(final boolean b) {
198
    void setRunning(final boolean b) {
-
 
199
        assert SwingUtilities.isEventDispatchThread();
195
        if (this.running != b) {
200
        if (this.running != b) {
196
            this.running = b;
201
            this.running = b;
197
            if (this.running) {
202
            if (this.running) {
198
                this.req.addTableListener(this);
203
                this.req.addTableListener(this);
199
                this.req.addWhereListener(this.filterListener);
204
                this.req.addWhereListener(this.filterListener);
Line 243... Line 248...
243
 
248
 
244
    public final boolean isSleepAllowed() {
249
    public final boolean isSleepAllowed() {
245
        return this.sleepAllowed;
250
        return this.sleepAllowed;
246
    }
251
    }
247
 
252
 
-
 
253
    public synchronized final int getRequestDelay() {
-
 
254
        return this.requestDelay;
-
 
255
    }
-
 
256
 
-
 
257
    /**
-
 
258
     * Set the delay before the request is executed. I.e. if two {@link #fillCombo()} are less than
-
 
259
     * <code>delay</code> apart the first one won't be executed.
-
 
260
     * 
-
 
261
     * @param delay the delay in milliseconds.
-
 
262
     */
-
 
263
    public synchronized final void setRequestDelay(final int delay) {
-
 
264
        this.requestDelay = delay;
-
 
265
    }
-
 
266
 
248
    /**
267
    /**
249
     * Reload this combo. This method is thread-safe.
268
     * Reload this combo. This method is thread-safe.
250
     */
269
     */
251
    public synchronized final void fillCombo() {
270
    public synchronized final void fillCombo() {
252
        this.fillCombo(null, true);
271
        this.fillCombo(null, true);
Line 293... Line 312...
293
            }
312
            }
294
            // add the runnable to an attribute since the worker we are creating might be canceled
313
            // add the runnable to an attribute since the worker we are creating might be canceled
295
            // and thus done() and r might never be called
314
            // and thus done() and r might never be called
296
            if (r != null)
315
            if (r != null)
297
                this.runnables.add(r);
316
                this.runnables.add(r);
-
 
317
            final int delay = this.getRequestDelay();
298
            // copy the current search, if it changes fillCombo() will be called
318
            // copy the current search, if it changes fillCombo() will be called
299
            final SearchSpec search = this.getSearch();
319
            final SearchSpec search = this.getSearch();
300
            // commencer l'update après, sinon modeToSelect == 0
320
            // commencer l'update après, sinon modeToSelect == 0
301
            final SwingWorker2<List<IComboSelectionItem>, Object> worker = new SwingWorker2<List<IComboSelectionItem>, Object>() {
321
            final SwingWorker2<List<IComboSelectionItem>, Object> worker = new SwingWorker2<List<IComboSelectionItem>, Object>() {
302
 
322
 
303
                @Override
323
                @Override
304
                protected List<IComboSelectionItem> doInBackground() throws InterruptedException {
324
                protected List<IComboSelectionItem> doInBackground() throws InterruptedException {
305
                    // attends 1 peu pour voir si on va pas être annulé
325
                    // attends 1 peu pour voir si on va pas être annulé
306
                    Thread.sleep(50);
326
                    Thread.sleep(delay);
307
                    return SearchSpecUtils.filter(IComboModel.this.req.getComboItems(readCache), search);
327
                    return SearchSpecUtils.filter(IComboModel.this.req.getComboItems(readCache), search);
308
                }
328
                }
309
 
329
 
310
                // Runs on the event-dispatching thread.
330
                // Runs on the event-dispatching thread.
311
                @Override
331
                @Override
Line 461... Line 481...
461
    public final IComboSelectionItem getValue() {
481
    public final IComboSelectionItem getValue() {
462
        if (!this.isUpdating())
482
        if (!this.isUpdating())
463
            return this.getSelectedValue();
483
            return this.getSelectedValue();
464
        else if (this.getWantedID() == SQLRow.NONEXISTANT_ID)
484
        else if (this.getWantedID() == SQLRow.NONEXISTANT_ID)
465
            return null;
485
            return null;
466
        else
486
        else if (this.getRequest().getKeepMode() == KeepMode.NONE)
467
            return new IComboSelectionItem(getWantedID(), null);
487
            return new IComboSelectionItem(getWantedID(), null);
-
 
488
        else
-
 
489
            // no point in passing an SQLRowValues as the graph would be limited to just this row
-
 
490
            return new IComboSelectionItem(new SQLRow(this.getForeignTable(), getWantedID()), null);
468
    }
491
    }
469
 
492
 
470
    /**
493
    /**
471
     * The currently selected item. I.e. the value before the last {@link #setValue(int)}) (possibly
494
     * The currently selected item. I.e. the value before the last {@link #setValue(int)}) (possibly
472
     * <code>null</code>) while {@link #isUpdating()}.
495
     * <code>null</code>) while {@link #isUpdating()}.
Line 596... Line 619...
596
                        error = " inexistante";
619
                        error = " inexistante";
597
                    else if (row.isArchived())
620
                    else if (row.isArchived())
598
                        error = " archivée";
621
                        error = " archivée";
599
                    else
622
                    else
600
                        error = " existe mais est non atteignable: " + row.findDistantArchived(2);
623
                        error = " existe mais est non atteignable: " + row.findDistantArchived(2);
601
                    newItem = new IComboSelectionItem(id, "ERREUR !!! " + row + error);
624
                    newItem = new IComboSelectionItem(row, "ERREUR !!! " + row + error);
602
                    newItem.setFlag(IComboSelectionItem.ERROR_FLAG);
625
                    newItem.setFlag(IComboSelectionItem.ERROR_FLAG);
603
                }
626
                }
604
                this.addItem(newItem);
627
                this.addItem(newItem);
605
                this.setSelectedItem(newItem);
628
                this.setSelectedItem(newItem);
606
            } else {
629
            } else {
Line 753... Line 776...
753
 
776
 
754
    public final boolean isUpdating() {
777
    public final boolean isUpdating() {
755
        assert SwingUtilities.isEventDispatchThread();
778
        assert SwingUtilities.isEventDispatchThread();
756
        return this.updating;
779
        return this.updating;
757
    }
780
    }
-
 
781
 
-
 
782
    @Override
-
 
783
    public boolean isSearchable() {
-
 
784
        return !this.getRequest().getSearchFields().isEmpty();
-
 
785
    }
-
 
786
 
-
 
787
    @Override
-
 
788
    public boolean setSearch(String s, Runnable r) {
-
 
789
        if (this.getRequest().setSearch(s)) {
-
 
790
            if (r != null) {
-
 
791
                synchronized (this) {
-
 
792
                    this.runnables.add(r);
-
 
793
                }
-
 
794
            }
-
 
795
            return true;
-
 
796
        } else {
-
 
797
            SwingUtilities.invokeLater(r);
-
 
798
            return false;
-
 
799
        }
-
 
800
    }
758
}
801
}