From: andrew7 <bd...@us...> - 2006-10-09 01:11:10
|
Update of /cvsroot/smartwin/SmartWin/include/io In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv13099/include/io Modified Files: InDialog.h InDialogClasses.h html_get.h html_put.h iolib.h Log Message: Add DirString class to InDialogClasses so that InDialogs can browse for directories. Add support for tagged strings in html_put and html_get. Make static functions in iolib.h, and conform more to tstring instead of string. Index: iolib.h =================================================================== RCS file: /cvsroot/smartwin/SmartWin/include/io/iolib.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- iolib.h 10 Jul 2006 02:52:52 -0000 1.10 +++ iolib.h 9 Oct 2006 01:11:05 -0000 1.11 @@ -46,7 +46,7 @@ { public: -void StringToBytes( const string & hexstring, unsigned char dat[], int & len ) +static void StringToBytes( const string & hexstring, unsigned char dat[], int & len ) { len = 0; @@ -58,7 +58,7 @@ //--------------------- -void BytesToString( unsigned char dat[], int len, string & hexstring ) +static void BytesToString( unsigned char dat[], int len, string & hexstring ) { stringstream out_hash; out_hash << hex; @@ -86,7 +86,7 @@ //------------------------------------------------------------------------- -bool FileToString( SmartUtil::tstring & filePath, SmartUtil::tstring & filedata, bool hex_editing ) +static bool FileToString( SmartUtil::tstring & filePath, SmartUtil::tstring & filedata, bool hex_editing ) { if ( 0 == filePath.size() ) return( false ); @@ -98,7 +98,7 @@ const int bytes_per_line = 24; int n = 0; - stringstream hexstr; + SmartUtil::tstringstream hexstr; hexstr << hex; int b = file.get(); while ( file.good() ) @@ -107,12 +107,12 @@ if ( ++n == bytes_per_line ) { - hexstr << "\r\n"; + hexstr << _T("\r\n"); n = 0; } else { - hexstr << " "; + hexstr << _T(" "); } b = file.get(); } @@ -125,11 +125,11 @@ if ( !file.good() ) return( false ); const int bsize = 65536; - char buff[bsize]; + TCHAR buff[bsize]; while ( file.getline( buff, bsize ) ) { filedata += buff; - filedata += "\r\n"; + filedata += _T("\r\n"); } } @@ -138,7 +138,7 @@ //------------------------------------------------------------------------- -bool StringToFile( const SmartUtil::tstring & filePath, const SmartUtil::tstring & filedata, bool hex_editing ) +static bool StringToFile( const SmartUtil::tstring & filePath, const SmartUtil::tstring & filedata, bool hex_editing ) { if ( 0 == filePath.size() != 0 ) return( false ); @@ -150,7 +150,7 @@ if ( ! file.good() ) return( false ); // Parse the "f3 32 85 d2" data into the corresponding characters. - stringstream hexstr( filedata ); + SmartUtil::tstringstream hexstr( filedata ); hexstr << hex; int b; @@ -174,7 +174,7 @@ //------------------------------------------------------------------------- -static bool print( string & printtext ) +static bool print( SmartUtil::tstring & printtext ) { PRINTDLG pd; @@ -192,7 +192,7 @@ // try to retrieve the printer DC if ( !PrintDlg( & pd ) ) { - MessageBox( NULL, "PrintDlg( &pd ) failed!", "Fatal Error", MB_OK | MB_ICONERROR ); + MessageBox( NULL, _T("PrintDlg( &pd ) failed!"), _T("Fatal Error"), MB_OK | MB_ICONERROR ); return false; } @@ -211,9 +211,9 @@ int page_width = GetDeviceCaps( hPrinter, HORZRES ); // 5100 int page_height = GetDeviceCaps( hPrinter, VERTRES ); // 6600 const int linesize = 999; - char line[linesize]; + TCHAR line[linesize]; - stringstream doc( printtext ); + SmartUtil::tstringstream doc( printtext ); // uncomment the following line to print in colour! :) // SetTextColor( hPrinter, 0x0000FF ); @@ -223,7 +223,7 @@ while ( doc.getline( line, linesize ) ) { - len = ( int ) strlen( line ); + len = ( int ) _tcslen( line ); // if ( line[len - 1] == '\n' ) len--; TextOut( hPrinter, 100, y_pos, line, len ); @@ -244,10 +244,10 @@ //------------------------------------------------------------------------- -static bool FtpWriteFile( string & ftptext, string & server, string fname, - string & username, string & password ) +static bool FtpWriteFile( SmartUtil::tstring & ftptext, SmartUtil::tstring & server, SmartUtil::tstring fname, + SmartUtil::tstring & username, SmartUtil::tstring & password ) { - HINTERNET io_hand = InternetOpen( "Me", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); + HINTERNET io_hand = InternetOpen( _T("Me"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); DWORD dwContext = 123; HINTERNET ic_hand = InternetConnect( io_hand, server.c_str(), INTERNET_DEFAULT_FTP_PORT, username.c_str(), password.c_str(), @@ -274,10 +274,11 @@ //------------------------------------------------------------------------- -static bool FtpReadFile( string & server, string fname, string & username, string & password, - string & ftptext ) +static bool FtpReadFile( SmartUtil::tstring & server, SmartUtil::tstring fname, + SmartUtil::tstring & username, SmartUtil::tstring & password, + SmartUtil::tstring & ftptext ) { - HINTERNET io_hand = InternetOpen( "Me", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); + HINTERNET io_hand = InternetOpen( _T("Me"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); DWORD dwContext = 123; HINTERNET ic_hand = InternetConnect( io_hand, server.c_str(), INTERNET_DEFAULT_FTP_PORT, username.c_str(), password.c_str(), @@ -291,11 +292,11 @@ FTP_TRANSFER_TYPE_BINARY, ( DWORD_PTR ) & dwContext ); // Read in the FTP file a chunk at a time. - ftptext = ""; + ftptext = _T(""); BOOL ReadOk; DWORD BytesRead = 0; const int bsize = 65536; - char buff[bsize]; + TCHAR buff[bsize]; while ( ReadOk = InternetReadFile( f_hand, buff, bsize, & BytesRead ) ) { if ( 0 == BytesRead ) break; @@ -312,11 +313,11 @@ //------------------------------------------------------------------------- -static bool FileEmailFile( string & emailtext ) +static bool FileEmailFile( SmartUtil::tstring & emailtext ) { #ifndef __WINE__ // Get address of function from MAPI32.DLL - HINSTANCE hDLL = LoadLibrary( "mapi32" ); if ( NULL == hDLL ) return( false ); + HINSTANCE hDLL = LoadLibrary( _T("mapi32") ); if ( NULL == hDLL ) return( false ); LPMAPISENDMAIL SendMail = ( LPMAPISENDMAIL ) GetProcAddress( hDLL, "MAPISendMail" ); if ( NULL == SendMail ) { Index: InDialogClasses.h =================================================================== RCS file: /cvsroot/smartwin/SmartWin/include/io/InDialogClasses.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- InDialogClasses.h 5 May 2006 17:14:40 -0000 1.4 +++ InDialogClasses.h 9 Oct 2006 01:11:05 -0000 1.5 @@ -102,6 +102,220 @@ vector< std::pair< SmartUtil::tstring, SmartUtil::tstring > > itsFilters; }; + + + + +/// A string that contains a directory name. +/** The prompt should be like "Install directory: " + * + * DirString * can be passed to InDialog.add functions. + * InDialog will fill a combo box with subdirectories if the dir exists + * otherwise with the directories above. Double clicking on directories will + * display a new level of directories. Double clicking on .. will move up a level. + * At the top level, InDialog will give a list of drives: a:\ b:\ c:\ etc + */ +class DirString +{ +public: + /// Constructor for an initial directory name. DirString( "c:\program files\tootsie" ) + DirString( const SmartUtil::tstring & inDirPath, bool inAllowCreation = true ) + : itsDirPath( inDirPath ), + itsAllowCreation( inAllowCreation ) + {} + + bool allowsCreation() { + return itsAllowCreation; + } + + SmartUtil::tstring getDir() + { + return itsDirPath; + } + + void setDir( const SmartUtil::tstring & inDirPath ) + { + itsDirPath= inDirPath; + } + + + // IN: A new directory for this class instance. + // OUT: returns a vector of the parent and subdirectories of inDirPath + // + // Given the current itsDirPath, generate a list of + // alternate directories, including the root directory, ("\"), the + // parent directory ("..") and any sub directories. + // + // The hierarchy is: + // + // a:\ + // b:\ + // c:\ + // c:\dir + // c:\dir\subdir + // d:\ + // + // The format of the vector returned is: + // CurrentDir + // ParentDir + // SubDirectories + // + vector< SmartUtil::tstring > genNearDirs() + { + vector< SmartUtil::tstring > choices; + + if ( 0 == itsDirPath.compare(_T("My Computer") ) ) { + genLogicalDrives( choices ); + choices.insert( choices.begin(), itsDirPath ); + } else { + choices= genSubDirectories(); + choices.insert( choices.begin(), parentOf( itsDirPath ) ); + choices.insert( choices.begin(), itsDirPath ); + } + + return choices; + } + + + // return c:\dir\subdir + // from c:\dir\subdir\file.ext + // + SmartUtil::tstring parentOf( const SmartUtil::tstring & pathFile ) + { + if ( isJustDrive( pathFile ) ) { + return _T("My Computer"); + } + + size_t slashDex= pathFile.find_last_of('\\'); + if ( string::npos == slashDex ) { + return _T("My Computer"); + } + SmartUtil::tstring parent = pathFile.substr( 0, slashDex ); + if ( string::npos == parent.find( '\\' ) ) { + parent += "\\"; // Set "c:\" from c: + } + return parent; + } + + bool isJustDrive( const SmartUtil::tstring & pathFile ) + { + if ( 1 == pathFile.find(':') ) { + if ( pathFile.size() <= 3 ) { + return true; // "c:\" + } + } + if ( 1 == pathFile.size() ) { + if ( '\\' == pathFile[0] ) { + return true; // "\" + } + } + + return false; // + } + + + void genLogicalDrives( vector< SmartUtil::tstring > & subdirs ) + { + SmartUtil::tstring drive; + DWORD drives= GetLogicalDrives(); + int mask= 1; + for( TCHAR b= 'A'; b <= 'Z'; b++ ) { + if ( mask & drives ) { + drive= _T("A:\\"); + drive[0]= b; + subdirs.push_back( drive ); + } + mask= mask << 1; + } + + } + + + vector< SmartUtil::tstring > genSubDirectories() + { + vector< SmartUtil::tstring > subdirs; // Return value + SmartUtil::tstring curPath, curFile, cur_dir_star; + + curPath= itsDirPath; + if ( '\\' != curPath[curPath.size()-1] ) { + curPath += TEXT( "\\" ); + } + // Now curPath is terminated with a \ + + cur_dir_star= curPath + TEXT( "*" ); + + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile( cur_dir_star.c_str(), &FindFileData); + + while ( INVALID_HANDLE_VALUE != hFind ) { + + if ( FILE_ATTRIBUTE_DIRECTORY == FindFileData.dwFileAttributes ) { + if ( '.' != FindFileData.cFileName[0] ) { + curFile= curPath + FindFileData.cFileName; + subdirs.push_back( curFile ); + } + } + + if ( ! FindNextFile( hFind, &FindFileData) ) { + break; // No more files in the directory + } + } + FindClose( hFind ); + return subdirs; + } + + + // + // fullpath, if true, returns files as c:\dir\subdir\file.ext + // + vector< SmartUtil::tstring > genFiles( bool fullPath= true, SmartUtil::tstring ext = _T("*") ) + { + vector< SmartUtil::tstring > subdirs; // Return value + SmartUtil::tstring curPath, curFile, cur_dir_star; + + curPath= itsDirPath; + if ( '\\' != curPath[curPath.size()-1] ) { + curPath += TEXT( "\\" ); + } + // Now curPath is terminated with a \ + + cur_dir_star= curPath + ext; + + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile( cur_dir_star.c_str(), &FindFileData); + + while ( INVALID_HANDLE_VALUE != hFind ) { + + if ( FILE_ATTRIBUTE_DIRECTORY != FindFileData.dwFileAttributes ) { + if ( fullPath ) { + curFile= curPath + FindFileData.cFileName; + } else { + curFile= FindFileData.cFileName; + } + subdirs.push_back( curFile ); + } + + if ( ! FindNextFile( hFind, &FindFileData) ) { + break; // No more files in the directory + } + } + FindClose( hFind ); + return subdirs; + } + + + + + +private: + bool itsAllowCreation; // If true, allow directories that don't exist yet. + SmartUtil::tstring itsDirPath; +}; + + + + + /// A string that must be selected from one of a list of possible strings. /** * The current selection is itsChoosenIndex. @@ -111,13 +325,13 @@ class ChoiceString { public: - /// Constructor accepting char * inStrings[] = { "scissors", "rock", "paper" }; - ChoiceString ( char * inStrings[], int inNumStrings, int inChossenIndex = 0 ) + /// Constructor accepting char * inStrings[] = { _T("scissors"), _T("rock"), _T("paper") }; + ChoiceString ( TCHAR * inStrings[], int inNumStrings, int inChossenIndex = 0 ) : itsChoosenIndex( inChossenIndex ) { for ( int i = 0; i < inNumStrings; i++ ) { - itsPossibleStrings.push_back( inStrings[i] ); + itsPossibleStrings.push_back( SmartUtil::tstring(inStrings[i]) ); } } @@ -140,7 +354,8 @@ // Get each string before a | string::size_type dex = 0, barDex; - while ( string::npos != ( barDex = inBarSeperatedStrings.find( "|", dex ) ) ) + SmartUtil::tstring bar( _T("|") ); + while ( string::npos != ( barDex = inBarSeperatedStrings.find( bar, dex ) ) ) { choice = inBarSeperatedStrings.substr( dex, barDex - dex ); itsPossibleStrings.push_back( choice ); Index: html_put.h =================================================================== RCS file: /cvsroot/smartwin/SmartWin/include/io/html_put.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- html_put.h 5 May 2006 17:14:40 -0000 1.8 +++ html_put.h 9 Oct 2006 01:11:05 -0000 1.9 @@ -97,6 +97,22 @@ //------------------------------------------------------------------------- + // put + // <input type="text" name="tag" value="taggedValue" > + // + void putTaggedText( const SmartUtil::tstring & tag, SmartUtil::tstring & taggedValue ) + { + itsIo << "<input type=text name=\"" << tag << "\"" + << " value=\"" << taggedValue << "\" >\n"; + } + + //------------------------------------------------------------------------- + + + + + + // put( WidgetCheckBox * wcb ) // template< class Parent, class MessageMapPolicy > Index: html_get.h =================================================================== RCS file: /cvsroot/smartwin/SmartWin/include/io/html_get.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- html_get.h 5 May 2006 17:14:40 -0000 1.9 +++ html_get.h 9 Oct 2006 01:11:05 -0000 1.10 @@ -114,6 +114,37 @@ //------------------------------------------------------------------------- + // Set value to "value_for_tag" from: + // <input type="text" name="tagExpected" value="value_for_tag" > + // + bool getTaggedText( const SmartUtil::tstring & tagExpected, SmartUtil::tstring & value ) + { + string tag, checkname; + itsIo >> tag; + if ( "<input" != tag ) return false; + + itsIo >> tag; + if ( "type=text" != tag ) return false; + + itsIo >> tag; + SmartUtil::tstring taglabel= "name=\""; + taglabel += tagExpected; taglabel += "\""; + if ( taglabel != tag ) return false; + + + itsIo >> tag; // value="value_for_tag" + if ( ! parse_quoted_string_value( tag, value ) ) + return false; + + itsIo >> tag; if ( ">" != tag ) return false; + + return true; + } + + //------------------------------------------------------------------------- + + + // Set value to 12 from: // <input type="text" value="12" > // @@ -472,9 +503,10 @@ //------------------------------------------------------------------------- - // Extract the number from a string: value="12" + // Given a valstr of: value="valstring" + // set inquotes to be: valstring // - bool parse_quoted_numeric_value( string & valstr, int & val ) + bool parse_quoted_string_value( const string & valstr, string & inquotes ) { string::size_type first_num = valstr.find( '"' ); if ( first_num == string::npos ) return false; @@ -483,7 +515,20 @@ string::size_type last_quote = valstr.find( '"', first_num ); if ( last_quote == string::npos ) return false; - string inquotes = valstr.substr( first_num, last_quote - first_num ); + inquotes = valstr.substr( first_num, last_quote - first_num ); + return true; + } + + //------------------------------------------------------------------------- + + // Extract the number from a string: value="12" + // + bool parse_quoted_numeric_value( const string & valstr, int & val ) + { + string inquotes; + bool ok= parse_quoted_string_value( valstr, inquotes ); + if ( ! ok ) return false; + stringstream ss( inquotes ); ss >> val; return true; Index: InDialog.h =================================================================== RCS file: /cvsroot/smartwin/SmartWin/include/io/InDialog.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- InDialog.h 5 May 2006 17:14:40 -0000 1.10 +++ InDialog.h 9 Oct 2006 01:11:05 -0000 1.11 @@ -85,14 +85,13 @@ .createDialog() ) return; </pre> * The resulting dialog: -* - is sized to show each prompt and variable initial value in two equally wide columns. +* - is sized to show each prompt and variable initial value in two columns. * - prevents illegal values from being entered. * - has an ok button that sets variables when pressed, and returns IDOK. * - has a cancel button which leaves the variables untouched, and returns IDCANCEL * - can optionally take a font in the constructor and size the fields accordingly. * - has tab control between input fields. * -* Need to add dates, colors */ class InDialog : public WidgetFactory< WidgetModalDialog, InDialog, MessageMapPolicyModalDialogWidget > @@ -142,7 +141,7 @@ * SmartUtil::tstring * <br> * SYSTEMTIME * <br> * The specially defined types (See InDialogClasses.h) are: <br> - * PasswordString *, FileString *, BoundedLong *, ChoiceString * + * PasswordString *, FileString *, DirString *, BoundedLong *, ChoiceString * * * * The initial contents are displayed as a default, @@ -172,12 +171,13 @@ DlgTemplate.dwExtendedStyle = 0; // WS_EX_CONTROLPARENT; DlgTemplate.cdit = 0; // No dialog items in the dialog - DlgTemplate.x = 0; DlgTemplate.y = 0; - DlgTemplate.cx = 0; DlgTemplate.cy = 0; // Sizing done at dialog init time. + DlgTemplate.x = 0; DlgTemplate.y = 0; // Positioning done now. + DlgTemplate.cx = 0; DlgTemplate.cy = 0; // Sizing done at dialog init time. setDlgTemplate( DlgTemplate ); // Optionally override the default dialog template } + // utility routine to add a WidgetStatic and WidgetRichTextBox for a textual variable. // OUT: Added an entry to itsStatics and itsBoxes // @@ -203,7 +203,7 @@ } else { - textSize = wtb->getTextSize( "yT-^" ); // A min size with descenders and a high symbol. + textSize = wtb->getTextSize( _T("yT-^") ); // A min size with descenders and a high symbol. } maxInputArea.maxOf( textSize ); // wtb->setBackgroundColor( RGB( rand()%255, rand()%255, rand()%255 ) ); @@ -234,7 +234,7 @@ template< class numtype > void putNumericIntoString( int b ) { - stringstream ss; + SmartUtil::tstringstream ss; numtype * val = boost::any_cast < numtype * >( itsVariables.at( b ) ); ss << * val; addPromptAndText( itsPrompts.at( b ), ss.str(), ES_NUMBER ); @@ -249,6 +249,7 @@ itsExtraAroundText = Point( 16, 12 ); // X,Y pixels added to calculated text height and width. itsBorder = Point( 4, 12 ); // Seperation between widgets + // Prepare the widgets for use. for ( unsigned int b = 0; b < itsVariables.size(); b++ ) { @@ -256,33 +257,38 @@ if ( itsVariables.at( b ).type() == typeid( long * ) ) { putNumericIntoString< long >( b ); + continue; } // int * if ( itsVariables.at( b ).type() == typeid( int * ) ) { putNumericIntoString< int >( b ); + continue; } // float * if ( itsVariables.at( b ).type() == typeid( float * ) ) { putNumericIntoString< float >( b ); + continue; } // double * if ( itsVariables.at( b ).type() == typeid( double * ) ) { putNumericIntoString< double >( b ); + continue; } // class BoundedLong * if ( itsVariables.at( b ).type() == typeid( class BoundedLong * ) ) { - stringstream ss; + SmartUtil::tstringstream ss; BoundedLong * valptr = boost::any_cast < BoundedLong * >( itsVariables.at( b ) ); ss << valptr->itsVal; addPromptAndText( itsPrompts.at( b ), ss.str(), 0 ); + continue; } // SmartUtil::tstring * @@ -290,6 +296,7 @@ { SmartUtil::tstring * val = boost::any_cast < SmartUtil::tstring * >( itsVariables.at( b ) ); addPromptAndText( itsPrompts.at( b ), * val, 0 ); + continue; } // PasswordString * @@ -297,6 +304,7 @@ { PasswordString * valptr = boost::any_cast < PasswordString * >( itsVariables.at( b ) ); addPromptAndText( itsPrompts.at( b ), valptr->itsString, ES_PASSWORD ); + continue; } // FileString * @@ -305,8 +313,49 @@ FileString * val = boost::any_cast < FileString * >( itsVariables.at( b ) ); addPromptAndText( itsPrompts.at( b ), val->itsFilePath, 0 ); itsStatics.at( b )->onClicked( & InDialog::FetchFilename ); + continue; } + + // DirString * + if ( itsVariables.at( b ).type() == typeid( DirString * ) ) + { + addPrompt( itsPrompts.at( b ) ); + DirString * valptr = boost::any_cast < DirString * >( itsVariables.at( b ) ); + + vector< SmartUtil::tstring > choices = valptr->genNearDirs(); + + // Put all the strings into the WidgetComboBox + // We calculate that the Combo needs enough space for 2 lines at least. + WidgetComboBox::Seed seed= WidgetComboBox::getDefaultSeed(); + if ( valptr->allowsCreation() ) { + seed.style= WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS | WS_VSCROLL; + } + WidgetComboBox * combo = createComboBox(seed); + combo->addRemoveStyle( WS_TABSTOP, true ); + if ( setFont ) + combo->setFont( itsFont ); + else + combo->setFont( SystemFont ); + + int numChoices = ( int ) choices.size(); + for ( int i = 0; i < numChoices; i++ ) + { + combo->addValue( choices[ i ] ); + Point OptionSize = combo->getTextSize( choices[ i ] ); + OptionSize.x += 24; // Account for \/ at right of combo box. + maxInputArea.maxOf( OptionSize ); + } + combo->setSelectedIndex( 0 ); + combo->onSelectionChanged( & InDialog::dirSelectionChanged ); + + itsIndicies.push_back( ( int ) itsCombos.size() ); + itsCombos.push_back( combo ); + continue; + } + + + // ChoiceString * if ( itsVariables.at( b ).type() == typeid( ChoiceString * ) ) { @@ -334,6 +383,7 @@ itsIndicies.push_back( ( int ) itsCombos.size() ); itsCombos.push_back( combo ); + continue; } // bool * @@ -354,6 +404,7 @@ itsChecks.push_back( check ); maxInputArea.maxOf( check->getTextSize( _T( "[ ]" ) ) ); + continue; } // SYSTEMTIME * @@ -375,26 +426,34 @@ itsIndicies.push_back( ( int ) itsDates.size() ); itsDates.push_back( date ); - maxInputArea.maxOf( itsStatics.at( b )->getTextSize( "12/12/1999" ) ); + maxInputArea.maxOf( itsStatics.at( b )->getTextSize( _T("12/12/1999") ) ); + continue; } // COLORREF * if ( itsVariables.at( b ).type() == typeid( COLORREF * ) ) { // Put the starting color in itsColors - addPromptAndText( itsPrompts.at( b ), "", 0 ); + addPromptAndText( itsPrompts.at( b ), _T(""), 0 ); COLORREF * colorPtr = boost::any_cast < COLORREF * >( itsVariables.at( b ) ); WidgetRichTextBox * wtb = itsBoxes[ itsIndicies[ b ] ]; wtb->setBackgroundColor( * colorPtr ); itsColors.insert( pair< int, COLORREF >( b, * colorPtr ) ); itsStatics.at( b )->onClicked( & InDialog::chooseColor ); + continue; } + + // Catch failure to pass in a supported type + // so that itsPrompts and itsVariables stay coherent. + SmartUtil::tstring msg( _T("InDialog unsupported type: ") ); + msg += itsVariables.at( b ).type().name(); + addPromptAndText( itsPrompts.at( b ), msg, 0 ); } // Add the Cancel and OK buttons. itsCancelBut = createButton(); - itsCancelBut->setText( "cancel" ); + itsCancelBut->setText( _T("cancel") ); itsCancelBut->addRemoveStyle( WS_TABSTOP, true ); itsCancelBut->onClicked( & InDialog::OnCancel ); if ( setFont ) @@ -403,7 +462,7 @@ itsCancelBut->setFont( SystemFont ); itsOkBut = createButton(); - itsOkBut->setText( "ok" ); + itsOkBut->setText( _T("ok") ); itsOkBut->addRemoveStyle( WS_TABSTOP, true ); itsOkBut->onClicked( & InDialog::OnOk ); if ( setFont ) @@ -421,6 +480,8 @@ return false; // Indicate that the focus was set. } + + // Bring up another dialog to accept a file name by browsing the file system. // ( used by FileString variables ) // @@ -462,11 +523,39 @@ } } + + void dirSelectionChanged( WidgetComboBoxPtr comboBox ) + { + // Need to find which DirString has this comboBox. + for ( unsigned int b = 0; b < itsVariables.size(); b++ ) { + if ( itsVariables.at( b ).type() == typeid( DirString * ) ) { + if ( comboBox == itsCombos[ itsIndicies[b] ] ) { + + DirString * valptr = boost::any_cast < DirString * >( itsVariables.at( b ) ); + + int seldex= comboBox->getSelectedIndex(); + valptr->setDir( comboBox->getValue( seldex ) ); + vector< SmartUtil::tstring > choices = valptr->genNearDirs(); + + comboBox->removeAllItems(); + for ( unsigned int i = 0; i < choices.size(); i++ ) { + comboBox->addValue( choices[ i ] ); + } + comboBox->setSelectedIndex( 0 ); // + return; + } + } + } + } + + + + // A start at converting the absolute path to a relative path. // unimplemented- void ChangeAbsToRelative( SmartUtil::tstring filePath ) { - char current[MAX_PATH + 1]; + TCHAR current[MAX_PATH + 1]; if ( GetCurrentDirectory( MAX_PATH, current ) ) { @@ -511,37 +600,58 @@ // Establish the overall size of the dialog // based on the calculated size of each row. + // void setDialogBounds() { Point titleSize = getTextSize( itsTitle ); if ( itsTitle.size() < 4 ) { - titleSize = getTextSize( "yT-^" ); // A min size with descenders and a high symbol. + titleSize = getTextSize( _T("yT-^") ); // A min size with descenders and a high symbol. } + titleSize.x += 24; // Space for close icon titleSize += itsExtraAroundText; + maxLabel += itsExtraAroundText; + maxInputArea += itsExtraAroundText; Point cellDim( maxInputArea ); - cellDim.maxOf( maxLabel ); - cellDim += itsExtraAroundText; Point size; - size.x = ( 2 * cellDim.x ) + ( 3 * itsBorder.x ); // bb ppp bb iii bb + size.x = maxLabel.x + cellDim.x + ( 3 * itsBorder.x ); // bb ppp bb iii bb if ( titleSize.x > size.x ) size.x = titleSize.x; int rows = rows_needed(); size.y = titleSize.y + ( cellDim.y * rows ) + ( itsBorder.y * ( 1 + rows ) ); // Ensure that it fits on the screen. + stringstream ss; Point deskSize = getDesktopSize(); - Point position = getPosition(); - if ( size.x > deskSize.x ) size.x = deskSize.x; + Point position = getScreenPosition(); + // Not larger than the screen + if ( size.x > deskSize.x ) size.x = deskSize.x; if ( size.y > deskSize.y ) size.y = deskSize.y; + // Not positioned so it goes off the screen if ( position.x + size.x > deskSize.x ) position.x = deskSize.x - size.x; if ( position.y + size.y > deskSize.y ) position.y = deskSize.y - size.y; setBounds( position, size ); } + + // pos_size holds the sizes assuming that each column should be 50%. + // But we want to adjust this by the actual ratio of the maximum xs. + // + void adjustSizesByRatio( SmartWin::Rectangle & pos_size, + SmartWin::Rectangle & pos_sizeLabel, SmartWin::Rectangle & pos_sizeInput ) + { + float fract = maxLabel.x / (float)(maxLabel.x + maxInputArea.x); + int rowWidth= 2 * pos_size.size.x; + pos_sizeLabel= pos_size; + pos_sizeLabel.size.x= rowWidth * fract; + + pos_sizeInput= pos_size; + pos_sizeInput.size.x= rowWidth * (1.0 - fract); + } + // Allocate space for each widget in the dialog // Given the size of the dialog, allocate each row // @@ -551,45 +661,49 @@ itsPlace.setBoundsBorders( getClientAreaSize(), itsBorder.x, itsBorder.y ); - SmartWin::Rectangle pos_size; + // maxLabel.x + SmartWin::Rectangle pos_size, pos_sizeLabel, pos_sizeInput; itsPlace.sizeOfCell( rows_needed(), 2, pos_size.size ); + adjustSizesByRatio( pos_size, pos_sizeLabel, pos_sizeInput ); for ( unsigned int b = 0; b < itsVariables.size(); b++ ) { - itsPlace.positionToRight( pos_size ); - itsStatics.at( b )->setBounds( pos_size ); + itsPlace.positionToRight( pos_sizeLabel ); + itsStatics.at( b )->setBounds( pos_sizeLabel ); - itsPlace.positionToRight( pos_size ); + itsPlace.positionToRight( pos_sizeInput ); if ( itsVariables.at( b ).type() == typeid( bool * ) ) { - itsChecks.at( itsIndicies[b] )->setBounds( pos_size ); + itsChecks.at( itsIndicies[b] )->setBounds( pos_sizeInput ); } else if ( itsVariables.at( b ).type() == typeid( SYSTEMTIME * ) ) { - itsDates.at( itsIndicies[b] )->setBounds( pos_size ); + itsDates.at( itsIndicies[b] )->setBounds( pos_sizeInput ); } else - if ( itsVariables.at( b ).type() == typeid( ChoiceString * ) ) + if ( ( itsVariables.at( b ).type() == typeid( ChoiceString * ) ) || + ( itsVariables.at( b ).type() == typeid( DirString * ) ) + ) { - itsCombos[ itsIndicies[b] ]->setBounds( pos_size.pos, - Point( pos_size.size.x, pos_size.size.y * 5 ) ); + itsCombos[ itsIndicies[b] ]->setBounds( pos_sizeInput.pos, + Point( pos_sizeInput.size.x, pos_sizeInput.size.y * 5 ) ); } else { // All other types just have a text box. - itsBoxes[ itsIndicies[b] ]->setBounds( pos_size ); + itsBoxes[ itsIndicies[b] ]->setBounds( pos_sizeInput ); } } - itsPlace.positionToRight( pos_size ); - itsCancelBut->setBounds( pos_size ); + itsPlace.positionToRight( pos_sizeLabel ); + itsCancelBut->setBounds( pos_sizeLabel ); - itsPlace.positionToRight( pos_size ); - itsOkBut->setBounds( pos_size ); + itsPlace.positionToRight( pos_sizeInput ); + itsOkBut->setBounds( pos_sizeInput ); } // Convert numeric strings to a number. @@ -600,13 +714,13 @@ template< class numtype > bool getNumericFromString( const SmartUtil::tstring & inStr, numtype & val ) { - stringstream ss( inStr ); + SmartUtil::tstringstream ss( inStr ); val = 1; ss >> val; if ( 1 != val ) return true; // val = 2; - stringstream ss2( inStr ); + SmartUtil::tstringstream ss2( inStr ); ss2 >> val; return( 2 != val ); } @@ -689,7 +803,7 @@ } else { - stringstream ss; + SmartUtil::tstringstream ss; ss << itsBoxes[ itsIndicies[b] ]->getText(); ss << _T( " is not between " ); ss << valptr->itsMinval << _T( " and " ) << valptr->itsMaxval; @@ -715,7 +829,7 @@ { if ( str.size() != valptr->itsKnownLength ) { - stringstream ss; // Complain that the length was not correct. + SmartUtil::tstringstream ss; // Complain that the length was not correct. ss << _T( "Should be exactly " ) << valptr->itsKnownLength << " characters long."; createMessageBox().show( ss.str(), itsPrompts[b] ); itsBoxes[ itsIndicies[b] ]->setFocus(); @@ -746,6 +860,13 @@ valptr->itsChoosenIndex = itsCombos[ itsIndicies[b] ]->getSelectedIndex(); } + // DirString * + if ( itsVariables.at( b ).type() == typeid( DirString * ) ) + { + DirString * valptr = boost::any_cast < DirString * >( itsVariables.at( b ) ); + valptr->setDir( itsCombos[ itsIndicies[b] ]->getSelectedValue() ); + } + // SYSTEMTIME if ( itsVariables.at( b ).type() == typeid( SYSTEMTIME * ) ) { @@ -786,6 +907,7 @@ // MEMBER VARIABLES SmartUtil::tstring itsTitle; + int itsX, itsY; FontPtr itsFont; bool setFont; @@ -800,7 +922,7 @@ vector< WidgetStaticPtr > itsStatics; // After InitDialog vector < WidgetRichTextBox * > itsBoxes; // For numbers and strings vector < WidgetCheckBox * > itsChecks; // For boolean - vector < WidgetComboBox * > itsCombos; // For ChoiceString + vector < WidgetComboBox * > itsCombos; // For ChoiceString and DirString vector < WidgetDateTimePicker * > itsDates; // For SYSTEMTIME map< int, COLORREF > itsColors; |