Fixed major issues
[ede] / explorer / src / ExplorerWindow.ec
1 import "Explorer"
2 import "IconBag"
3 import "ToolBar"
4
5 enum ExplorerToolId
6 {
7    none,
8    newWindow, goBack, goForward, goUp, goHome,
9    browse,
10    panelTree, panelSearch,
11    addressBar,
12    refresh,
13    viewList, viewDetails, viewIcons, viewCards, viewShowcase, viewTree, viewCustom,
14    previewPictures
15 };
16
17 class ExplorerWindow : Window
18 {
19 #ifdef _DEBUG
20    text = "Ecere Explorer (Debug)";
21 #else
22    text = "Ecere Explorer";
23 #endif
24    background = activeBorder;
25    borderStyle = sizable;
26    hasMaximize = true;
27    hasMinimize = true;
28    hasClose = true;
29    hasMenuBar = true;
30    //tabCycle = true;
31    size = { 840, 480 };
32    minClientSize = { 600, 300 };
33    nativeDecorations = true;
34
35    /*
36    bool userMode;
37    bool clipboard;
38
39    int treeSplit;
40    int searchSplit;
41    
42    ExplorerToolId lastViewId;
43 */
44
45    menu = Menu { };
46    
47    Menu fileMenu { menu, "File", f };
48    Menu windowMenu { menu, "Window", w };
49       MenuItem itemNewWindow
50       {
51          windowMenu, "New Window", n;
52          
53          bool NotifySelect(MenuItem selection, Modifiers mods)
54          {
55             ExplorerWindow { }.Create();
56             return true;
57          }
58       };
59
60    IconBag<ExplorerToolId> iconBag
61    {
62       //window = guiApp.desktop;
63       window = this;
64       alphaBlend = true;
65       iconNames =
66       [
67          "<:ecere>emblems/unreadable.png",     /* none */
68
69          "<:ecere>actions/windowNew.png",            /* newWindow */
70          "<:ecere>actions/goPrevious.png",           /* goBack */
71          "<:ecere>actions/goNext.png",               /* goForward */
72          "<:ecere>actions/goUp.png",                 /* goUp */
73          "<:ecere>actions/goHome.png",               /* goHome */
74
75          ":browse.png",                                           /* browse */
76
77          ":panel-tree.png",                                       /* panelTree */
78          "<:ecere>actions/editFind.png",             /* panelSearch */
79
80          "<:ecere>emblems/unreadable.png",     /* addressBar */
81
82          "<:ecere>actions/viewRefresh.png",          /* refresh */
83
84          ":view-list.png",                                        /* viewList */
85          ":view-details.png",                                     /* viewDetails */
86          ":view-icons.png",                                       /* viewIcons */
87          ":view-cards.png",                                       /* viewCards */
88          ":view-showcase-right.png",                              /* viewShowcase */
89          ":panel-tree.png",                                       /* viewTree */
90          ":view-custom.png",                                      /* viewCustom */
91          
92          "<:ecere>mimeTypes/image.png"     /* previewPictures */
93       ];
94    };
95
96    Stacker stack
97    {
98       this;
99       gap = 0;
100       direction = vertical;
101       background = activeBorder;
102       //opacity = 1.0f;
103       
104       anchor = { left = 0, top = 0, right = 0, bottom = 0 };
105       //moveable = false;
106    };
107
108    ToolBar/*<ExplorerToolId>*/ toolBar
109    {
110       stack, this;
111       iconBag = iconBag;
112       size = { h = 32 };
113       //moveable = false;
114
115       void NotifyToolClick(ToolButton button)
116       {
117          ExplorerToolId id = (ExplorerToolId)button.id;
118          switch(id)
119          {
120             case none:
121                break;
122             case newWindow:
123                ExplorerWindow { }.Create();
124                break;
125             case goBack:
126             case goForward:
127                break;
128             case goHome:
129             {
130                char * home = getenv("HOME");
131                if(home && home[0] && FileExists(home).isDirectory)
132                   GoToLocation(home, false, false);
133                break;
134             }
135             case goUp:
136             {
137                char * path = view.path;
138                char * newPath = new char[strlen(path)+1];
139                StripLastDirectory(path, newPath);
140                if(!newPath[0])
141                {
142                   newPath[0] = '/';
143                   newPath[1] = 0;
144                }
145                GoToLocation(newPath, false, false);
146                delete newPath;
147                break;
148             }
149             case panelTree:
150                // TODO TOFIX : need to fix Stacker for this to work
151                tree.visible = button.checked;
152                split.visible = button.checked;
153                if(button.checked)
154                {
155                   split.rightPane = view;
156                   view.anchor = { top = 0, bottom = 0, right = 0 };
157                   tree.SelectLocation(view.path);
158                }
159                else
160                {
161                   split.rightPane = null;
162                   view.anchor = { left = 0, top = 0, bottom = 0, right = 0 };
163                }
164                //search.visible = !button.checked;
165                panels.size = { panels.size.w, panels.size.h }; // TOFIX : another Stacker fix needed
166                break;
167             case panelSearch:
168                // TODO TOFIX : need to fix Stacker for this to work
169                //search.visible = button.checked;
170                tree.visible = false; //!button.checked;
171                split.visible = false; //!button.checked;
172                if(button.checked)
173                {
174                   /*split.rightPane = view;
175                   view.anchor = { top = 0, bottom = 0, right = 0 };*/
176                   split.rightPane = null;
177                   view.anchor = { left = 0, top = 0, bottom = 0, right = 0 };
178
179                   SearchStart();
180                }
181                else
182                {
183                   split.rightPane = null;
184                   view.anchor = { left = 0, top = 0, bottom = 0, right = 0 };
185
186                   SearchStop();
187                   view.path = addressBar.path;
188                }
189                panels.size = { panels.size.w, panels.size.h }; // TOFIX : another Stacker fix needed
190                break;
191             case refresh:
192                if(tree.visible)
193                   tree.Refresh();
194                view.Refresh();
195                break;
196             case previewPictures:
197                view.previewPictures = button.checked;
198                view.Refresh();
199                break;
200             case viewList:
201             case viewDetails:
202             case viewIcons:
203             case viewCards:
204             case viewShowcase:
205                //SwitchViews(toolId);
206                view.treeBranches = false;
207                view.Refresh();
208                break;
209             case viewTree:
210                view.treeBranches = button.checked;
211                view.Refresh();
212                break;
213          }
214       }
215    };
216
217    Window s1 { toolBar, size = { w = 8 } };
218    ToolButton goBack { toolBar, this, id = ExplorerToolId::goBack };
219    Window s2 { toolBar, size = { w = 2 } };
220    ToolButton goForward { toolBar, this, id = ExplorerToolId::goForward };
221    Window s3 { toolBar, size = { w = 2 } };
222    ToolButton refresh { toolBar, this, id = ExplorerToolId::refresh };
223    Window s4 { toolBar, size = { w = 2 } };
224    ToolButton goHome { toolBar, this, id = ExplorerToolId::goHome };
225    Window s5 { toolBar, size = { w = 8 } };
226    PathBox addressBar
227    {
228       toolBar, this;
229       size = { 300, 23 }, id = ExplorerToolId::addressBar;
230       typeExpected = directory;
231
232       bool OnKeyDown(Key key, unichar ch)
233       {
234          if((SmartKey)key == enter)
235          {
236             // how to make enter effect a modification
237             // how to implement in PathBox
238          }
239          return true;
240       }
241
242       bool NotifyModified(PathBox pathBox)
243       {
244          GoToLocation(pathBox.path, false, false);
245          return true;
246       }
247    };
248    FlipStacker { toolBar, spring = previous };
249    Window s6 { toolBar, size = { w = 8 } };
250    ToolButton goUp { toolBar, this, id = ExplorerToolId::goUp };
251    Window s7 { toolBar, size = { w = 8 } };
252    GroupToggleToolButton selectedPanel;
253    GroupToggleToolButton panelTree   { toolBar, this, id = ExplorerToolId::panelTree, selected = &selectedPanel, checked = true };
254    GroupToggleToolButton panelSearch { toolBar, this, id = ExplorerToolId::panelSearch, selected = &selectedPanel };
255    selectedPanel = panelTree;
256    Window s8 { toolBar, size = { w = 8 } };
257    OptionToolButton selectedView;
258    OptionToolButton viewList     { toolBar, this, id = ExplorerToolId::viewList, selected = &selectedView, checked = true };
259    OptionToolButton viewDetails  { toolBar, this, id = ExplorerToolId::viewDetails, selected = &selectedView };
260    OptionToolButton viewIcons    { toolBar, this, id = ExplorerToolId::viewIcons, selected = &selectedView };
261    OptionToolButton viewTiles    { toolBar, this, id = ExplorerToolId::viewCards, selected = &selectedView };
262    OptionToolButton viewShowcase { toolBar, this, id = ExplorerToolId::viewShowcase, selected = &selectedView };
263    OptionToolButton viewTree     { toolBar, this, id = ExplorerToolId::viewTree, selected = &selectedView };
264    selectedView = viewList;
265    Window s9 { toolBar, size = { w = 8 } };
266    ToggleToolButton previewPictures { toolBar, this, id = ExplorerToolId::previewPictures };
267
268    Window s10 { toolBar, size = { w = 8 } };
269    ToolButton newWindow { toolBar, this, id = ExplorerToolId::newWindow };
270    Window s11 { toolBar, size = { w = 8 } };
271
272    /*void OnDestroy()
273    {
274       iconBag.window = null;
275       delete iconBag;
276    }*/
277
278    bool OnLoadGraphics()
279    {
280       iconBag.Load();
281       return true;
282    }
283
284    void OnUnloadGraphics()
285    {
286       iconBag.Unload();
287    }
288
289    Stacker panels
290    {
291       stack, this;
292       gap = 0;
293       direction = horizontal;
294       background = yellow;//activeBorder;
295       //opacity = 1.0f;
296
297       anchor.left = 0;
298       anchor.bottom = 0;
299       anchor.right = 0;
300    };
301
302    //FlipStacker flipStack { stack, spring = previous };
303
304    /*SearchPanel searchPanel
305    {
306       panels, this;
307    };*/
308
309    Window hack
310    {
311       panels, this;
312       anchor.top = 0;
313       anchor.bottom = 0;
314       anchor.right = 0;
315       borderStyle = deep;
316    };
317
318    /*Tree*/FileSystemBox tree//;
319    {
320       hack, this;
321       size = { w = 240 };
322       borderStyle = none;
323       visible = false;
324       /*anchor.top = 0;
325       anchor.bottom = 0;*/
326       anchor = { left = 0, top = 0, bottom = 0 };
327
328       treeBranches = true;
329       foldersOnly = true;
330       autoLoad = false;
331
332       bool NotifyNodeSelect(FileSystemBox box, FileSystemNode node)
333       {
334          char p[MAX_LOCATION];
335          node.GetPath(p);
336          GoToLocation(node.path, false, true);
337          return true;
338       }
339    };
340
341    PaneSplitter split
342    {
343       hack, this;
344       visible = false;
345       leftPane = tree;//, rightPane = view;
346       split = 300;
347    };
348
349    FileSystemBox view
350    {
351       hack, this;
352       borderStyle = none;
353       /*anchor.top = 0;
354       anchor.bottom = 0;
355       anchor.right = 0;*/
356       anchor = { left = 0, top = 0, bottom = 0, right = 0 };
357
358       locationBox = addressBar;
359       navigateFolders = true;
360       multiSelect = true;
361       autoLoad = false;
362
363       bool NotifyNodeOpen(FileSystemBox box, FileSystemNode node)
364       {
365          if(node.type.isFile)
366          {
367             char path[MAX_LOCATION];
368          #ifndef __WIN32__
369             char command[MAX_LOCATION];
370             node.GetPath(path);
371             /*_FileType t = node.type;
372             if(t == ewsFile || t == epjFile ||
373                   t == ecFile || t == ehFile ||
374                   t == cppFile || t == hppFile ||
375                   t == cFile || t == hFile ||
376                   t == textFile || t == webFile)*/
377                sprintf(command, "ide %s", path);
378             /*else
379                sprintf(command, "%s", path);*/
380             Execute(command);
381          #else
382             node.GetPath(path);
383             ShellOpen(path);
384          #endif
385          }
386          else if(node.type.isFolder && tree.visible)
387             tree.SelectLocation(node.path);
388          return true;
389       }
390    };
391
392    FileSystemSearch searchThread
393    {
394       owner = this, fsb = view/*, searchPanel = this*/;
395
396       bool Window::NotifyUpdateSearchLocation(FileSystemSearch search, char * location)
397       {
398          char text[2048];
399          sprintf(text, "Search Results (Searching %s)", location);
400          PrintLn(text); //view.results.text = text;
401          return true;
402       }
403    };
404
405    void SearchStart()
406    {
407       char text[2048];
408
409       searchThread.active = true;
410
411       searchThread.optionSubdirs = true; //options.subdirs.checked;
412       searchThread.optionTree = view.treeBranches; //(options.subdirs.checked && options.tree.checked);
413       searchThread.optionBrowser = false; //(options.subdirs.checked && options.browser.checked);
414       searchThread.optionNameMatchCase = false; //findName.optionMatchCase.checked;
415       searchThread.optionNameMatchWord = false; //findName.optionMatchWord.checked;
416       searchThread.optionContentMatchCase = false; //findTextContent.optionMatchCase.checked;
417       searchThread.optionContentMatchWord = false; //findTextContent.optionMatchWord.checked;
418
419       strcpy(searchThread.location, view.path/*location.GetText()*/);
420       strcpy(searchThread.nameSearch, ".txt"/*findName.GetText()*/);
421       strcpy(searchThread.contentSearch, ""/*findTextContent.GetText()*/);
422
423       //actions.startStop.text = "Stop Search";
424       //actions.clear.disabled = false;
425       //view.results.Clear();
426       //view.results.hasHeader = !searchThread.optionTree;
427       //view.results.treeBranches = searchThread.optionTree;
428       //view.browser.Clear();
429       //ToggleBrowserDisplay(searchThread.optionBrowser);
430
431       //view.browser.text = "Browser";
432       //sprintf(text, "Search Results (Searching %s)", location.GetText());
433       PrintLn("Search Results (Searching ", view.path, ")");
434       //view.results.text = text;
435
436       searchThread.Create();
437    }
438
439    bool SearchStop()
440    {
441       if(searchThread.active)
442       {
443          searchThread.terminate = true;
444          app.Unlock();
445             searchThread.Wait();
446          app.Lock();
447          return true;
448       }
449       return false;
450    }
451
452    /*ExplorerSearch search
453    {
454       deep, this;
455       visible = false;
456       tabCycle = true;
457       size = Size { 624, 268 };
458       anchor = Anchor { left = 0, top = 0, bottom = 0 };
459    };
460
461    ExplorerViewSearch results;*/
462
463    /*Window viewHolder
464    {
465       parent = deep, master = this;
466       tabCycle = true;
467       anchor = Anchor { top = 0, bottom = 0, right = 0 };
468    };*/
469
470    // Preview / Showcase
471    /*PreviewArea previewArea
472    {
473       panels, this;
474    };*/
475
476    //FlipStacker flipPanels { panels, spring = previous };
477
478    /*bool TreeNotifyBranchSelect(ExplorerTree tree, ExplorerFileBranch branch)
479    {
480       if(branch)
481       {
482          char path[MAX_LOCATION];
483          branch.GetPath(path);
484          toolBar.addressBar.contents = path;
485          view.Load(branch);
486       }
487       return true;
488    }*/
489    
490    /*bool ViewNotifyItemOpen(ExplorerView view, ExplorerFileItem item)
491    {
492       ExplorerFileBranch branch = tree.branch;
493       if(item && branch)
494       {
495          if(item.type.isFolderType)
496          {
497             ExplorerFileBranch child;
498             
499             if(!branch.loaded || !branch.childrenLoaded)
500                BranchLoad(branch, tree.tree);
501
502             for(child = branch.children.first; child; child = child.next)
503                if(!strcmp(child.name, item.name))
504                   break;
505             
506             if(child)
507             {
508                if(branch.row.collapsed)
509                   child.row.collapsed = true;
510                child.EnsureVisible(false);
511                tree.Select(child);
512             }
513          }
514          else
515          {
516             char path[MAX_LOCATION];
517             branch.GetPath(path);
518             PathCat(path, item.name);
519             ShellOpen(path);
520          }
521       }
522    }*/
523
524    /*void SwitchViews(ExplorerToolId viewId)
525    {
526       ExplorerFileBranch branch = tree.branch;
527       view.Destroy(0);
528       switch(viewId)
529       {
530          case viewList:     view = ExplorerViewList     { parent = viewHolder, master = this }; break;
531          case viewDetails:  view = ExplorerViewDetails  { parent = viewHolder, master = this }; break;
532          case viewIcons:    view = ExplorerViewIcons    { parent = viewHolder, master = this }; break;
533          case viewCards:    view = ExplorerViewCards    { parent = viewHolder, master = this }; break;
534          case viewShowcase: view = ExplorerViewShowcase { parent = viewHolder, master = this }; break;
535       }
536       view.tabCycle = true;
537       view.previewPictures = toolBar.previewPictures.checked;
538       view.anchor = Anchor { left = 0, top = 0, bottom = 0, right = 0 };
539       view.NotifyItemOpen = ViewNotifyItemOpen;
540       view.Create();
541       view.Load(branch);
542       lastViewId = viewId;
543    }*/
544
545    void GoToLocation(char * location, bool viewIsAtLocation, bool treeIsAtLocation)
546    {
547       if(!viewIsAtLocation)
548          view.path = location;
549       if(tree.visible && !treeIsAtLocation)
550          tree.SelectLocation(location);
551    }
552
553    /*void SearchLocation(char * location)
554    {
555       GoToLocation(location);
556       search.location.editBox.contents = location;
557    }*/
558
559    bool OnPostCreate()
560    {
561       //userMode = true;
562       addressBar.path = view.path;
563       tree.path = "/"; // this should be available as a parameter
564       return true;
565    }
566
567    /*ExplorerWindow()
568    {
569       userMode = false;
570
571       treeSplit = 300;
572       searchSplit = 200;
573
574       view = ExplorerViewList
575       {
576          parent = viewHolder, master = this;
577          tabCycle = true;
578          previewPictures = toolBar.previewPictures.checked;
579          anchor = Anchor { left = 0, top = 0, bottom = 0, right = 0 };
580          NotifyItemOpen = ViewNotifyItemOpen;
581       };
582       lastViewId = viewList;
583       
584       tree.Load();
585       view.Load(tree.root);
586    }*/
587
588    /*void InitTree()
589    {
590    }*/
591
592    /*void InitSearch()
593    {
594    }*/
595 }
596
597 //class TreeFileSystemBox : FileSystemBox { }