1 /** @file displaylines.cpp
2 @package snark14Display
3 @author Bruno M. Carvalho and Deniz Sarioz
4 licensed under (open-source) QPL v1.0
5 which accompanies this distribution in the file QPL
7 modification: Joanna Klukowska 1/13/2009
8 added choice of grayScale display for plot
9 in addition to color display
12 #include "displaylines.hpp"
13 #include "verbosity.hpp"
20 #include <qpushbutton.h>
24 #include <qwhatsthis.h>
27 #include <qmessagebox.h>
28 #include <qfiledialog.h>
33 * Constructs a displaylineswindow which is a child of 'parent', with the
34 * name 'name' and widget flags set to 'f'
36 * The dialog will by default be modeless, unless you set 'modal' to
37 * TRUE to construct a modal dialog.
39 displaylineswindow::displaylineswindow( QWidget* parent, const char* name, QPixmap* pixmap, bool modal, WFlags fl , int x, int y )
40 : QDialog( parent, name, modal, fl )
45 setName( "Column/Line Profile" );
48 int outerTopYPad = 10;
49 int outerBotYPad = 90;
50 int WID = pixmap->width();
51 int WINWIDTH = 2*outerXPAD + WID;
52 int HEI = pixmap->height();
53 int WINHEIGHT = HEI + outerTopYPad + outerBotYPad;
54 resize( WINWIDTH, WINHEIGHT );
55 setMinimumSize( QSize( WINWIDTH, WINHEIGHT ) );
56 setMaximumSize( QSize( WINWIDTH, WINHEIGHT ) );
57 // setCaption( tr( "Column/Line Profile" ) );
63 pixmapwidget = new QWidget( this, "pixmapwidget" );
64 pixmapwidget->setGeometry( QRect( outerXPAD, outerTopYPad, WID, HEI ) );
65 pixmapwidget->setBackgroundPixmap( *pixmap );
70 savebutton = new QPushButton( this, "savebutton" );
71 savebutton->setGeometry( QRect( BUTXPAD, WINHEIGHT-BUTTONHEI-BUTBOTPAD, BUTTONWID, BUTTONHEI ) );
72 savebutton->setCaption( tr( "" ) );
73 savebutton->setText( tr( "Save" ) );
74 QObject::connect(savebutton,SIGNAL(clicked()),this,SLOT(saveImage()));
76 closebutton = new QPushButton( this, "closebutton" );
77 closebutton->setGeometry( QRect( WINWIDTH-BUTTONWID-BUTXPAD, WINHEIGHT-BUTTONHEI-BUTBOTPAD, BUTTONWID, BUTTONHEI ) );
78 closebutton->setCaption( tr( "" ) );
79 closebutton->setText( tr( "Close" ) );
80 QObject::connect(closebutton,SIGNAL(clicked()),this,SLOT(accept()));
81 } // displaylineswindow ctor
84 * Destroys the object and frees any allocated resources
86 displaylineswindow::~displaylineswindow()
88 // no need to delete child widgets, Qt does it all for us
91 /** Saves the profile graph image
93 @author Bruno M. Carvalho, changes by Deniz
95 void displaylineswindow::saveImage()
97 if(std::verbose >=2) std::cout << "++displaylineswindow::saveImage()" << std::endl;
98 QString prefixForSaving = (imagename.simplifyWhiteSpace());
99 if(std::verbose >=2) std::cout << "My prefix is originally: \"" << prefixForSaving << "\"" << std::endl;
100 // beware weird characters in save file name!
101 // these might be intentionally meaningful
102 prefixForSaving.replace( QRegExp("\\="), "_EQ_");
103 prefixForSaving.replace( QRegExp("\\+"), "_PLUS_");
104 prefixForSaving.replace( QRegExp("\\@"), "_AT_");
105 // prefixForSaving.replace( QRegExp("-"), "_MINUS_"); // maybe
106 // convert everything non-alphanumeric to underscore
107 prefixForSaving.replace( QRegExp("[^a-zA-Z0-9]"), "_");
108 // allow maximum of 2 consecutive underscores
109 prefixForSaving.replace( QRegExp("__+") , "__");
110 // chuck underscore from beginning and end
111 prefixForSaving.replace( QRegExp("^_+"), "");
112 prefixForSaving.replace( QRegExp("_+$"), "");
113 if(std::verbose >=2) std::cout << "My prefix became: \"" << prefixForSaving << "\"" << std::endl;
114 // this is how the filter ought to be according to manual for version 3.3.
115 QString myExtensionFilter = // delimiter is double-semicolon, NOT '\n'
123 QString mySaveAs = "Save Image as";
124 QString startInDir = "./";
125 QFileDialog fd(startInDir, myExtensionFilter, this, mySaveAs, true);
126 fd.setMode(QFileDialog::AnyFile);
127 fd.setSelection(prefixForSaving);
128 if (QDialog::Accepted != fd.exec()) {
129 if(std::verbose >=2) std::cout << "--displaylineswindow::saveImage() in a hurry" << std::endl;
130 return; // happens, say, when cancel is pressed. just leave, no harm.
132 QString userFileSavePrefix = fd.selectedFile();
133 QString userFileSaveExtension = fd.selectedFilter();
134 if (userFileSavePrefix.isEmpty()) {
135 if(std::verbose >=2) std::cout << "--displaylineswindow::saveImage() in a hurry" << std::endl;
136 return; // happens, say, when cancel is pressed. just leave, no harm.
138 if(std::verbose >=2) std::cout << "Got file name as: \"" << userFileSavePrefix << "\"" << std::endl;
139 if(std::verbose >=2) std::cout << "Got selected ext: \"" << userFileSaveExtension << "\"" << std::endl;
140 /* NB: userFileSavePrefix now contains directory info as well.
141 * if user entered additional forward-slashes without
142 * knowing that it signified directory, that's NOT our problem.
143 * (the user MAY legitimately enter "a/myImage" as file name if there is a directory "a"
144 * within the currently open directory in the save dialog window)
145 * do part only after last forward-slash (i.e., what user entered)...
146 * don't want to burn ourselves if path in fact had legit non-alphanumericounderscore chars
148 QString justFilePrefix, justPath;
149 // funnylooking because written to work with Qt BOTH 2.3 and 3.3
150 int posLastSlash = userFileSavePrefix.findRev('/'); // returns pos if found, -1 if not.
151 if (-1 != posLastSlash) {
152 justPath = userFileSavePrefix.left(posLastSlash+1); // +1 to include last '/'
153 justFilePrefix = userFileSavePrefix;
154 QRegExp fakeRegex("^" + justPath); // it just *looks* fake...
155 justFilePrefix.replace( fakeRegex, "" ); // chuck away including last '/' for justFilePrefix
156 if(std::verbose >=2) std::cout << "just after regex replace, justFilePrefix: \"" << justFilePrefix << "\"" << std::endl;
157 } else { // if for some reason no forwardslash, handle that gracefully too.
158 justFilePrefix = userFileSavePrefix;
161 if(std::verbose >=2) std::cout << "justPath is: \"" << justPath << "\"" << std::endl;
162 if(std::verbose >=2) std::cout << "justFilePrefix is first: \"" << justFilePrefix << "\"" << std::endl;
163 // remove justFilePrefix from ONLY the end of 'userFileSavePrefix'.
164 justFilePrefix.replace( QRegExp("="), "_EQ_");
165 justFilePrefix.replace( QRegExp("+"), "_PLUS_");
166 justFilePrefix.replace( QRegExp("[^a-zA-Z0-9]"), "_"); // no forward slash in regex
167 // allow maximum of 2 consecutive underscores
168 justFilePrefix.replace( QRegExp("__+") , "__");
169 // chuck underscore from beginning and end
170 justFilePrefix.replace( QRegExp("^_+"), "");
171 justFilePrefix.replace( QRegExp("_+$"), "");
172 if(std::verbose >=2) std::cout << "justFilePrefix is later: \"" << justFilePrefix << "\"" << std::endl;
173 // reset userFileSavePrefix by putting back together justPath and the refined justFilePrefix
174 userFileSavePrefix = justPath + justFilePrefix;
175 userFileSaveExtension.truncate(3);
176 if(std::verbose >=2) std::cout << "My userFileSavePrefix is \"" << userFileSavePrefix << "\"" << std::endl;
177 if(std::verbose >=2) std::cout << "My userFileSaveExtension is \"" << userFileSaveExtension << "\"" << std::endl;
178 QString extensionUpper = userFileSaveExtension.upper();
179 QString saveFullNameWithPath = userFileSavePrefix + "." + extensionUpper;
180 if(std::verbose >=2) std::cout << "extensionUpper is now \"" << extensionUpper << "\"" << std::endl;
181 if(std::verbose >=2) std::cout << "saveFullNameWithPath is now \"" << saveFullNameWithPath << "\"" << std::endl;
182 QImage prof=localpixmap->convertToImage();
184 recio.setImage(prof);
185 recio.setFormat(extensionUpper);
186 recio.setFileName(saveFullNameWithPath);
187 if ( recio.write() ) {
188 if(std::verbose>=1) {
189 std::cout << "successfully saved: \"" << saveFullNameWithPath << "\"" << std::endl;
192 std::cerr << "UNsuccessfully tried to save as: \"" << saveFullNameWithPath << "\"" << std::endl;
194 if(std::verbose >=2) std::cout << "--displaylineswindow::saveImage()" << std::endl;
195 } // --displaylineswindow::saveImage()