4141import org .eclipse .swt .custom .CLabel ;
4242import org .eclipse .swt .custom .ScrolledComposite ;
4343import org .eclipse .swt .custom .StyledText ;
44+ import org .eclipse .swt .events .FocusEvent ;
45+ import org .eclipse .swt .events .FocusListener ;
4446import org .eclipse .swt .events .SelectionAdapter ;
4547import org .eclipse .swt .events .SelectionEvent ;
4648import org .eclipse .swt .events .SelectionListener ;
4749import org .eclipse .swt .graphics .Color ;
4850import org .eclipse .swt .graphics .Font ;
4951import org .eclipse .swt .graphics .FontData ;
5052import org .eclipse .swt .graphics .Image ;
53+ import org .eclipse .swt .graphics .Point ;
5154import org .eclipse .swt .graphics .RGB ;
5255import org .eclipse .swt .layout .FillLayout ;
5356import org .eclipse .swt .layout .GridData ;
7376import org .eclipse .ui .dialogs .PreferencesUtil ;
7477import org .eclipse .ui .ide .IDE ;
7578import org .eclipse .ui .part .ViewPart ;
79+ import org .eclipse .ui .statushandlers .StatusManager ;
7680import org .osgi .service .event .EventHandler ;
7781
7882import com .checkmarx .ast .codebashing .CodeBashing ;
@@ -115,6 +119,7 @@ public class CheckmarxView extends ViewPart implements EventHandler {
115119 private static final String NO_PROJECTS_AVAILABLE = "No projects available." ;
116120 private static final String FORMATTED_SCAN_LABEL = "%s %s" ;
117121 private static final String FORMATTED_SCAN_LABEL_LATEST = "%s %s (%s)" ;
122+ private boolean isUpdatingCombo = false ;
118123
119124 private Timer debounceTimer = new Timer ("ProjectSearchDebounce" , true );
120125 private TimerTask pendingSearchTask ;
@@ -824,19 +829,28 @@ protected IStatus run(IProgressMonitor arg0) {
824829
825830 // Add ModifyListener to handle manual text input for projects
826831 projectComboViewer .getCombo ().addModifyListener (e -> {
832+ if (isUpdatingCombo ) return ;
827833 String enteredProject = projectComboViewer .getCombo ().getText ().trim ();
828834 // Skip search if the text is the default instruction
829- if (enteredProject .equals (PROJECT_COMBO_VIEWER_TEXT )) {
835+ if (enteredProject .equals (PROJECT_COMBO_VIEWER_TEXT ) || enteredProject . equals ( LOADING_PROJECTS ) ) {
830836 updateStartScanButton (false ); // Disable scan button
831837 return ;
832838 }
839+ // If user starts typing again and list is empty, restore currentProjects
840+ if (projectComboViewer .getCombo ().getItemCount () == 0 && !currentProjects .isEmpty () && enteredProject .length ()>0 ) {
841+ isUpdatingCombo = true ;
842+ int caretPos = projectComboViewer .getCombo ().getCaretPosition ();
843+ projectComboViewer .setInput (currentProjects );
844+ PluginUtils .setTextForComboViewer (projectComboViewer , enteredProject );
845+ projectComboViewer .getCombo ().setSelection (new Point (caretPos , caretPos ));
846+ isUpdatingCombo = false ;
847+ }
833848
834849 latestProjectSearchTerm = enteredProject ; // Track the latest term
835850 List <String > matchedProjects ;
836851 matchedProjects = currentProjects .stream ().map (Project ::getName )
837852 .filter (name -> name != null && name .toLowerCase ().contains (enteredProject .toLowerCase ())).limit (100 )
838853 .collect (Collectors .toList ());
839-
840854 if (matchedProjects .isEmpty ()) {
841855 CxLogger .info ("Entered project is not exist in current projects list" );
842856 // Cancel any pending search
@@ -857,13 +871,21 @@ protected IStatus run(IProgressMonitor monitor) {
857871 searchedProjects = DataProvider .getInstance ().getProjects (searchTerm );
858872 Display .getDefault ().asyncExec (() -> {
859873 if (searchTerm .equals (latestProjectSearchTerm )) {
874+ isUpdatingCombo = true ;
860875 // Update UI in UI thread
861876 if (searchedProjects != null && !searchedProjects .isEmpty ()) {
862877 projectComboViewer .setInput (searchedProjects );
863878 currentProjects = searchedProjects ;
864879 } else {
880+ int caretPos = projectComboViewer .getCombo ().getCaretPosition ();
881+ projectComboViewer .setInput (Collections .emptyList ());
882+ PluginUtils .setTextForComboViewer (projectComboViewer , searchTerm );
883+ projectComboViewer .getCombo ().setSelection (new Point (caretPos , caretPos ));
865884 updateStartScanButton (false ); // Disable scan button
885+ isUpdatingCombo = false ;
886+ return ;
866887 }
888+ isUpdatingCombo = false ;
867889 }
868890 });
869891 } catch (Exception ex ) {
@@ -878,6 +900,8 @@ protected IStatus run(IProgressMonitor monitor) {
878900 debounceTimer .schedule (pendingSearchTask , DEBOUNCE_DELAY_MS );
879901 }
880902 });
903+
904+
881905 }
882906 /**
883907 * Update state variables and make plugin fields loading when project changes
@@ -2570,9 +2594,9 @@ private void clearAndRefreshPlugin() {
25702594
25712595 @ Override
25722596 protected IStatus run (IProgressMonitor arg0 ) {
2573- List < Project > projectList = getProjects ();
2597+ currentProjects = getProjects ();
25742598 sync .asyncExec (() -> {
2575- projectComboViewer .setInput (projectList );
2599+ projectComboViewer .setInput (currentProjects );
25762600 projectComboViewer .refresh ();
25772601 PluginUtils .setTextForComboViewer (projectComboViewer , PROJECT_COMBO_VIEWER_TEXT );
25782602 PluginUtils .enableComboViewer (projectComboViewer , true );
0 commit comments