Back to index

texmacs  1.0.7.15
tm_data.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tm_data.cpp
00004 * DESCRIPTION: Buffer management for TeXmacs server
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "tm_data.hpp"
00013 #include "convert.hpp"
00014 #include "file.hpp"
00015 #include "web_files.hpp"
00016 #include "tm_link.hpp"
00017 #include "message.hpp"
00018 #include "dictionary.hpp"
00019 #include "new_document.hpp"
00020 
00021 url tm_init_buffer_file= url_none ();
00022 url my_init_buffer_file= url_none ();
00023 
00024 /******************************************************************************
00025 * Low level view routines
00026 ******************************************************************************/
00027 
00028 tm_view
00029 new_view (url name) {
00030   // cout << "Creating new view\n";
00031 
00032   tm_buffer buf= create_buffer (name);
00033   editor    ed = new_editor (get_server () -> get_server (), buf);
00034   tm_view   vw = tm_new<tm_view_rep> (buf, ed);
00035   buf->vws << vw;
00036   ed->set_data (buf->data);
00037 
00038   tm_view temp_vw= get_view (false);
00039   set_view (vw);
00040   if (is_none (tm_init_buffer_file))
00041     tm_init_buffer_file= "$TEXMACS_PATH/progs/init-buffer.scm";
00042   if (is_none (my_init_buffer_file))
00043     my_init_buffer_file= "$TEXMACS_HOME_PATH/progs/my-init-buffer.scm";
00044   if (exists (tm_init_buffer_file)) exec_file (tm_init_buffer_file);
00045   if (exists (my_init_buffer_file)) exec_file (my_init_buffer_file);
00046   set_view (temp_vw);
00047 
00048   // cout << "View created\n";
00049   return vw;
00050 }
00051 
00052 tm_view
00053 get_passive_view (tm_buffer buf) {
00054   int i;
00055   for (i=0; i<N(buf->vws); i++)
00056     if (buf->vws[i]->win == NULL)
00057       return buf->vws[i];
00058   return new_view (buf->buf->name);
00059 }
00060 
00061 void
00062 delete_view (tm_view vw) {
00063   tm_buffer buf= vw->buf;
00064   int i, j, n= N(buf->vws);
00065   for (i=0; i<n; i++)
00066     if (buf->vws[i] == vw) {
00067       array<tm_view> a (n-1);
00068       for (j=0; j<n-1; j++)
00069        if (j<i) a[j]= buf->vws[j];
00070        else a[j]= buf->vws[j+1];
00071       buf->vws= a;
00072     }
00073   // tm_delete (vw);
00074   // FIXME: causes very annoying segfault;
00075   // recently introduced during reorganization
00076 }
00077 
00078 void
00079 attach_view (tm_window win, tm_view vw) {
00080   // cout << "Attach view " << vw->buf->buf->name << "\n";
00081   vw->win= win;
00082   widget wid= win->wid;
00083   set_scrollable (wid, vw->ed);
00084   vw->ed->cvw= wid.rep;
00085   ASSERT (is_attached (wid), "widget should be attached");
00086   vw->ed->resume ();
00087   win->set_window_name (vw->buf->buf->abbr);
00088   win->set_window_url (is_none (vw->buf->buf->extra)? vw->buf->buf->name: vw->buf->buf->extra);
00089   // cout << "View attached\n";
00090 }
00091 
00092 void
00093 detach_view (tm_view vw) {
00094   // cout << "Detach view " << vw->buf->buf->name << "\n";
00095   tm_window win= vw->win;
00096   if (win == NULL) return;
00097   vw->win= NULL;
00098   widget wid= win->wid;
00099   ASSERT (is_attached (wid), "widget should be attached");
00100   vw->ed->suspend ();
00101   set_scrollable (wid, glue_widget ());
00102   win->set_window_name ("TeXmacs");
00103   win->set_window_url (url_none ());
00104   // cout << "View detached\n";
00105 }
00106 
00107 /******************************************************************************
00108 * Low level window routines
00109 ******************************************************************************/
00110 
00111 class kill_window_command_rep: public command_rep {
00112 public:
00113   inline kill_window_command_rep () {}
00114   inline void apply () { exec_delayed (scheme_cmd ("(safely-kill-window)")); }
00115   tm_ostream& print (tm_ostream& out) { return out << "kill window"; }
00116 };
00117 
00118 tm_window
00119 new_window (bool map_flag, tree geom) {
00120   int mask= 0;
00121   if (get_preference ("header") == "on") mask += 1;
00122   if (get_preference ("main icon bar") == "on") mask += 2;
00123   if (get_preference ("mode dependent icons") == "on") mask += 4;
00124   if (get_preference ("focus dependent icons") == "on") mask += 8;
00125   if (get_preference ("user provided icons") == "on") mask += 16;
00126   if (get_preference ("status bar") == "on") mask += 32;
00127   command quit= tm_new<kill_window_command_rep> ();
00128   tm_window win= tm_new<tm_window_rep> (texmacs_widget (mask, quit), geom);
00129   if (map_flag) win->map ();
00130   return win;
00131 }
00132 
00133 bool
00134 delete_view_from_window (tm_window win) {
00135   int i, j;
00136   for (i=0; i<N(bufs); i++) {
00137     tm_buffer buf= bufs[i];
00138     for (j=0; j<N(buf->vws); j++) {
00139       tm_view vw= buf->vws[j];
00140       if (vw->win == win) {
00141        detach_view (vw);
00142        delete_view (vw);
00143        return true;
00144       }
00145     }
00146   }
00147   return false;
00148 }
00149 
00150 void
00151 delete_window (tm_window win) {
00152   while (delete_view_from_window (win)) {}
00153   win->unmap ();
00154   destroy_window_widget (win->win);
00155   tm_delete (win);
00156 }
00157 
00158 /******************************************************************************
00159 * Other subroutines
00160 ******************************************************************************/
00161 
00162 void
00163 new_buffer_in_this_window (url name, tree doc) {
00164   int nr= find_buffer (name);
00165   if (nr != -1) switch_to_buffer (nr);
00166   else {
00167     (void) create_buffer (name, doc);
00168     switch_to_buffer (name);
00169   }
00170 }
00171 
00172 void
00173 new_buffer_in_new_window (url name, tree doc, tree geom) {
00174   tm_window win= new_window (true, geom);
00175   tm_buffer buf= create_buffer (name, doc);
00176   tm_view   vw = get_passive_view (buf);
00177   attach_view (win, vw);
00178   set_view (vw);
00179   buf->buf->last_visit= texmacs_time ();
00180 }
00181 
00182 /******************************************************************************
00183 * Exported routines
00184 ******************************************************************************/
00185 
00186 url
00187 open_window (tree geom) {
00188   int i=1;
00189   while (true) {
00190     url name= url_scratch ("no_name_", ".tm", i);
00191     int nr= find_buffer (name);
00192     if (nr == -1) {
00193       new_buffer_in_new_window (name, tree (DOCUMENT), geom);
00194       return name;
00195     }
00196     else i++;
00197   }
00198 }
00199 
00200 void
00201 clone_window () {
00202   tm_window win= new_window ();
00203   tm_buffer buf= get_buffer ();
00204   tm_view   vw = get_passive_view (buf);
00205   attach_view (win, vw);
00206   set_view (vw);
00207   buf->buf->last_visit= texmacs_time ();
00208 }
00209 
00210 void
00211 kill_window () {
00212   int i, j;
00213   tm_window win= get_window ();
00214   for (i=0; i<N(bufs); i++) {
00215     tm_buffer buf= bufs[i];
00216     for (j=0; j<N(buf->vws); j++) {
00217       tm_view vw= buf->vws[j];
00218       if ((vw->win != NULL) && (vw->win != win)) {
00219        set_view (vw);
00220         vw->buf->buf->last_visit= texmacs_time ();
00221        delete_window (win);
00222        return;
00223       }
00224     }
00225   }
00226   if (number_of_servers () == 0) get_server () -> quit ();
00227   else delete_window (win);
00228 }
00229 
00230 void
00231 kill_window_and_buffer () {
00232   if (N(bufs) <= 1) get_server () -> quit();
00233   int i;
00234   bool kill= true;
00235   tm_buffer buf= get_buffer();
00236   tm_window win= get_window ();
00237   for (i=0; i<N(buf->vws); i++) {
00238     tm_view old_vw= buf->vws[i];
00239     if (old_vw->win != win) kill= false;
00240   }
00241   kill_window ();
00242   if (kill) delete_buffer (buf);
00243 }
00244 
00245 /******************************************************************************
00246 * Projects
00247 ******************************************************************************/
00248 
00249 void
00250 project_attach (string prj_name) {
00251   int i;
00252   tm_buffer buf= get_buffer ();
00253   buf->data->project= prj_name;
00254   for (i=0; i<N(buf->vws); i++) {
00255     tm_view vw= buf->vws[i];
00256     vw->ed->notify_change (THE_DECORATIONS);
00257     vw->ed->require_save ();
00258   }
00259   if (prj_name == "") buf->prj= NULL;
00260   else {
00261     url full_name= head (buf->buf->name) * prj_name;
00262     buf->prj= load_passive_buffer (full_name);
00263   }
00264 }
00265 
00266 bool
00267 project_attached () {
00268   tm_buffer buf= get_buffer ();
00269   return buf->data->project != "";
00270 }
00271 
00272 url
00273 project_get () {
00274   tm_buffer buf= get_buffer ();
00275   if (buf->data->project == "") return url_none ();
00276   return buf->prj->buf->name;
00277 }
00278 
00279 /******************************************************************************
00280 * Window management
00281 ******************************************************************************/
00282 
00283 static int  last_window= 1;
00284 static path the_windows;
00285 
00286 int
00287 create_window_id () {
00288   the_windows= path (last_window, the_windows);
00289   return last_window++;
00290 }
00291 
00292 static path
00293 reset (path p, int i) {
00294   if (is_nil (p)) return p;
00295   else if (p->item == i) return p->next;
00296   else return path (p->item, reset (p->next, i));
00297 }
00298 
00299 void
00300 destroy_window_id (int i) {
00301   the_windows= reset (the_windows, i);
00302 }
00303 
00304 int
00305 window_current () {
00306   tm_window win= get_window ();
00307   return win->id;
00308 }
00309 
00310 path
00311 windows_list () {
00312   return the_windows;
00313 }
00314 
00315 path
00316 buffer_to_windows (url name) {
00317   path p;
00318   int nr= find_buffer (name);
00319   if (nr == -1) return path ();
00320   tm_buffer buf= bufs[nr];
00321   for (int i=0; i<N(buf->vws); i++)
00322     if (buf->vws[i]->win != NULL)
00323       p= path (buf->vws[i]->win->id, p);
00324   return p;
00325 }
00326 
00327 url
00328 window_to_buffer (int id) {
00329   for (int i=0; i<N(bufs); i++)
00330     for (int j=0; j<N(bufs[i]->vws); j++)
00331       if (bufs[i]->vws[j]->win != NULL)
00332        if (bufs[i]->vws[j]->win->id == id)
00333          return bufs[i]->buf->name;
00334   return url_none ();
00335 }
00336 
00337 tm_view
00338 window_find_view (int id) {
00339   for (int i=0; i<N(bufs); i++)
00340     for (int j=0; j<N(bufs[i]->vws); j++)
00341       if (bufs[i]->vws[j]->win != NULL)
00342        if (bufs[i]->vws[j]->win->id == id)
00343          return bufs[i]->vws[j];
00344   return NULL;
00345 }
00346 
00347 void
00348 window_set_buffer (int id, url name) {
00349   tm_view old_vw= window_find_view (id);
00350   if (old_vw == NULL || old_vw->buf->buf->name == name) return;
00351   tm_window win= old_vw->win;
00352   int nr= find_buffer (name);
00353   if (nr == -1) return;
00354   tm_buffer buf   = bufs[nr];
00355   tm_view   new_vw= get_passive_view (buf);
00356   detach_view (old_vw);
00357   attach_view (win, new_vw);
00358 }
00359 
00360 void
00361 window_focus (int id) {
00362   if (id == window_current ()) return;
00363   tm_view vw= window_find_view (id);
00364   if (vw == NULL) return;
00365   set_view (vw);
00366   vw->buf->buf->last_visit= texmacs_time ();
00367 }