* Moved most of the BBS View renderer code into its own file, in preparation for...
[citadel.git] / webcit / bbsview_renderer.c
1 #include "webcit.h"
2 #include "webserver.h"
3 #include "groupdav.h"
4
5
6 typedef struct _bbsview_stuct {
7         StrBuf *BBViewToolBar;
8         StrBuf *MessageDropdown;
9         long *displayed_msgs;
10         int a;
11 } bbsview_struct;
12
13 int bbsview_GetParamsGetServerCall(SharedMessageStatus *Stat, 
14                                    void **ViewSpecific, 
15                                    long oper, 
16                                    char *cmd, 
17                                    long len)
18 {
19         bbsview_struct *VS;
20
21         VS = (bbsview_struct*) malloc(sizeof(bbsview_struct));
22         memset(VS, 0, sizeof(bbsview_struct));
23         *ViewSpecific = (void*)VS;
24         Stat->defaultsortorder = 1;
25         Stat->startmsg = -1;
26         Stat->sortit = 1;
27         
28         rlid[oper].cmd(cmd, len);
29         
30         if (havebstr("maxmsgs"))
31                 Stat->maxmsgs = ibstr("maxmsgs");
32         if (Stat->maxmsgs == 0) Stat->maxmsgs = DEFAULT_MAXMSGS;
33         
34         if (havebstr("startmsg")) {
35                 Stat->startmsg = lbstr("startmsg");
36         }
37         if (lbstr("SortOrder") == 2) {
38                 Stat->reverse = 1;
39                 Stat->num_displayed = -DEFAULT_MAXMSGS;
40         }
41         else {
42                 Stat->reverse = 0;
43                 Stat->num_displayed = DEFAULT_MAXMSGS;
44         }
45
46         return 200;
47 }
48
49 /* startmsg is an index within the message list.
50  * starting_from is the Citadel message number to be supplied to a "MSGS GT" operation
51  */
52 long DrawMessageDropdown(StrBuf *Selector, long maxmsgs, long startmsg, int nMessages, long starting_from)
53 {
54         StrBuf *TmpBuf;
55         wcsession *WCC = WC;
56         void *vMsg;
57         int lo, hi;
58         long ret;
59         long hklen;
60         const char *key;
61         int nItems;
62         HashPos *At;
63         long vector[16];
64         WCTemplputParams SubTP;
65         int wantmore = 1;
66
67         memset(&SubTP, 0, sizeof(WCTemplputParams));
68         SubTP.Filter.ContextType = CTX_LONGVECTOR;
69         SubTP.Context = &vector;
70         TmpBuf = NewStrBufPlain(NULL, SIZ);
71         At = GetNewHashPos(WCC->summ, nMessages);
72         nItems = GetCount(WCC->summ);
73         ret = nMessages;
74         vector[0] = 7;
75         vector[2] = 1;
76         vector[1] = startmsg;
77         vector[3] = 0;
78         vector[7] = starting_from;
79
80         while (wantmore)
81         {
82         
83                 vector[3] = abs(nMessages);
84                 lo = GetHashPosCounter(WCC->summ, At);
85                 wantmore = GetNextHashPos(WCC->summ, At, &hklen, &key, &vMsg);
86                 if (!wantmore)
87                         break;
88                 if (nMessages > 0) {
89                         if (lo + nMessages >= nItems) {
90                                 hi = nItems - 1;
91                                 vector[3] = nItems - lo;
92                                 if (startmsg == lo) 
93                                         ret = vector[3];
94                         }
95                         else {
96                                 hi = lo + nMessages - 1;
97                         }
98                 } else {
99                         if (lo + nMessages < -1) {
100                                 hi = 0;
101                         }
102                         else {
103                                 if ((lo % abs(nMessages)) != 0) {
104                                         int offset = (lo % abs(nMessages) *
105                                                       (nMessages / abs(nMessages)));
106                                         hi = lo + offset;
107                                         vector[3] = abs(offset);
108                                         if (startmsg == lo)
109                                                  ret = offset;
110                                 }
111                                 else
112                                         hi = lo + nMessages;
113                         }
114                 }
115                 
116                 /*
117                  * Bump these because although we're thinking in zero base, the user
118                  * is a drooling idiot and is thinking in one base.
119                  */
120                 vector[4] = lo + 1;
121                 vector[5] = hi + 1;
122                 vector[6] = lo;
123                 FlushStrBuf(TmpBuf);
124                 dbg_print_longvector(vector);
125                 DoTemplate(HKEY("select_messageindex"), TmpBuf, &SubTP);
126                 StrBufAppendBuf(Selector, TmpBuf, 0);
127         }
128         vector[6] = 0;
129         FlushStrBuf(TmpBuf);
130         if (maxmsgs == 9999999) {
131                 vector[1] = 1;
132                 ret = maxmsgs;
133         }
134         else
135                 vector[1] = 0;          
136         vector[2] = 0;
137         dbg_print_longvector(vector);
138         DoTemplate(HKEY("select_messageindex_all"), TmpBuf, &SubTP);
139         StrBufAppendBuf(Selector, TmpBuf, 0);
140         FreeStrBuf(&TmpBuf);
141         DeleteHashPos(&At);
142         return ret;
143 }
144
145
146 int bbsview_PrintViewHeader(SharedMessageStatus *Stat, void **ViewSpecific)
147 {
148         bbsview_struct *VS;
149         WCTemplputParams SubTP;
150
151         VS = (bbsview_struct*)*ViewSpecific;
152
153         VS->BBViewToolBar = NewStrBufPlain(NULL, SIZ);
154         VS->MessageDropdown = NewStrBufPlain(NULL, SIZ);
155
156         /*** startmsg->maxmsgs = **/DrawMessageDropdown(VS->MessageDropdown, 
157                                                         Stat->maxmsgs, 
158                                                         Stat->startmsg,
159                                                         Stat->num_displayed, 
160                                                         Stat->lowest_found-1);
161         if (Stat->num_displayed < 0) {
162                 Stat->startmsg += Stat->maxmsgs;
163                 if (Stat->num_displayed != Stat->maxmsgs)                               
164                         Stat->maxmsgs = abs(Stat->maxmsgs) + 1;
165                 else
166                         Stat->maxmsgs = abs(Stat->maxmsgs);
167
168         }
169         if (Stat->nummsgs > 0) {
170                 memset(&SubTP, 0, sizeof(WCTemplputParams));
171                 SubTP.Filter.ContextType = CTX_STRBUF;
172                 SubTP.Context = VS->MessageDropdown;
173                 DoTemplate(HKEY("msg_listselector_top"), VS->BBViewToolBar, &SubTP);
174                 StrBufAppendBuf(WC->WBuf, VS->BBViewToolBar, 0);
175                 FlushStrBuf(VS->BBViewToolBar);
176         }
177         return 200;
178 }
179
180 int bbsview_LoadMsgFromServer(SharedMessageStatus *Stat, 
181                               void **ViewSpecific, 
182                               message_summary* Msg, 
183                               int is_new, 
184                               int i)
185 {
186         bbsview_struct *VS;
187
188         VS = (bbsview_struct*)*ViewSpecific;
189         if (VS->displayed_msgs == NULL) {
190                 VS->displayed_msgs = malloc(sizeof(long) *
191                                             ((Stat->maxmsgs < Stat->nummsgs) ? 
192                                              Stat->maxmsgs + 1 : 
193                                              Stat->nummsgs + 1));
194         }
195         if ((i >= Stat->startmsg) && (i < Stat->startmsg + Stat->maxmsgs)) {
196                 VS->displayed_msgs[Stat->num_displayed] = Msg->msgnum;
197                 Stat->num_displayed++;
198         }
199         return 200;
200 }
201
202
203 int bbsview_RenderView_or_Tail(SharedMessageStatus *Stat, 
204                                void **ViewSpecific, 
205                                long oper)
206 {
207         wcsession *WCC = WC;
208         bbsview_struct *VS;
209         WCTemplputParams SubTP;
210         const StrBuf *Mime;
211
212         VS = (bbsview_struct*)*ViewSpecific;
213         if (Stat->nummsgs == 0) {
214                 wc_printf("<div class=\"nomsgs\"><br><em>");
215                 switch (oper) {
216                 case readnew:
217                         wc_printf(_("No new messages."));
218                         break;
219                 case readold:
220                         wc_printf(_("No old messages."));
221                         break;
222                 default:
223                         wc_printf(_("No messages here."));
224                 }
225                 wc_printf("</em><br></div>\n");
226         }
227         else 
228         {
229                 if (VS->displayed_msgs != NULL) {
230                         /* if we do a split bbview in the future, begin messages div here */
231                         int a;/// todo  
232                         for (a=0; a < Stat->num_displayed; ++a) {
233                                 read_message(WCC->WBuf, HKEY("view_message"), VS->displayed_msgs[a], NULL, &Mime);
234                         }
235                         
236                         /* if we do a split bbview in the future, end messages div here */
237                         
238                         free(VS->displayed_msgs);
239                         VS->displayed_msgs = NULL;
240                 }
241                 memset(&SubTP, 0, sizeof(WCTemplputParams));
242                 SubTP.Filter.ContextType = CTX_STRBUF;
243                 SubTP.Context = VS->MessageDropdown;
244                 DoTemplate(HKEY("msg_listselector_bottom"), VS->BBViewToolBar, &SubTP);
245                 StrBufAppendBuf(WCC->WBuf, VS->BBViewToolBar, 0);
246         }
247         return 0;
248
249 }
250
251
252 int bbsview_Cleanup(void **ViewSpecific)
253 {
254         bbsview_struct *VS;
255
256         VS = (bbsview_struct*)*ViewSpecific;
257         wDumpContent(1);
258         FreeStrBuf(&VS->BBViewToolBar);
259         FreeStrBuf(&VS->MessageDropdown);
260         free(VS);
261         return 0;
262 }
263
264 void 
265 InitModule_BBSVIEWRENDERERS
266 (void)
267 {
268         RegisterReadLoopHandlerset(
269                 VIEW_BBS,
270                 bbsview_GetParamsGetServerCall,
271                 bbsview_PrintViewHeader,
272                 bbsview_LoadMsgFromServer,
273                 bbsview_RenderView_or_Tail,
274                 bbsview_Cleanup);
275 }