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