1 /*
2   FXiTe - The Free eXtensIble Text Editor
3   Copyright (c) 2009-2012 Jeffrey Pohlmeyer <yetanothergeek@gmail.com>
4 
5   This program is free software; you can redistribute it and/or modify it
6   under the terms of the GNU General Public License version 3 as
7   published by the Free Software Foundation.
8 
9   This software is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13 
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18 
19 #include <fx.h>
20 #include <fxkeys.h>
21 
22 #include "scidoc_util.h"
23 #include "appwin_pub.h"
24 #include "compat.h"
25 #include "prefs.h"
26 #include "popmenu.h"
27 
28 #include "intl.h"
29 #include "outpane.h"
30 
31 
32 FXDEFMAP(OutputList) OutputListMap[]={
33   FXMAPFUNC(SEL_COMMAND,            0,                            OutputList::onUserInput),
34   FXMAPFUNC(SEL_DOUBLECLICKED,      0,                            OutputList::onUserInput),
35   FXMAPFUNC(SEL_KEYPRESS,           0,                            OutputList::onUserInput),
36   FXMAPFUNC(SEL_RIGHTBUTTONPRESS,   0,                            OutputList::onUserInput),
37   FXMAPFUNC(SEL_FOCUSIN,            0,                            OutputList::onUserInput),
38   FXMAPFUNC(SEL_COMMAND,            OutputList::ID_SELECT_ALL,    OutputList::onSelectPopCmd),
39   FXMAPFUNC(SEL_COMMAND,            OutputList::ID_COPY_SELECTED, OutputList::onSelectPopCmd),
40   FXMAPFUNC(SEL_IO_WRITE,           OutputList::ID_CMDIO,         OutputList::onCmdIO),
41   FXMAPFUNC(SEL_IO_EXCEPT,          OutputList::ID_CMDIO,         OutputList::onCmdIO),
42 
43 
44 };
45 
46 FXIMPLEMENT(OutputList,FXList,OutputListMap,ARRAYNUMBER(OutputListMap));
47 
48 
onUserInput(FXObject * o,FXSelector sel,void * p)49 long OutputList::onUserInput(FXObject*o, FXSelector sel, void*p)
50 {
51   FXEvent* ev=(FXEvent*)p;
52   switch (FXSELTYPE(sel)) {
53     case SEL_RIGHTBUTTONPRESS: {
54       if(!ev->moved){
55         FXMenuPane *outpop=new FXMenuPane(this);
56         new PopUpMnuCmd(outpop,_("Select &All"),NULL,this,ID_SELECT_ALL);
57         new PopUpMnuCmd(outpop,_("&Copy"),NULL,this,ID_COPY_SELECTED);
58         outpop->create();
59         outpop->popup(NULL,ev->root_x-4,ev->root_y-2);
60         outpop->grabKeyboard();
61         getApp()->runModalWhileShown(outpop);
62         delete outpop;
63       }
64       return 1;
65     }
66     case SEL_DOUBLECLICKED: { break; }
67     case SEL_KEYPRESS: {
68       FXint code=ev->code;
69       if ((code==KEY_Return)||(code==KEY_KP_Enter)) { break; } else {
70         if (code==KEY_Tab) {
71           killFocus();
72           SciDocUtils::SetFocus(TopWinPub::ControlDoc());
73           return 1;
74         } else {
75           if (ev->state&CONTROLMASK) {
76             switch (code) {
77               case KEY_a: { return handle(this,FXSEL(SEL_COMMAND,ID_SELECT_ALL),p); }
78               case KEY_c: { return handle(this,FXSEL(SEL_COMMAND,ID_COPY_SELECTED),p); }
79             }
80           }
81         }
82         return FXList::handle(o,sel,p);
83       }
84     }
85     case SEL_FOCUSIN: {
86       TopWinPub::ActiveWidget(id());
87       return FXList::handle(o,sel,p);
88     }
89     default: { return FXList::handle(o,sel,p); }
90   }
91   GoToError();
92   return 1;
93 }
94 
95 
96 
onCmdIO(FXObject * o,FXSelector sel,void * p)97 long OutputList::onCmdIO(FXObject*o, FXSelector sel, void*p)
98 {
99   fillItems(*((FXString*)p));
100   return 1;
101 }
102 
103 
104 
GoToError()105 void OutputList::GoToError()
106 {
107   FXint n=getCurrentItem();
108   if (n>=0) {
109     FXListItem*item=getItem(n);
110     if (item) {
111       FXString txt=item->getText();
112       if (!txt.empty()) {
113         ErrorPattern*pats=prefs->ErrorPatterns();
114         for (FXint i=0; i<prefs->ErrorPatternCount(); i++) {
115           FXint begs[4]={0,0,0,0};
116           FXint ends[4]={0,0,0,0};
117           FXRex rx(pats[i].pat, REX_CAPTURE);
118 #ifdef FOX_1_7_50_OR_NEWER
119           if (rx.search(txt,0,txt.length(),FXRex::Normal,begs,ends,3)>=0)
120 #else
121           if (rx.match(txt,begs,ends,REX_FORWARD,3))
122 #endif
123           {
124             FXString filename = txt.mid(begs[1],ends[1]-begs[1]);
125             FXString linenum =  txt.mid(begs[2],ends[2]-begs[2]);
126             if (FXStat::isFile(filename)) {
127               TopWinPub::OpenFile(filename.text(), linenum.text(),false,true);
128               break;
129             } else {
130               SciDoc*sci=TopWinPub::ControlDoc();
131               if (sci && (!SciDocUtils::Filename(sci).empty()) && (!FXPath::isAbsolute(filename))) {
132                 filename=FXPath::name(filename);
133                 filename.prepend(PATHSEP);
134                 filename.prepend(FXPath::directory(SciDocUtils::Filename(sci)));
135                 if (FXStat::isFile(filename)) {
136                   TopWinPub::OpenFile(filename.text(), linenum.text(),false,true);
137                   break;
138                 }
139               }
140             }
141           }
142         }
143       }
144     }
145   }
146 }
147 
148 
149 
Focus()150 bool OutputList::Focus()
151 {
152   static bool isfocused=false;
153   if (getNumItems()<=0) { return 1; }
154   isfocused=!isfocused;
155   if (!isfocused) {
156     killFocus();
157     SciDocUtils::SetFocus(TopWinPub::ControlDoc());
158     return false;
159   } else {
160     if (!prefs->ShowOutputPane) { TopWinPub::ShowOutputPane(true); }
161     SciDocUtils::KillFocus(TopWinPub::FocusedDoc());
162     setFocus();
163     if (getCurrentItem()<0) { setCurrentItem(0); }
164     if (!isItemSelected(getCurrentItem())) {
165       selectItem(getCurrentItem());
166     }
167     makeItemVisible(getCurrentItem());
168     return true;
169   }
170 }
171 
172 
173 
onSelectPopCmd(FXObject * o,FXSelector sel,void * p)174 long OutputList::onSelectPopCmd(FXObject*o, FXSelector sel, void*p)
175 {
176   FXint count=getNumItems();
177   if (count==0) { return 1; }
178   switch (FXSELID(sel))
179   {
180     case ID_SELECT_ALL: {
181       setAnchorItem(0);
182       selectItem(0);
183       extendSelection(count-1);
184       break;
185     }
186     case ID_COPY_SELECTED: {
187       FXint i;
188       FXString outclip="";
189       FXString newline="\n";
190       switch (prefs->DefaultFileFormat) {
191         case 0: { newline="\r\n"; break; }
192         case 1: { newline="\r";   break; }
193         case 2: { newline="\n";   break; }
194       }
195       for (i=0; i<count; i++) {
196         if (isItemSelected(i)) {
197           outclip.append(getItemText(i));
198           outclip.append(newline);
199         }
200       }
201       SciDocUtils::CopyText(TopWinPub::ControlDoc(),outclip);
202     }
203     default: { return 0; }
204   }
205   return 1;
206 }
207 
208 
209 
fillItems(const FXString & strings)210 FXint OutputList::fillItems(const FXString& strings)
211 {
212   FXString s=strings;
213   s.substitute('\t', ' ');
214   s.substitute('\r', ' ');
215   FXint rv=FXList::fillItems(s);
216   makeItemVisible(getNumItems()-1);
217   return rv;
218 }
219 
220 
221 
appendItem(const FXString & text)222 FXint OutputList::appendItem(const FXString& text)
223 {
224   FXint rv=FXList::appendItem(text);
225   makeItemVisible(getNumItems()-1);
226   return rv;
227 }
228 
229 
230 
SelectFirstError()231 void OutputList::SelectFirstError()
232 {
233   FXRex rx(_(": [Ee]rror: "));
234   for (FXint i=0; i<getNumItems(); i++) {
235     FXListItem *item=getItem(i);
236 #ifdef FOX_1_7_50_OR_NEWER
237     if (rx.search(item->getText(),0,item->getText().length())>=0) {
238 #else
239     if (rx.match(item->getText())) {
240 #endif
241       selectItem(i);
242       setCurrentItem(i);
243       makeItemVisible(i);
244       break;
245     }
246   }
247 }
248 
249 
250 
251 OutputList::OutputList(FXComposite*p,FXObject*tgt,FXSelector sel,FXuint opts,FXint x,FXint y,FXint w,FXint h):
252 FXList(new FXGroupBox(p,"",LAYOUT_SIDE_TOP|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK,0,0,0,0,0,0,0,0),tgt,sel,opts,x,y,w,h)
253 {
254   prefs=Settings::instance();
255 }
256 
257 
258 
259 OutputList::~OutputList()
260 {
261 
262 }
263 
264 
265 
266 void OutputList::show()
267 {
268   getParent()->show();
269 }
270 
271 
272 
273 void OutputList::hide()
274 {
275   getParent()->hide();
276 }
277 
278