surface.C

Go to the documentation of this file.
00001 /* Gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  * 
00005  * Copyright (C) 1999,2000,2001,2002,2003 Percy Zahl
00006  *
00007  * Authors: Percy Zahl <zahl@users.sf.net>
00008  * additional features: Andreas Klust <klust@users.sf.net>
00009  * WWW Home: http://gxsm.sf.net
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00024  */
00025 
00026 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 8 c-style: "K&R" -*- */
00027 
00028 #include <iostream>
00029 #include <fstream>
00030 
00031 #include <cstring>
00032 
00033 #include <dirent.h>
00034 #include <fnmatch.h>
00035 
00036 #include "surface.h"
00037 #include "xsmmasks.h"
00038 #include "glbvars.h"
00039 #include "action_id.h"
00040 
00041 #include "dataio.h"
00042 #include "app_profile.h"
00043 
00044 #include "epsfutils.h"
00045 
00046 //moved to pi
00047 //#include "xsm_mkicons.h"
00048 //#include "app_mkicons.h"
00049 
00050 #define SET_CHANNEL_SCAN_MODE(X, M) X = ((X) > 0 ? M : -M)
00051 
00052 Surface::Surface() : Xsm(){
00053         StopScanFlg= TRUE;
00054         ActiveScan = NULL;
00055 
00056         ScanList = NULL;
00057         ProfileList = NULL;
00058         DelProfileList = NULL;
00059 
00060         for(int i=0; i<MAX_CHANNELS; i++){
00061                 scan[i] = NULL; // noch keine Scan Objekte !
00062                 ChannelView[i] = ID_CH_V_GREY;
00063                 ChannelMode[i] = ID_CH_M_OFF;
00064                 ChannelScanMode[i] = ID_CH_M_OFF;
00065         }
00066         SetRedraw();
00067 }
00068 
00069 Surface::~Surface(){
00070         XSM_DEBUG (DBG_L2, "Surface Destructor");
00071         RemoveAllProfiles();
00072         for(int i=0; i<MAX_CHANNELS; i++)
00073                 if(scan[i]){
00074                         XSM_DEBUG (DBG_L2, "killing Scan " << i);
00075                         delete scan[i]; // Scan Obj.. löschen
00076                 }
00077 }
00078 
00079 void Surface::hide(){;}
00080 
00081 int Surface::draw(){ return 0; }
00082 
00083 void Surface::CleanupProfiles(){
00084         g_slist_foreach ((GSList*) DelProfileList, 
00085                          (GFunc) Surface::remove_profile, this);
00086         g_slist_free (DelProfileList);
00087         DelProfileList = NULL;
00088 }
00089 
00090 int Surface::AddProfile(gchar *filename){
00091         CleanupProfiles ();
00092         ProfileList = g_slist_prepend (ProfileList,
00093                                        new ProfileControl (filename, "ProfileFromFile"));
00094         return 0;
00095 }
00096 
00097 int Surface::AddProfile(ProfileControl *pc){
00098         CleanupProfiles ();
00099         ProfileList = g_slist_prepend (ProfileList, pc);
00100         return 0;
00101 }
00102 
00103 int Surface::RemoveProfile(ProfileControl *pc){
00104         ProfileList = g_slist_remove((GSList*) ProfileList, pc); 
00105         DelProfileList = g_slist_prepend(DelProfileList, pc);
00106         // add to "to Delete" List
00107         return 0;
00108 }
00109 
00110 void Surface::remove_profile(ProfileControl *pc, gpointer data){ delete pc; }
00111 
00112 void Surface::RemoveAllProfiles(){
00113         g_slist_foreach((GSList*) ProfileList, 
00114                         (GFunc) Surface::remove_profile, this);
00115         g_slist_free(ProfileList);
00116         ProfileList = NULL;
00117 }
00118 
00119 
00120 int Surface::SetView(int Channel, int choice){
00121         XSM_DEBUG (DBG_L2,  "SetView " << Channel << " " << choice );
00122         if(Channel < 0 || Channel >= MAX_CHANNELS) return 1;
00123         if(scan[Channel]){
00124                 if(ChannelView[Channel] != choice){
00125                         ChannelView[Channel] = scan[Channel]->SetView(choice);
00126                 }
00127                 gapp->channelselector->SetView(Channel, choice);
00128         }
00129         else
00130                 ChannelView[Channel] = choice;
00131         return 0;
00132 }
00133 
00134 void Surface::AutoDisplay(double hi, double lo){
00135         if (ActiveScan){
00136                 ActiveScan->AutoDisplay(hi, lo, xsmres.HiLoDelta);      
00137                 SetVM ();
00138                 gapp->spm_update_all ();
00139         }
00140 }
00141 
00142 int Surface::SetVM(int mode){
00143         //  XSM_DEBUG (DBG_L2, "Surface::SetVM m:" << mode << " rdf:" << redrawflg);
00144         if (mode)
00145                 data.display.ViewFlg = mode;
00146 
00147         if (ActiveScan && redrawflg)
00148                 ActiveScan->SetVM (data.display.ViewFlg, &data, xsmres.HiLoDelta);
00149         
00150         return 0;
00151 }
00152 
00153 int Surface::SetSDir(int Channel, int choice){
00154         if(Channel < 0 || Channel >= MAX_CHANNELS) return -1;
00155         if(abs(ChannelScanMode[Channel]) == ID_CH_M_OFF) return -1;
00156         switch(choice){
00157         case ID_CH_D_P:
00158                 ChannelScanMode[Channel] = abs(ChannelScanMode[Channel]);
00159                 break;
00160         case ID_CH_D_M:
00161                 ChannelScanMode[Channel] = -abs(ChannelScanMode[Channel]);
00162                 break;
00163         case ID_CH_D_2ND_P:
00164                 ChannelScanMode[Channel] = ID_CH_M_2ND_OFFSET + abs(ChannelScanMode[Channel]);
00165                 break;
00166         case ID_CH_D_2ND_M:
00167                 ChannelScanMode[Channel] = -ID_CH_M_2ND_OFFSET -abs(ChannelScanMode[Channel]);
00168                 break;
00169         }
00170         XSM_DEBUG (DBG_L2, "Surface::SetSDir: " << Channel << " " << choice << " ChScM: " << ChannelScanMode[Channel]);
00171 
00172         return 0;
00173 }
00174 
00175 int Surface::SetMode(int Channel, int choice, int force){
00176         int lastmode;
00177         XSM_DEBUG (DBG_L2, "Surface::SetMode: " << Channel << " " << choice);
00178         if (Channel == -1) Channel = ActiveChannel;
00179         if (Channel < 0 || Channel >= MAX_CHANNELS) return -1;
00180         lastmode=ChannelMode[Channel];
00181 
00182         switch (choice){
00183         case ID_CH_M_ACTIVE: 
00184                 XSM_DEBUG (DBG_L2, "Surface::SetMode: ACTIVE " << Channel);
00185                 ActivateChannel (Channel);
00186                 ChannelMode[Channel] = choice;
00187                 return 0;
00188         case ID_CH_M_ON: 
00189                 if (scan[Channel]){
00190                         if (ChannelMode[Channel] == ID_CH_M_ACTIVE)
00191                                 ActiveScan = NULL;
00192                         ChannelMode[Channel] = choice;
00193                 }
00194                 else{
00195                         gapp->channelselector->SetMode(Channel, ID_CH_M_OFF);
00196                         return 0;
00197                 }
00198                 gapp->channelselector->SetMode (Channel, ChannelMode[Channel]);
00199                 return 0;
00200         }
00201         XSM_DEBUG (DBG_L2, "Surface::SetMode: CH " << Channel << ":" << choice);
00202         ChannelMode[Channel] = choice;
00203         switch (choice){
00204         case ID_CH_M_OFF: 
00205                 if (scan[Channel]) //&& (!ScanInProgress())
00206                         if (! (scan[Channel]->get_refcount ())){
00207                                 if (force || XSM_SHOW_QUESTION(Q_KILL_SCAN, 0)){
00208                                         if (ActiveScan == scan[Channel]){
00209                                                 ActiveScan = NULL;
00210                                         }
00211                                         delete scan[Channel];
00212                                         scan[Channel] = NULL;
00213                                         SET_CHANNEL_SCAN_MODE(ChannelScanMode[Channel], choice);
00214                                 }else{ // Nicht löschen ...
00215                                         ChannelMode[Channel] = ID_CH_M_ON;
00216                                         SET_CHANNEL_SCAN_MODE(ChannelScanMode[Channel], ID_CH_M_ON);
00217                                 }
00218                         }
00219                 break;
00220         case ID_CH_M_X:
00221                 SET_CHANNEL_SCAN_MODE(ChannelScanMode[Channel], choice);
00222                 break;
00223         case ID_CH_M_MATH:
00224                 SET_CHANNEL_SCAN_MODE(ChannelScanMode[Channel], choice);
00225                 break;
00226         default:
00227                 if(choice > ID_CH_M_X){
00228                         SET_CHANNEL_SCAN_MODE(ChannelScanMode[Channel], choice);
00229                 }
00230                 else
00231                         XSM_DEBUG (DBG_L2, "Surface::SetMode: wrong Mode !");
00232                 break;
00233         }
00234         gapp->channelselector->SetMode(Channel, ChannelMode[Channel]);
00235         return 0;
00236 }
00237 
00238 Scan* Surface::NewScan(int vtype, int vflg, int ChNo, SCAN_DATA *vd){
00239 // ToDo: needs to be more flexible in future...
00240 
00241         if (!strncasecmp (xsmres.InstrumentType, "SPALEED",7))
00242                 return ( new SpaScan (vtype, vflg, ChNo, vd));  // data type is ZD_LONG
00243         else
00244                 return ( new TopoGraphicScan (vtype, vflg, ChNo, vd)); // data type is ZD_SHORT
00245 }
00246 
00247 int Surface::ActivateFreeChannel(){
00248         int Ch=0;
00249         // auto activate Channel or use active one
00250         if((Ch=FindChan(ID_CH_M_OFF)) < 0){
00251                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOFREECHAN,"View in new Channel",1);
00252                 return 1;
00253         }
00254         if(ActivateChannel(Ch))
00255                 return 1;
00256         return 0;
00257 }
00258 
00259 int Surface::ActivateChannel(int NewActiveChannel){
00260         int Ch;
00261         //  XSM_DEBUG (DBG_L2, "Surface::ActivateChannel #" << NewActiveChannel);
00262         ActiveChannel=NewActiveChannel;
00263         if(ActiveScan)
00264                 ActiveScan->draw(1,0);
00265         ActiveScan = NULL;
00266         // Falls ein Channel "aktiv", dann auf "on" stellen
00267         // es darf immer nur ein Channel aktiv sein !!!!
00268         if((Ch=FindChan(ID_CH_M_ACTIVE)) >= 0){
00269                 gapp->channelselector->SetMode(Ch, ID_CH_M_ON);
00270                 ChannelMode[Ch] = ID_CH_M_ON;
00271                 if((Ch=FindChan(ID_CH_M_ACTIVE)) >= 0)
00272                         XSM_DEBUG (DBG_L2, "zu viele Active Channels !!!!");
00273         }
00274         // Falls Scan[Chanel] ex., benutze Ihn !
00275         if(scan[ActiveChannel]){
00276                 ActiveScan = scan[ActiveChannel];
00277                 scan[ActiveChannel]->Activate();
00278                 gapp->channelselector->SetMode(ActiveChannel, ID_CH_M_ACTIVE);
00279                 ChannelMode[ActiveChannel] = ID_CH_M_ACTIVE;
00280                 ActiveScan->draw(1,0);
00281                 return 0;
00282         }
00283 
00284         // neuen Scan anlegen
00285         scan[ActiveChannel] = NewScan(ChannelView[ActiveChannel], data.display.ViewFlg, ActiveChannel, &data);
00286 
00287         // Fehler ?
00288         if(!scan[ActiveChannel]){
00289                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOMEM,"",1);
00290                 return 1;
00291         }
00292 
00293         // Set ActiveScan
00294         ActiveScan = scan[ActiveChannel];
00295         gapp->channelselector->SetMode(ActiveChannel, ID_CH_M_ACTIVE);
00296         ChannelMode[ActiveChannel] = ID_CH_M_ACTIVE;
00297         ActiveScan->draw();
00298 
00299         return 0;
00300 }
00301 
00302 // Service Fkt, suche Channel Nr. mit fid als ID
00303 int Surface::FindChan(int fid){
00304         int i;
00305         for(i=0; i<MAX_CHANNELS; i++){
00306                 if(ChannelMode[i] == fid){
00307                         //      XSM_DEBUG (DBG_L2, "Surface::FindChan ID=" << fid << " => Match #" << i);
00308                         return i;
00309                 }
00310                 else
00311                         if(fid != ID_CH_M_OFF && ChannelScanMode[i] == fid){
00312                                 //      XSM_DEBUG (DBG_L2, "Surface::FindChan ID=" << fid << " => Match #" << i);
00313                                 ChannelMode[i] = abs(fid);
00314                                 gapp->channelselector->SetMode(i, abs(fid));
00315                                 return i;
00316                         }
00317         }
00318 
00319         //  XSM_DEBUG (DBG_L2, "Surface::FindChan ID=" << fid << " No Match");
00320         return -1;
00321 }
00322 
00323 int Surface::load(const char *rname){
00324         int Ch;
00325         std::ifstream f;
00326         static gchar *path = NULL;
00327         gchar *cname = NULL;
00328         gchar *fname = NULL;
00329         gchar *ffname;
00330         
00331         XSM_DEBUG (DBG_L2, "load: " << rname);
00332         // default path from resources
00333         if(! path)
00334                 path = g_strdup(xsmres.DataPath);
00335 
00336         // File Dialog ?
00337         if(! rname){
00338                 ffname = gapp->file_dialog("NC/asc file to load",path, 
00339                                            "*.[na][cs]*", NULL, "normalload");
00340                 if (! ffname){
00341                         gapp->SetStatus("load aborted.");
00342                         return 1;
00343                 }
00344                 fname = g_strdup(ffname);
00345         }else{
00346                 if(!strrchr(rname, '/'))
00347                         fname = g_strconcat("./",rname,NULL);
00348                 else
00349                         fname = g_strdup(rname);
00350         }
00351         
00352         // check if type may be .asc (profile)
00353         if (strstr(fname, ".asc")){
00354                 int ret = AddProfile (fname);
00355                 g_free (fname);
00356                 return ret;
00357         }
00358 
00359         // check if something else (no NetCDF, HDF, DAT)
00360         if (!(  strstr(fname, ".nc") || strstr(fname, ".NC"))){
00361                 
00362                 int ret = gapp->xsm->gnuimport (fname) ;
00363                 g_free (fname);
00364                 return ret;
00365         }
00366         
00367         // check for valid name extension length
00368         if(strlen(fname) <= 3){
00369                 gapp->SetStatus(N_("invalid filename, load aborted."));
00370                 g_free (fname);
00371                 return 1;
00372         }
00373 
00374         // save path for next time...
00375         g_free(path);
00376         path = g_strndup(fname, strrchr(fname, '/')-fname);
00377         
00378         // auto activate Channel or use active one
00379         if(!ActiveScan){
00380                 if((Ch=FindChan(ID_CH_M_OFF)) < 0){
00381                         gapp->SetStatus (ERR_SORRY, ERR_NOFREECHAN);
00382                         XSM_SHOW_ALERT (ERR_SORRY, ERR_NOFREECHAN, fname, 1);
00383                         g_free (fname);
00384                         return 1;
00385                 }
00386                 if(ActivateChannel(Ch)){
00387                         gapp->SetStatus(N_("Load: Error activating channel"));
00388                         g_free (fname);
00389                         return 1;
00390                 }
00391         }
00392 
00393         // zipped ? unzip it to /tmp/... !
00394         // depends on the avaibility of gzip and bzip2 for *.gz and *.bz2
00395         // files respectively
00396         if(!strncasecmp(fname+strlen(fname)-3,".gz",3) || 
00397            !strncasecmp(fname+strlen(fname)-4,".bz2",4)){
00398                 FILE *cmd;
00399                 int fd;
00400                 gchar *cmdstr;
00401                 gapp->SetStatus(N_("Load: unpacking..."), strrchr(fname,'/'));
00402 #   define GXSMTMPDIRPREFIX "/tmp/GxsmUnzipdir"
00403                 char *gxsmtmpdir = g_strdup(GXSMTMPDIRPREFIX"_XXXXXX");
00404                 
00405                 if (!(fd=mkstemp(gxsmtmpdir))){
00406                         g_warning (N_("Could not generate temporary filename: %s\n"),
00407                                    g_strerror(errno));
00408                         XSM_DEBUG(DBG_L2, "ErrorTmpFn: " <<  g_strerror(errno) );
00409                 }
00410                 if(fd) close(fd);
00411                 cmd = popen("rm -rf " GXSMTMPDIRPREFIX "*", "w");
00412                 if(cmd)
00413                         pclose(cmd);
00414                 
00415                 
00416                 if ((mkdir(gxsmtmpdir, 0755) != 0)){
00417                         g_warning (N_("Could not generate temporary directory: %s\n"),
00418                                    g_strerror(errno));
00419                         XSM_DEBUG(DBG_L2, "Error: " <<  g_strerror(errno) );
00420                 }
00421                 
00422                 XSM_DEBUG(DBG_L2, "MkTmpdir: " << gxsmtmpdir );
00423                 XSM_DEBUG(DBG_L2, "FileName:" << fname );
00424                 
00425                 cmdstr = g_strconcat("cp ", fname, " ", gxsmtmpdir, 
00426                                      strrchr(fname, '/'), NULL);
00427                 cmd = popen(cmdstr, "w");
00428                 if(cmd)
00429                         pclose(cmd);
00430                 else{
00431                         gapp->SetStatus(N_("error executing"), cmdstr);
00432                         XSM_SHOW_ALERT(ERR_SORRY, ERR_CPTMP, fname,1);
00433                         g_free(fname);
00434                         g_free(gxsmtmpdir);
00435                         g_free(cmdstr);
00436                         return 0;
00437                 }
00438                 g_free(cmdstr);
00439                 
00440                 cname = g_strconcat(gxsmtmpdir, strrchr(fname,'/'), NULL);
00441                 if (!strncasecmp(fname+strlen(fname)-3,".gz",3))
00442                         cmdstr = g_strconcat("gunzip ", cname, NULL);
00443                 else
00444                         cmdstr = g_strconcat("bunzip2 ", cname, NULL);
00445                 g_free(fname);
00446                 fname = g_strndup(cname, strrchr(cname,'.')-cname);
00447                 
00448                 cmd = popen(cmdstr, "w");
00449                 gapp->SetStatus("sh", cmdstr);
00450                 g_free(cmdstr);
00451                 // gxsmtmpdir done.
00452                 g_free(gxsmtmpdir);
00453                 if(cmd)
00454                         pclose(cmd);
00455                 else{
00456                         gapp->SetStatus(N_("error while unzipping"));
00457                         XSM_SHOW_ALERT(ERR_SORRY, ERR_UNZIP, fname,1);
00458                         g_free(fname);
00459                         return 0;
00460                 }
00461         }
00462 
00463         ActiveScan->CpyDataSet(data);
00464         
00465         Dataio *Dio = NULL;
00466         
00467         if (!strncasecmp(fname+strlen(fname)-3,".nc",3))
00468                 Dio = new NetCDF(ActiveScan, fname); // NetCDF File
00469 
00470         if (Dio){
00471                 Dio->Read();
00472                 if(Dio->ioStatus())
00473                         XSM_SHOW_ALERT(ERR_SORRY, Dio->ioStatus(), fname,1);
00474         
00475                 delete Dio;
00476         }
00477         
00478         // fname done.
00479         g_free(fname);
00480         
00481         ActiveScan->GetDataSet(data);
00482 
00483         // refresh all Parameter and draw Scan
00484         gapp->spm_update_all();
00485         ActiveScan->draw();
00486 
00487         if (xsmres.LoadDelay>0){
00488                 clock_t t=clock()+xsmres.LoadDelay*CLOCKS_PER_SEC/10;
00489                 gapp->xsm->AutoDisplay();
00490                 do {
00491                         gapp->check_events();
00492                 } while(t < clock());
00493         }
00494         return 0; 
00495 }
00496 
00497 // Save Scan(s)
00498 // ========================================
00499 // autoon: TRUE   auto generate filename and save away
00500 //         FALSE  use Filedlg
00501 //         2      autogenerate filename and attach <autosave> to it
00502 //         At the end of a scan or a moviescan "2" is NOT used,
00503 //         the autosave extension is used only for backup-intermediate scans
00504 //         to easily distinguish between final saves and intermediate results.
00505 // rname:  NULL: auto or ask (default)
00506 //         !=0 : use it
00507 // chidx: -1: check all channels (default)
00508 //        >=0: save Channel chidx
00509 // forceOverwrite:  TRUE  = force overwrite
00510 //                  FALSE = ask before overwrite (default)
00511 int Surface::save(int autoon, char *rname, int chidx, int forceOverwrite){
00512         int si,i,ii;
00513         std::ofstream f;
00514         gchar *fname = NULL;
00515         gchar *defaultname = NULL;
00516         gchar *basename = NULL;
00517         gchar *ffname;
00518         static gchar *digits = NULL;
00519         static gchar *path = NULL;
00520         gchar *stype = NULL;
00521 #define CHMAX (1+2*PIDCHMAX+2*DAQCHMAX)
00522         int Ch[CHMAX];
00523 
00524         if(!path)
00525                 path = g_strdup(xsmres.DataPath);
00526 
00527         if(chidx >= 0){
00528                 for(si=0; si<CHMAX; si++) Ch[si] = -1;
00529                 Ch[0] = chidx;
00530         }
00531         else{
00532                 si=0;
00533 
00534                 // Active scan
00535                 Ch[si++] = FindChan(ID_CH_M_ACTIVE);
00536 
00537                 // Auto check for all dataaq scans to save
00538                 for(i=0; i<PIDCHMAX; ++i){
00539                         Ch[si++] = FindChan(xsmres.pidchno[i]);
00540                         Ch[si++] = FindChan(-xsmres.pidchno[i]);
00541                 }
00542     
00543                 for(i=0; i<DAQCHMAX; ++i){
00544                         Ch[si++] = FindChan(xsmres.daqchno[i]);
00545                         Ch[si++] = FindChan(-xsmres.daqchno[i]);
00546                 }
00547     
00548                 for(ii=si=0; si<CHMAX; si++) // prevent of saving a copy (active scan == XXX-Topo-Xp (etc.))!
00549                         if(Ch[0] == Ch[si]){ Ch[0] = -1; break; } // magic remove from list if already marked for saving!
00550     
00551                 for(ii=si=0; si<CHMAX; si++)
00552                         if(Ch[si] != -1){ ii++; break; }
00553     
00554                 if(!ii){
00555                         gapp->SetStatus(ERR_SORRY, ERR_NOACTIVESCAN);
00556                         XSM_SHOW_ALERT(ERR_SORRY, ERR_NOACTIVESCAN,HINT_ACTIVATESCAN,1);
00557                         return 1;
00558                 }
00559         }
00560 
00561         if (digits)
00562                 g_free (digits);
00563         digits = NULL;
00564 
00565         // Automatic file counter --> DIGITS string
00566         if( IS_FILENAME_CONVENTION_ALPHA ) {
00567                 int cbase = (int)'z'-(int)'a'+1;
00568                 int tmp = counter/cbase/cbase;
00569                 digits = g_strdup_printf ("%c%c%c",
00570                                           (char)('a'+ tmp % cbase), 
00571                                           (char)('a'+ ((counter - tmp*cbase*cbase) / cbase) % cbase), 
00572                                           (char)('a'+ counter % cbase ));
00573         } else if( IS_FILENAME_CONVENTION_DIGIT ){
00574                 digits = g_strdup_printf ("%03d",counter+1);
00575         } else {
00576                 for(si=0; si<CHMAX; si++) if(Ch[si] == -1) continue; else break;
00577                 struct tm *ts = localtime (&scan[Ch[si]]->data.s.tStart);
00578                 digits = g_strdup_printf ("%04d%02d%02d%02d%02d%02d", 
00579                                           1900+ts->tm_year, ts->tm_mon, ts->tm_mday, 
00580                                           ts->tm_hour, ts->tm_min, ts->tm_sec);
00581         }
00582 
00583         // if autosavemode, additional subcounter used, Automatic file counter --> DIGITS string
00584         if( autoon == 2 ){
00585                 gchar *suffix = NULL;
00586                 if( IS_FILENAME_CONVENTION_ALPHA) {
00587                         int cbase = (int)'z'-(int)'a'+1;
00588                         int tmp = subcounter/cbase/cbase;
00589                         suffix = g_strdup_printf ("_%c%c%c",
00590                                                   (char)('a'+ tmp % cbase), 
00591                                                   (char)('a'+ ((subcounter - tmp*cbase*cbase) / cbase) % cbase), 
00592                                                   (char)('a'+ subcounter % cbase ));
00593                 } else  suffix = g_strdup_printf ("_%03d", subcounter+1);
00594                 gchar *tmp=digits;
00595                 digits = g_strconcat (tmp, suffix, NULL);
00596                 g_free (tmp); g_free (suffix);
00597         }
00598   
00599         for(si=0; si<CHMAX; si++){
00600                 if(Ch[si] == -1) continue;
00601 
00602                 // Automatisch Namen erzeugen 
00603                 // Name := BASENAME [[ + DIGITS] + SCANTYPE] + "." + FILETYPEEXT
00604                 // 1. --> make basename, add counter if no name given
00605                 if(rname)
00606                         basename = g_strdup(rname);
00607                 else
00608                         basename = g_strconcat(data.ui.basename, digits, NULL);
00609 
00610                 // 2. --> add ScanTyp specifier, SCANTYPE := ChannelModeName + p|m
00611 
00612                 if(si > 0){ // ScanChannels ..., get Type
00613                         if (! strncmp (scan[Ch[si]]->data.ui.type, "not set", 7)){
00614                                 if (! strncmp (scan[Ch[si]]->data.ui.title, "title not set", 13))
00615                                         stype = g_strdup_printf ("ch%02d ", Ch[si]);
00616                                 else
00617                                         stype = g_strdup (scan[Ch[si]]->data.ui.title);
00618                         } else
00619                                 stype = g_strdup (scan[Ch[si]]->data.ui.type);
00620                         // convert type to a more regular filename
00621                         g_strdelimit (stype, "+",'p');
00622                         g_strdelimit (stype, "-",'m');
00623                         g_strdelimit (stype, " ",'-');
00624 
00625                         gchar *p = strchr (stype, ',');
00626                         if(p)
00627                                 *p=0;
00628                         defaultname = g_strdup_printf ("%s-%s",basename,stype);
00629                         if(p)
00630                                 *p = ',';
00631                         // stype done.
00632                         g_free(stype);
00633                 }
00634                 else // only acticve Channel, no special stuff
00635                         defaultname = g_strdup(basename);
00636                 // basename done.
00637                 g_free(basename);
00638 
00639                 int overwrite;
00640                 do{ // while some error...
00641                         // get and check filename fname
00642                         // File Dialog oder Automatik ?
00643                         if(autoon){ // attach path to autogenerated name...
00644                                 fname = g_strconcat(path, "/", defaultname, NULL);
00645 
00646                                 // attach additional .autosave to filename for intermediate saves.
00647                                 if( autoon == 2 ) // Autosaves need another name!
00648                                         fname = g_strconcat(path, "/", defaultname, ".autosave", NULL);
00649       
00650                         }else{ // or call filedialog
00651                                 ffname = gapp->file_dialog(N_("NC file to save"), path, 
00652                                                            "*.nc", defaultname, "normalsave");
00653                                 if(! ffname){ // cancel ??
00654                                         gapp->SetStatus(N_("Save aborted by user."));
00655                                         return 1;
00656                                 }
00657                                 fname = g_strdup(ffname);
00658                                 g_free(path);
00659                                 path  = g_strndup(fname, strrchr(fname, '/')-fname);
00660                         }
00661                         XSM_DEBUG (DBG_L2, "Save: Name is:<" << fname << ">");
00662                         XSM_DEBUG (DBG_L2, "Save: Path is:<" << path << ">");
00663                         // if no extension given, use default type from resources
00664                         if (strncasecmp(fname+strlen(fname)-3,".nc",3)){
00665                                 gchar *fnamebase = g_strdup(fname);
00666                                 g_free(fname);
00667                                 fname = g_strconcat(fnamebase, ".nc", NULL);
00668                                 // fnamebase done.
00669                                 g_free(fnamebase);
00670                         }
00671                         // defaultname done.
00672                         g_free(defaultname);
00673 
00674                         overwrite = GTK_RESPONSE_YES;
00675                         // check if file exists -- if so, ask user for action
00676                         f.open(fname, std::ios::in);
00677                         if(f.good()){
00678                                 f.close();
00679                                 // Check overwrite on save?
00680                                 if(forceOverwrite == FALSE){
00681                                         GtkWidget *dialog = gtk_message_dialog_new (NULL,
00682                                                                                     GTK_DIALOG_DESTROY_WITH_PARENT,
00683                                                                                     GTK_MESSAGE_WARNING,
00684                                                                                     GTK_BUTTONS_YES_NO,
00685                                                                                     N_("File '%s' exists, overwrite?"),
00686                                                                                     fname);
00687                                         overwrite = gtk_dialog_run (GTK_DIALOG (dialog));
00688                                         gtk_widget_destroy (dialog);
00689                                         if (overwrite != GTK_RESPONSE_YES){
00690                                                 gapp->SetStatus(N_("File exists, save aborted by user."));
00691                                                 return 1;
00692                                         }
00693                                 }else{
00694                                         XSM_DEBUG (DBG_L2, "forceOverwrite enabled: overwriting file!");
00695                                         gapp->SetStatus(N_("File overwrite forced by default."));
00696                                 }
00697                         }
00698                 }while (overwrite != GTK_RESPONSE_YES);
00699     
00700                 gapp->monitorcontrol->LogEvent("*Save", fname);
00701 
00702                 // save Parameter and Data
00703                 {
00704                         Dataio *Dio = NULL;
00705                         scan[Ch[si]]->CpyUserEntries(data);
00706                         //      scan[Ch[si]]->data.ui.SetBaseName(strrchr(fname,'/')+1);
00707       
00708                         if(!strncasecmp(fname+strlen(fname)-3,".nc",3))
00709                                 Dio = new NetCDF(scan[Ch[si]], fname);
00710 
00711                         if (Dio){
00712                                 Dio->Write();
00713                                 if(Dio->ioStatus()){
00714                                         gapp->SetStatus(N_("Error"), Dio->ioStatus());
00715                                         XSM_SHOW_ALERT(ERR_SORRY, Dio->ioStatus(), fname,1);
00716                                 }
00717                                 else{
00718                                         scan[Ch[si]]->Saved();
00719                                         gapp->SetStatus(N_("Saving done "), fname);
00720                                 }
00721 
00722                                 delete Dio;
00723                         } 
00724                         else
00725                                 gapp->SetStatus(N_("Error, not saved "), fname);
00726                 }
00727                 // fname done.
00728                 g_free(fname);
00729         }
00730         // Jetzt Zähler erhöhen !
00731         if( autoon != 2){
00732                 ++counter;
00733                 subcounter = 0;
00734         }
00735         else{
00736                 ++subcounter;
00737         }
00738 
00739         gapp->spm_update_all();
00740 
00741         return 0; 
00742 }
00743 
00744 int Surface::gnuimport(const char *rname){
00745         // auto activate Channel or use active one
00746         if(! GetActiveScan())
00747                 return 1;
00748         
00749         XSM_DEBUG(DBG_L2, "Checking file with Import Plugins!" );
00750         gchar *ret;
00751         gchar *nametocheck = g_strdup(rname);
00752         ret = nametocheck;
00753         gapp->SignalLoadFileEventToPlugins(&ret);
00754         XSM_DEBUG(DBG_L2, "Result: " << (ret==NULL? "MATCHING IMPORT PLUGIN FOUND":"unknown file type") );
00755         g_free (nametocheck);
00756 
00757         return ret==NULL?0:1;
00758 }
00759 
00760 int Surface::gnuexport(const char *rname){
00761 
00762         if(!ActiveScan){
00763                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOACTIVESCAN,HINT_ACTIVATESCAN,1);
00764                 return 1;
00765         }
00766         if(!ActiveScan->mem2d){
00767                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOACTIVESCAN,HINT_ACTIVATESCAN,1);
00768                 return 1;
00769         }
00770         
00771         XSM_DEBUG(DBG_L2, "Checking file with Export Plugins!" );
00772         gchar *ret;
00773         gchar *nametocheck = g_strdup(rname);
00774         ret = nametocheck;
00775         gapp->SignalSaveFileEventToPlugins(&ret);
00776         XSM_DEBUG(DBG_L2, "Result: " << (ret==NULL? "MATCHING EXPORT PLUGIN FOUND":"unknown file type") );
00777         g_free (nametocheck);
00778 
00779         return 0;
00780 }
00781 
00782 Scan* Surface::GetActiveScan(){
00783         int Ch;
00784         if (!ActiveScan){
00785                 if ((Ch=FindChan (ID_CH_M_OFF)) < 0){
00786                         XSM_SHOW_ALERT(ERR_SORRY, ERR_NOFREECHAN,"",1);
00787                         return NULL;
00788                 }
00789                 if (ActivateChannel (Ch)){
00790                         return NULL;
00791                 }
00792         }
00793         return ActiveScan;
00794 }
00795 
00796 // Directory File Selection Stuff
00797 // //  char select_mask[256];
00798 // //  int gxsm_select(const struct dirent *item){ return !fnmatch(select_mask, item->d_name, 0); }
00799 // //  
00800 // //MkIconsData::MkIconsData(gchar *InPath, gchar *OutPath, gchar *InMask, 
00801 // //                    gchar *Opt, gchar *IconName){
00802 // //  
00803 // //   pathname   = InPath   ? InPath   : g_strdup(".") ;
00804 // //   outputname = OutPath  ? OutPath  : g_strdup("/tmp/icons.ps") ;
00805 // //   name       = IconName ? IconName : g_strdup("icons.ps") ;
00806 // //   mask       = InMask   ? InMask   : g_strdup("*.nc") ;
00807 // //   options    = Opt      ? Opt      : g_strdup("--------") ;
00808 // //    
00809 // //   redres = 0;
00810 // //   nix = 4;
00811 // //}
00812 // //  
00813 //MkIconsData::~MkIconsData(){
00814 // //   g_free(pathname);
00815 // //   g_free(outputname);
00816 // //   g_free(name);
00817 // //   g_free(mask);
00818 // //   g_free(options);
00819 //}
00820 // //  
00821 // //  // Options: ...out of date...
00822 // //  // EReg:              
00823 // //  //0       [-Ee] do E-Regression, '-': keine 'E': 30% Rand, 'e': 5% Rand
00824 // //  //  HighRes 1200DPI:  
00825 // //  //1       [-h]  Hi Resolution, '-': RedRes=250, 'h': =700 Pixel in A4 Breite
00826 // //  //   AutoSkl
00827 // //  //2       [-a]  Auto Skaling to Min-Max, '-' use defaults, 'a': do skl
00828 // //  //    Lin1D
00829 // //  //3       [-l]  do LineRegression, '-': keine, 'l': do LinReg
00830 // //  //4     [-0123] eps=0.1, 0.05, 0.25, 0.3
00831 // //  // ----
00832 // //  // ehal
00833 // //  // E
00834 // //  // x
00835 // // void Surface::MkIcons(MkIconsData *mid){
00836 // //   struct dirent **namelist;
00837 // //   int n;
00838 // //   double hi0,lo0;
00839 // //   lo0=data.display.cpslow;
00840 // //   hi0=data.display.cpshigh;
00841 // //  
00842 // //   // auto activate Channel or use active one
00843 // //   if(!ActiveScan){
00844 // //           int Ch;
00845 // //           if((Ch=FindChan(ID_CH_M_OFF)) < 0){
00846 // //                   XSM_SHOW_ALERT(ERR_SORRY, ERR_NOFREECHAN,"for Mk Icons",1);
00847 // //                   return;
00848 // //           }
00849 // //           if(ActivateChannel(Ch))
00850 // //                   return;
00851 // //           ActiveScan->create();
00852 // //   }
00853 // //   ActiveScan->CpyDataSet(data);
00854 // //  
00855 // //   if(mid->nix && ActiveScan){
00856 // //           int redres;
00857 // //           const double dpifac=72.*6./300.; // 72.dpi grey bei 300dpi Auflösung und 6in nutzbarer Breite
00858 // //           // calulate needed resolution
00859 // //           switch(mid->options[MkIconOpt_Resolution]){
00860 // //           case '3': redres = (int)(300.*dpifac); break;
00861 // //           case '6': redres = (int)(600.*dpifac); break;
00862 // //           case 'C': redres = (int)(1200.*dpifac); break;
00863 // //           default:  redres = (int)(600.*dpifac); break;
00864 // //           }
00865 // //           redres /= mid->nix;
00866 // //           XSM_DEBUG (DBG_L2,  "N Icons in X: " << mid->nix << ", Reduce to Pixels less than " << redres );
00867 // //  
00868 // //           // setup selection mask for "gxsm_select()"
00869 // //           strcpy(select_mask, mid->mask);
00870 // //           n = scandir(mid->pathname, &namelist, gxsm_select, alphasort);
00871 // //           if (n < 0)
00872 // //                   perror("scandir");
00873 // //           else{
00874 // //                   Scan *Original=NULL, *Icon, *TmpSc, *HlpSc;
00875 // //                   char fname[256];
00876 // //  
00877 // //                   EpsfTools *epsf;
00878 // //                   if(IS_SPALEED_CTRL)
00879 // //                           epsf = new SPA_epsftools;
00880 // //                   else
00881 // //                           epsf = new SPM_epsftools;
00882 // //  
00883 // //                   epsf->SetPaperTyp (mid->options[MkIconOpt_Paper] == 'A' ? A4PAPER:LETTERPAPER);
00884 // //                   epsf->open(mid->outputname, TRUE);
00885 // //                   epsf->NIcons(mid->nix);
00886 // //                   while(n--){
00887 // //                           XSM_DEBUG(DBG_L2, "Loading " << namelist[n]->d_name );
00888 // //   
00889 // //                           // Load
00890 // //                           sprintf(fname,"%s/%s",mid->pathname,namelist[n]->d_name);
00891 // //                           XSM_DEBUG (DBG_L2, "Icon: " << namelist[n]->d_name);
00892 // //                           load(fname);
00893 // //   
00894 // //                           Original = ActiveScan;
00895 // //                           G_FREE_STRDUP_PRINTF(Original->data.ui.name, namelist[n]->d_name); // ohne Pfad !!
00896 // //   
00897 // //                           Icon = NewScan(0, data.display.ViewFlg, 0, &data);
00898 // //                           Icon->create();
00899 // //                           TmpSc = NewScan(0, data.display.ViewFlg, 0, &data);
00900 // //                           TmpSc->create();
00901 // //  
00902 // //                           // Copy all data
00903 // //                           Icon->CpyDataSet(Original->data);
00904 // //                           TmpSc->CpyDataSet(Original->data);
00905 // //  
00906 // //                           // scale down to lower than redres
00907 // //                           // [0] "Resolution"
00908 // //                           // ========================================
00909 // //                           if(CopyScan(Original, Icon))
00910 // //                                   XSM_SHOW_ALERT(ERR_MATH, "", "", 1);
00911 // //  
00912 // //                           XSM_DEBUG (DBG_L2,  "W00:" << "nx:" << Icon->data.s.nx << " GetNx:" << Icon->mem2d->GetNx() );
00913 // //  
00914 // //                           while(Icon->data.s.nx > redres && Icon->data.s.ny > redres){
00915 // //                                   // Excange Icon <=> TmpSc
00916 // //                                   HlpSc = Icon; Icon = TmpSc; TmpSc = HlpSc;
00917 // //                                   // TmpSc => Quench2 => Icon
00918 // //                                   if(TR_QuenchScan(TmpSc, Icon))
00919 // //                                           XSM_SHOW_ALERT(ERR_MATH, "", "", 1);
00920 // //                                   XSM_DEBUG (DBG_L2,  "WOK:" << "nx:" << Icon->data.s.nx << " GetNx:" << Icon->mem2d->GetNx() );
00921 // //                                   memcpy( &TmpSc->data, &Icon->data, sizeof(SCAN_DATA));
00922 // //                           }
00923 // //                           if(CopyScan(Icon, TmpSc))
00924 // //                                   XSM_SHOW_ALERT(ERR_MATH, "", "", 1);
00925 // //  
00926 // //                           XSM_DEBUG (DBG_L2,  "Icon :" << "nx:" << Icon->data.s.nx << " GetNx:" << Icon->mem2d->GetNx() );
00927 // //                           XSM_DEBUG (DBG_L2,  "TmpSc:" << "nx:" << TmpSc->data.s.nx << " GetNx:" << TmpSc->mem2d->GetNx() );
00928 // //   
00929 // //                           // do some more math...
00930 // //  
00931 // //                           // [1] "E Regression"
00932 // //                           // ========================================
00933 // //                           if(mid->options[MkIconOpt_EReg] != '-'){
00934 // //                                   double eps=0.1;
00935 // //                                   XSM_DEBUG (DBG_L2,  "doing E regress ..." );
00936 // //                                   // Excange Icon <=> TmpSc
00937 // //                                   HlpSc = Icon; Icon = TmpSc; TmpSc = HlpSc; 
00938 // //                                   // TmpSc => Quench2 => Icon
00939 // //                                   if(mid->options[MkIconOpt_EReg] == 'e') eps=0.05; 
00940 // //                                   if(mid->options[MkIconOpt_EReg] == 'E') eps=0.3; 
00941 // //                                   TmpSc->Pkt2d[0].x = (int)(eps*TmpSc->mem2d->GetNx());
00942 // //                                   TmpSc->Pkt2d[0].y = (int)(eps*TmpSc->mem2d->GetNy());
00943 // //                                   TmpSc->Pkt2d[1].x = (int)((1.-eps)*TmpSc->mem2d->GetNx());
00944 // //                                   TmpSc->Pkt2d[1].y = (int)((1.-eps)*TmpSc->mem2d->GetNy());
00945 // //                                   if(BgERegress(TmpSc, Icon))
00946 // //                                           XSM_SHOW_ALERT(ERR_MATH, "", "", 1);
00947 // //                                   XSM_DEBUG (DBG_L2,  "Ereg - Icon :" << "nx:" << Icon->data.s.nx << " GetNx:" << Icon->mem2d->GetNx() );
00948 // //                                   XSM_DEBUG (DBG_L2,  "Ereg - TmpSc:" << "nx:" << TmpSc->data.s.nx << " GetNx:" << TmpSc->mem2d->GetNx() );
00949 // //                           }
00950 // //                           // [2] "Line Regression"
00951 // //                           // ========================================
00952 // //                           if(mid->options[MkIconOpt_LReg] == 'l'){
00953 // //                                   XSM_DEBUG (DBG_L2,  "doing BgLin1D ..." );
00954 // //                                   // Excange Icon <=> TmpSc
00955 // //                                   HlpSc = Icon; Icon = TmpSc; TmpSc = HlpSc; 
00956 // //                                   // TmpSc => Quench2 => Icon
00957 // //                                   if(BgLin1DScan(TmpSc, Icon))
00958 // //                                           XSM_SHOW_ALERT(ERR_MATH, "", "", 1);
00959 // //                                   XSM_DEBUG (DBG_L2,  "BgLin1D - Icon :" << "nx:" << Icon->data.s.nx << " GetNx:" << Icon->mem2d->GetNx() );
00960 // //                                   XSM_DEBUG (DBG_L2,  "BgLin1D - TmpSc:" << "nx:" << TmpSc->data.s.nx << " GetNx:" << TmpSc->mem2d->GetNx() );
00961 // //                           }
00962 // //                           // [3] "View Mode" override: -qdlph
00963 // //                           // ========================================
00964 // //                           switch(mid->options[MkIconOpt_ViewMode]){
00965 // //                           case 'q': Icon->mem2d->SetDataPktMode (SCAN_V_QUICK); break;
00966 // //                           case 'd': Icon->mem2d->SetDataPktMode (SCAN_V_DIRECT); break;
00967 // //                           case 'l': Icon->mem2d->SetDataPktMode (SCAN_V_LOG); break;
00968 // //                           case 'h': Icon->mem2d->SetDataPktMode (SCAN_V_HORIZONTAL); break;
00969 // //                           case 'p': Icon->mem2d->SetDataPktMode (SCAN_V_PERIODIC); break;
00970 // //                           }
00971 // //                           // [4] "Auto Scaling" -123
00972 // //                           // ========================================
00973 // //                           if(mid->options[MkIconOpt_AutoSkl] != '-'){
00974 // //                                   double eps=0.1;
00975 // //                                   XSM_DEBUG (DBG_L2,  "doing Skl ..." );
00976 // //                                   // Excange Icon <=> TmpSc
00977 // //                                   HlpSc = ActiveScan; ActiveScan = Icon; 
00978 // //                                   if(mid->options[MkIconOpt_AutoSkl] == '1') eps=0.05; 
00979 // //                                   if(mid->options[MkIconOpt_AutoSkl] == '2') eps=0.20; 
00980 // //                                   if(mid->options[MkIconOpt_AutoSkl] == '3') eps=0.30; 
00981 // //                                   Icon->Pkt2d[0].x = (int)(eps*(double)Icon->mem2d->GetNx());
00982 // //                                   Icon->Pkt2d[0].y = (int)(eps*(double)Icon->mem2d->GetNy());
00983 // //                                   Icon->Pkt2d[1].x = (int)((1.-eps)*(double)Icon->mem2d->GetNx());
00984 // //                                   Icon->Pkt2d[1].y = (int)((1.-eps)*(double)Icon->mem2d->GetNy());
00985 // //                                   Icon->PktVal=2;
00986 // //                                   Icon->mem2d->AutoHistogrammEvalMode (&Icon->Pkt2d[0], &Icon->Pkt2d[1]);
00987 // //                                   // AutoDisplay();
00988 // //                                   Icon->PktVal=0;
00989 // //                                   ActiveScan = HlpSc;
00990 // //                                   XSM_DEBUG (DBG_L2,  "AutoSkl - Icon :" << "nx:" << Icon->data.s.nx << " GetNx:" << Icon->mem2d->GetNx() );
00991 // //                                   Original->data.display.contrast = data.display.contrast;
00992 // //                                   Original->data.display.bright   = data.display.bright;
00993 // //                                   XSM_DEBUG (DBG_L2, "Contrast=" << Original->data.display.contrast);
00994 // //                           }
00995 // //                           if(mid->options[MkIconOpt_Scaling] == 'c'){
00996 // //                                   XSM_DEBUG (DBG_L2,  "doing manual Cps hi=" << hi0 << " ... lo=" << lo0 << " Gate=" << data.display.cnttime);
00997 // //                                   // Excange Icon <=> TmpSc
00998 // //                                   HlpSc = ActiveScan; ActiveScan = Icon; 
00999 // //                                   AutoDisplay(hi0*data.display.cnttime, lo0*data.display.cnttime);
01000 // //                                   ActiveScan = HlpSc;
01001 // //     
01002 // //                           }
01003 // //  
01004 // //                           // Put Icon
01005 // //                           epsf->init();
01006 // //   
01007 // //                           //          epsf->SetAbbWidth(figwidth);
01008 // //                           //          epsf->SetFontSize(fontsize);
01009 // //   
01010 // //                           epsf->placeimage();
01011 // //   
01012 // //                           epsf->putsize(Original);
01013 // //                           epsf->putframe();
01014 // //                           epsf->putticks(Original);
01015 // //                           //        epsf->putbar(ActiveScan);
01016 // //                           //        epsf->putmore(ActiveScan, title);
01017 // //                           //        epsf->putgrey(Original, Icon->mem2d, options[MkIconOpt_ELReg] == 'a', FALSE);
01018 // //                           XSM_DEBUG (DBG_L2,  "-Original:" << "nx:" << Original->data.s.nx << " GetNx:" << Original->mem2d->GetNx() );
01019 // //                           XSM_DEBUG (DBG_L2,  "-Icon    :" << "nx:" << Icon->data.s.nx << " GetNx:" << Icon->mem2d->GetNx() );
01020 // //                           // [5] "Scaling": -a
01021 // //  
01022 // //                           //      gapp->check_events();
01023 // //  
01024 // //                           epsf->putgrey(Original, Icon->mem2d, mid->options[MkIconOpt_Scaling] == 'a', FALSE);
01025 // //                           epsf->endimage();
01026 // //                           epsf->FootLine(Original);
01027 // //   
01028 // //                           //      delete Icon;
01029 // //                           delete TmpSc;
01030 // //                   }
01031 // //                   epsf->FootLine(Original, TRUE);
01032 // //                   epsf->close();
01033 // //                   delete epsf;
01034 // //           }
01035 // //   }
01036 // //}
01037 
01038 void Surface::MathOperationNoDest(gboolean (*MOp)(MATHOPPARAMSNODEST)){
01039         // Src, Quelle: Aktive Channel
01040         // Punkte: Diagonale Ecken von Rechteck
01041         int Merr;
01042         if(ActiveScan){ // ist ein Scan Active ? (als Quelle nötig)
01043                 // call of MathOp( SourceMem2d )
01044                 if( (Merr=(*MOp)(ActiveScan)) )
01045                         XSM_SHOW_ALERT(ERR_MATH, MathErrString[Merr], "", 1);
01046         }
01047         else{
01048                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOACTIVESCAN,HINT_ACTIVATESCANMATH,1);
01049         }
01050 }
01051 
01052 void Surface::MathOperation(gboolean (*MOp)(MATHOPPARAMS)){
01053         // Src, Quelle: Aktive Channel
01054         // Dest, Ziel:  Math Channel, wird ggf, angelegt oder überschrieben !
01055         // Punkte: Diagonale Ecken von Rechteck
01056         int Merr;
01057         int ChDest;
01058         if(ActiveScan){ // ist ein Scan Active ? (als Quelle nötig)
01059                 if((ChDest=FindChan(ID_CH_M_MATH)) < 0){ // ist bereits ein Math Scan vorhanden ? (benutzen !)
01060                         if((ChDest=FindChan(ID_CH_M_OFF)) < 0){ // keiner Math Scan, dann neuen anlegen, noch möglich ?
01061                                 // alle belegt !!!
01062                                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOFREECHAN,"",1);
01063                                 return;
01064                         }
01065                 }
01066                 // anlegen/erneuern einen Math Scans
01067                 gapp->channelselector->SetMode(ChDest, ID_CH_M_MATH);
01068                 ChannelMode[ChDest] = ID_CH_M_MATH;
01069                 if(! scan[ChDest]){ // Topo,.. Channel neu anlegen ?
01070                         //      scan[ChDest] = NewScan(ChannelView[ChDest], data.display.ViewFlg, ChDest, &data);
01071                         scan[ChDest] = new Scan(ChannelView[ChDest], data.display.ViewFlg, ChDest, &data, ActiveScan->mem2d->GetTyp());
01072                         // Fehler ?
01073                         if(!scan[ChDest]){
01074                                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOMEM,"",1);
01075                                 return;
01076                         }
01077                 }
01078                 // Parameter übernehmen, Größe einstellen, etc.
01079                 scan[ChDest]->create();
01080                 G_FREE_STRDUP_PRINTF(scan[ChDest]->data.ui.name, ActiveScan->data.ui.name); // Copy FileName
01081                 // call of MathOp( SourceMem2d, DestMem2d )
01082                 if( (Merr=(*MOp)(ActiveScan, scan[ChDest])) ){
01083                         XSM_SHOW_ALERT(ERR_MATH, MathErrString[Merr], "", 1);
01084                         SetMode (ChDest, ID_CH_M_OFF, TRUE);
01085                 } 
01086                 else
01087                         scan[ChDest]->draw();
01088         }
01089         else{
01090                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOACTIVESCAN,HINT_ACTIVATESCANMATH,1);
01091         }
01092 }
01093 
01094 void Surface::MathOperationX(gboolean (*MOp)(MATH2OPPARAMS), int IdSrc2, gboolean size_matching){
01095         // Src1, Quelle: Aktive Channel
01096         // Src2, second src: first Channel w Type "X"
01097         // Dest, Ziel:  Math Channel, wird ggf, angelegt oder überschrieben !
01098         // Punkte: Diagonale Ecken von Rechteck
01099         int Merr;
01100         int ChDest;
01101         int ChSrc2;
01102         if(ActiveScan){ // ist ein Scan Active ? (als Quelle nötig)
01103                 if((ChSrc2=FindChan(IdSrc2))>=0){ // ist zweite Quelle vorhanden ?
01104                         if(!scan[ChSrc2]){
01105                                 XSM_DEBUG (DBG_L2, "Scr2==0");
01106                                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NO2SRC,HINT_MAKESRC2,1);
01107                                 return;
01108                         }
01109                         if (size_matching)
01110                                 // are both srcs same size?
01111                                 if(scan[ChSrc2]->mem2d->GetNx() != ActiveScan->mem2d->GetNx()
01112                                    || scan[ChSrc2]->mem2d->GetNy() != ActiveScan->mem2d->GetNy()
01113                                         ){
01114                                         XSM_SHOW_ALERT(ERR_SORRY, ERR_SIZEDIFF,HINT_SIZEEQ,1);
01115                                         return;
01116                                 }
01117                         if((ChDest=FindChan(ID_CH_M_MATH)) < 0){ // ist bereits ein Math Scan vorhanden ? (benutzen !)
01118                                 if((ChDest=FindChan(ID_CH_M_OFF)) < 0){ // keiner Math Scan, dann neuen anlegen, noch möglich ?
01119                                         // alle belegt !!!
01120                                         XSM_SHOW_ALERT(ERR_SORRY, ERR_NOFREECHAN,"",1);
01121                                         return;
01122                                 }
01123                         }
01124                         // anlegen/erneuern einen Math Scans
01125                         gapp->channelselector->SetMode(ChDest, ID_CH_M_MATH);
01126                         ChannelMode[ChDest] = ID_CH_M_MATH;
01127                         if(! scan[ChDest]){ // Topo,.. Channel neu anlegen ?
01128                                 //      scan[ChDest] = NewScan(ChannelView[ChDest], data.display.ViewFlg, ChDest, &data);
01129                                 scan[ChDest] = new Scan(ChannelView[ChDest], data.display.ViewFlg, ChDest, &data, ActiveScan->mem2d->GetTyp());
01130                                 // Fehler ?
01131                                 if(!scan[ChDest]){
01132                                         XSM_SHOW_ALERT(ERR_SORRY, ERR_NOMEM,"",1);
01133                                         return;
01134                                 }
01135                         }
01136                         // Parameter übernehmen, Größe einstellen, etc.
01137                         scan[ChDest]->create();
01138                         // call of MathOp( Source1Mem2d, Source2Mem2d, DestMem2d )
01139                         if( (Merr=(*MOp)(ActiveScan, scan[ChSrc2], scan[ChDest])) ){
01140                                 XSM_SHOW_ALERT(ERR_MATH, MathErrString[Merr], "", 1);
01141                                 SetMode (ChDest, ID_CH_M_OFF, TRUE);
01142                         }
01143                         else
01144                                 scan[ChDest]->draw();
01145                 }
01146                 else{
01147                         XSM_SHOW_ALERT(ERR_SORRY, ERR_NO2SRC,HINT_MAKESRC2,1);
01148                 }
01149         }
01150         else{
01151                 XSM_SHOW_ALERT(ERR_SORRY, ERR_NOACTIVESCAN,HINT_ACTIVATESCANMATH,1);
01152         }
01153 }
01154 
01155  

Generated on Sat Apr 1 09:04:04 2006 for GXSM by  doxygen 1.4.6