IncSet.c 6.23 KB
Newer Older
1
2
3
4
5
6
7
8
/*
htop - IncSet.c
(C) 2005-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/

#include "IncSet.h"
David Hunt's avatar
David Hunt committed
9
#include "StringUtils.h"
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "Panel.h"
#include "ListItem.h"
#include "CRT.h"
#include <string.h>
#include <stdlib.h>

/*{

#include "FunctionBar.h"
#include "Panel.h"
#include <stdbool.h>

#define INCMODE_MAX 40

typedef enum {
   INC_SEARCH = 0,
   INC_FILTER = 1
} IncType;

#define IncSet_filter(inc_) (inc_->filtering ? inc_->modes[INC_FILTER].buffer : NULL)

typedef struct IncMode_ {
Hisham Muhammad's avatar
Hisham Muhammad committed
32
   char buffer[INCMODE_MAX+1];
33
34
35
36
37
38
39
40
41
42
   int index;
   FunctionBar* bar;
   bool isFilter;
} IncMode;

typedef struct IncSet_ {
   IncMode modes[2];
   IncMode* active;
   FunctionBar* defaultBar;
   bool filtering;
Hisham's avatar
Hisham committed
43
   bool found;
44
45
46
47
48
49
50
51
52
53
54
} IncSet;

typedef const char* (*IncMode_GetPanelValue)(Panel*, int);

}*/

static void IncMode_reset(IncMode* mode) {
   mode->index = 0;
   mode->buffer[0] = 0;
}

Richard's avatar
Richard committed
55
56
static const char* const searchFunctions[] = {"Next  ", "Cancel ", " Search: ", NULL};
static const char* const searchKeys[] = {"F3", "Esc", "  "};
57
58
59
60
61
62
63
64
static int searchEvents[] = {KEY_F(3), 27, ERR};

static inline void IncMode_initSearch(IncMode* search) {
   memset(search, 0, sizeof(IncMode));
   search->bar = FunctionBar_new(searchFunctions, searchKeys, searchEvents);
   search->isFilter = false;
}

Richard's avatar
Richard committed
65
66
static const char* const filterFunctions[] = {"Done  ", "Clear ", " Filter: ", NULL};
static const char* const filterKeys[] = {"Enter", "Esc", "  "};
67
68
69
70
71
72
73
74
75
static int filterEvents[] = {13, 27, ERR};

static inline void IncMode_initFilter(IncMode* filter) {
   memset(filter, 0, sizeof(IncMode));
   filter->bar = FunctionBar_new(filterFunctions, filterKeys, filterEvents);
   filter->isFilter = true;
}

static inline void IncMode_done(IncMode* mode) {
76
   FunctionBar_delete(mode->bar);
77
78
79
}

IncSet* IncSet_new(FunctionBar* bar) {
Hisham's avatar
Hisham committed
80
   IncSet* this = xCalloc(1, sizeof(IncSet));
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
   IncMode_initSearch(&(this->modes[INC_SEARCH]));
   IncMode_initFilter(&(this->modes[INC_FILTER]));
   this->active = NULL;
   this->filtering = false;
   this->defaultBar = bar;
   return this;
}

void IncSet_delete(IncSet* this) {
   IncMode_done(&(this->modes[0]));
   IncMode_done(&(this->modes[1]));
   free(this);
}

static void updateWeakPanel(IncSet* this, Panel* panel, Vector* lines) {
   Object* selected = Panel_getSelected(panel);
   Panel_prune(panel);
   if (this->filtering) {
      int n = 0;
      const char* incFilter = this->modes[INC_FILTER].buffer;
      for (int i = 0; i < Vector_size(lines); i++) {
         ListItem* line = (ListItem*)Vector_get(lines, i);
         if (String_contains_i(line->value, incFilter)) {
            Panel_add(panel, (Object*)line);
            if (selected == (Object*)line) Panel_setSelected(panel, n);
            n++;
         }
      }
   } else {
      for (int i = 0; i < Vector_size(lines); i++) {
         Object* line = Vector_get(lines, i);
         Panel_add(panel, line);
         if (selected == line) Panel_setSelected(panel, i);
      }
   }
}

Hisham's avatar
Hisham committed
118
static bool search(IncMode* mode, Panel* panel, IncMode_GetPanelValue getPanelValue) {
119
120
121
122
123
124
125
126
127
128
129
130
131
   int size = Panel_size(panel);
   bool found = false;
   for (int i = 0; i < size; i++) {
      if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
         Panel_setSelected(panel, i);
         found = true;
         break;
      }
   }
   if (found)
      FunctionBar_draw(mode->bar, mode->buffer);
   else
      FunctionBar_drawAttr(mode->bar, mode->buffer, CRT_colors[FAILED_SEARCH]);
Hisham's avatar
Hisham committed
132
   return found;
133
134
135
136
137
138
139
}

bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue getPanelValue, Vector* lines) {
   if (ch == ERR)
      return true;
   IncMode* mode = this->active;
   int size = Panel_size(panel);
140
   bool filterChanged = false;
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
   bool doSearch = true;
   if (ch == KEY_F(3)) {
      if (size == 0) return true;
      int here = Panel_getSelectedIndex(panel);
      int i = here;
      for(;;) {
         i++;
         if (i == size) i = 0;
         if (i == here) break;
         if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
            Panel_setSelected(panel, i);
            break;
         }
      }
      doSearch = false;
Hisham's avatar
Hisham committed
156
157
158
159
160
161
162
163
164
   } else if (ch < 255 && isprint((char)ch)) {
      if (mode->index < INCMODE_MAX) {
         mode->buffer[mode->index] = ch;
         mode->index++;
         mode->buffer[mode->index] = 0;
         if (mode->isFilter) {
            filterChanged = true;
            if (mode->index == 1) this->filtering = true;
         }
165
      }
Hisham's avatar
Hisham committed
166
167
168
169
170
171
172
173
174
175
   } else if ((ch == KEY_BACKSPACE || ch == 127)) {
      if (mode->index > 0) {
         mode->index--;
         mode->buffer[mode->index] = 0;
         if (mode->isFilter) {
            filterChanged = true;
            if (mode->index == 0) {
               this->filtering = false;
               IncMode_reset(mode);
            }
176
         }
Hisham's avatar
Hisham committed
177
178
      } else {
         doSearch = false;
179
      }
180
181
   } else if (ch == KEY_RESIZE) {
     Panel_resize(panel, COLS, LINES-panel->y-1);
182
183
   } else {
      if (mode->isFilter) {
184
         filterChanged = true;
185
186
187
188
189
190
191
192
         if (ch == 27) {
            this->filtering = false;
            IncMode_reset(mode);
         }
      } else {
         IncMode_reset(mode);
      }
      this->active = NULL;
193
      Panel_setDefaultBar(panel);
194
195
196
197
      FunctionBar_draw(this->defaultBar, NULL);
      doSearch = false;
   }
   if (doSearch) {
Hisham's avatar
Hisham committed
198
      this->found = search(mode, panel, getPanelValue);
199
   }
200
   if (filterChanged && lines) {
201
202
      updateWeakPanel(this, panel, lines);
   }
203
   return filterChanged;
204
205
206
207
208
209
210
211
212
}

const char* IncSet_getListItemValue(Panel* panel, int i) {
   ListItem* l = (ListItem*) Panel_get(panel, i);
   if (l)
      return l->value;
   return "";
}

213
void IncSet_activate(IncSet* this, IncType type, Panel* panel) {
214
215
   this->active = &(this->modes[type]);
   FunctionBar_draw(this->active->bar, this->active->buffer);
216
   panel->currentBar = this->active->bar;
217
218
219
}

void IncSet_drawBar(IncSet* this) {
220
221
222
223
224
225
226
227
228
229
230
231
232
   if (this->active) {
      FunctionBar_draw(this->active->bar, this->active->buffer);
   } else {
      FunctionBar_draw(this->defaultBar, NULL);
   }
}

int IncSet_synthesizeEvent(IncSet* this, int x) {
   if (this->active) {
      return FunctionBar_synthesizeEvent(this->active->bar, x);
   } else {
      return FunctionBar_synthesizeEvent(this->defaultBar, x);
   }
233
}