Refactoring FLabel::draw and FFileDialog::readDir
This commit is contained in:
parent
7eb6bfa587
commit
10275c0953
|
@ -1,3 +1,7 @@
|
||||||
|
2017-01-30 Markus Gans <guru.mail@muenster.de>
|
||||||
|
* Refactoring FLabel::draw
|
||||||
|
* Refactoring FFileDialog::readDir
|
||||||
|
|
||||||
2017-01-28 Markus Gans <guru.mail@muenster.de>
|
2017-01-28 Markus Gans <guru.mail@muenster.de>
|
||||||
* Refactoring FApplication::processKeyboardEvent
|
* Refactoring FApplication::processKeyboardEvent
|
||||||
* Shorter methods and a fix for recreating new windows
|
* Shorter methods and a fix for recreating new windows
|
||||||
|
|
140
examples/ui.cpp
140
examples/ui.cpp
|
@ -277,6 +277,10 @@ class MyDialog : public FDialog
|
||||||
void initStatusBar();
|
void initStatusBar();
|
||||||
void initStatusBarCallbacks();
|
void initStatusBarCallbacks();
|
||||||
void initWidgets();
|
void initWidgets();
|
||||||
|
void initFlatButtons();
|
||||||
|
void initToggleButtons();
|
||||||
|
void initButtons();
|
||||||
|
void initLabels();
|
||||||
void initWidgetsCallbacks();
|
void initWidgetsCallbacks();
|
||||||
void adjustSize();
|
void adjustSize();
|
||||||
|
|
||||||
|
@ -531,7 +535,7 @@ void MyDialog::initStatusBar()
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void MyDialog::initStatusBarCallbacks()
|
void MyDialog::initStatusBarCallbacks()
|
||||||
{
|
{
|
||||||
// Add some function callbacks
|
// Add statusbar function callbacks
|
||||||
|
|
||||||
key_F1->addCallback
|
key_F1->addCallback
|
||||||
(
|
(
|
||||||
|
@ -555,7 +559,40 @@ void MyDialog::initStatusBarCallbacks()
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void MyDialog::initWidgets()
|
void MyDialog::initWidgets()
|
||||||
{
|
{
|
||||||
|
// Flat buttons
|
||||||
|
initFlatButtons();
|
||||||
|
|
||||||
|
// Radio buttons and check boxes
|
||||||
|
initToggleButtons();
|
||||||
|
|
||||||
|
// A text input field
|
||||||
|
myLineEdit = new FLineEdit (this);
|
||||||
|
myLineEdit->setGeometry(22, 1, 10, 1);
|
||||||
|
myLineEdit->setLabelText (L"&Input");
|
||||||
|
myLineEdit->setStatusbarMessage ("Press Enter to set the title");
|
||||||
|
*myLineEdit << FString("EnTry").toLower();
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
|
initButtons();
|
||||||
|
|
||||||
|
// A multiple selection listbox
|
||||||
|
myList = new FListBox (this);
|
||||||
|
myList->setGeometry(38, 1, 14, 17);
|
||||||
|
myList->setText ("Items");
|
||||||
|
myList->setStatusbarMessage ("99 items in a list");
|
||||||
|
myList->setMultiSelection();
|
||||||
|
|
||||||
|
for (int z = 1; z < 100; z++)
|
||||||
|
myList->insert (FString() << z << L" placeholder");
|
||||||
|
|
||||||
|
// Text labels
|
||||||
|
initLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void MyDialog::initFlatButtons()
|
||||||
|
{
|
||||||
|
// Flat buttons
|
||||||
MyButton1 = new FButton (this);
|
MyButton1 = new FButton (this);
|
||||||
MyButton1->setGeometry(3, 3, 5, 1);
|
MyButton1->setGeometry(3, 3, 5, 1);
|
||||||
MyButton1->setText (L"&SIN");
|
MyButton1->setText (L"&SIN");
|
||||||
|
@ -579,6 +616,29 @@ void MyDialog::initWidgets()
|
||||||
MyButton3->setNoUnderline();
|
MyButton3->setNoUnderline();
|
||||||
MyButton3->setFlat();
|
MyButton3->setFlat();
|
||||||
|
|
||||||
|
// Add button callback functions
|
||||||
|
MyButton1->addCallback
|
||||||
|
(
|
||||||
|
"clicked",
|
||||||
|
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
|
||||||
|
);
|
||||||
|
|
||||||
|
MyButton2->addCallback
|
||||||
|
(
|
||||||
|
"clicked",
|
||||||
|
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
|
||||||
|
);
|
||||||
|
|
||||||
|
MyButton3->addCallback
|
||||||
|
(
|
||||||
|
"clicked",
|
||||||
|
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void MyDialog::initToggleButtons()
|
||||||
|
{
|
||||||
// Radio buttons in a group
|
// Radio buttons in a group
|
||||||
FButtonGroup* radioButtonGroup = new FButtonGroup ("Button", this);
|
FButtonGroup* radioButtonGroup = new FButtonGroup ("Button", this);
|
||||||
radioButtonGroup->setGeometry(3, 8, 14, 4);
|
radioButtonGroup->setGeometry(3, 8, 14, 4);
|
||||||
|
@ -607,14 +667,11 @@ void MyDialog::initWidgets()
|
||||||
check2->setGeometry(1, 2, 9, 1);
|
check2->setGeometry(1, 2, 9, 1);
|
||||||
check2->setChecked();
|
check2->setChecked();
|
||||||
check2->setNoUnderline();
|
check2->setNoUnderline();
|
||||||
|
}
|
||||||
|
|
||||||
// A text input field
|
//----------------------------------------------------------------------
|
||||||
myLineEdit = new FLineEdit (this);
|
void MyDialog::initButtons()
|
||||||
myLineEdit->setGeometry(22, 1, 10, 1);
|
{
|
||||||
myLineEdit->setLabelText (L"&Input");
|
|
||||||
myLineEdit->setStatusbarMessage ("Press Enter to set the title");
|
|
||||||
*myLineEdit << FString("EnTry").toLower();
|
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
MyButton4 = new FButton (this);
|
MyButton4 = new FButton (this);
|
||||||
MyButton4->setGeometry(20, 8, 12, 1);
|
MyButton4->setGeometry(20, 8, 12, 1);
|
||||||
|
@ -634,16 +691,30 @@ void MyDialog::initWidgets()
|
||||||
MyButton6->setStatusbarMessage ("Exit the program");
|
MyButton6->setStatusbarMessage ("Exit the program");
|
||||||
MyButton6->addAccelerator('x');
|
MyButton6->addAccelerator('x');
|
||||||
|
|
||||||
// A multiple selection listbox
|
// Add button callback functions
|
||||||
myList = new FListBox (this);
|
MyButton4->addCallback
|
||||||
myList->setGeometry(38, 1, 14, 17);
|
(
|
||||||
myList->setText ("Items");
|
"clicked",
|
||||||
myList->setStatusbarMessage ("99 items in a list");
|
F_METHOD_CALLBACK (this, &MyDialog::cb_input2buttonText),
|
||||||
myList->setMultiSelection();
|
static_cast<FWidget::data_ptr>(myLineEdit)
|
||||||
|
);
|
||||||
|
|
||||||
for (int z = 1; z < 100; z++)
|
MyButton5->addCallback
|
||||||
myList->insert (FString() << z << L" placeholder");
|
(
|
||||||
|
"clicked",
|
||||||
|
F_METHOD_CALLBACK (this, &MyDialog::cb_ProgressBar)
|
||||||
|
);
|
||||||
|
|
||||||
|
MyButton6->addCallback
|
||||||
|
(
|
||||||
|
"clicked",
|
||||||
|
F_METHOD_CALLBACK (this, &FApplication::cb_exitApp)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void MyDialog::initLabels()
|
||||||
|
{
|
||||||
// Text labels
|
// Text labels
|
||||||
FLabel* headline = new FLabel (this);
|
FLabel* headline = new FLabel (this);
|
||||||
headline->setGeometry(21, 3, 10, 1);
|
headline->setGeometry(21, 3, 10, 1);
|
||||||
|
@ -672,43 +743,6 @@ void MyDialog::initWidgetsCallbacks()
|
||||||
{
|
{
|
||||||
// Add some function callbacks
|
// Add some function callbacks
|
||||||
|
|
||||||
MyButton1->addCallback
|
|
||||||
(
|
|
||||||
"clicked",
|
|
||||||
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
|
|
||||||
);
|
|
||||||
|
|
||||||
MyButton2->addCallback
|
|
||||||
(
|
|
||||||
"clicked",
|
|
||||||
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
|
|
||||||
);
|
|
||||||
|
|
||||||
MyButton3->addCallback
|
|
||||||
(
|
|
||||||
"clicked",
|
|
||||||
F_METHOD_CALLBACK (this, &MyDialog::cb_noFunctionMsg)
|
|
||||||
);
|
|
||||||
|
|
||||||
MyButton4->addCallback
|
|
||||||
(
|
|
||||||
"clicked",
|
|
||||||
F_METHOD_CALLBACK (this, &MyDialog::cb_input2buttonText),
|
|
||||||
static_cast<FWidget::data_ptr>(myLineEdit)
|
|
||||||
);
|
|
||||||
|
|
||||||
MyButton5->addCallback
|
|
||||||
(
|
|
||||||
"clicked",
|
|
||||||
F_METHOD_CALLBACK (this, &MyDialog::cb_ProgressBar)
|
|
||||||
);
|
|
||||||
|
|
||||||
MyButton6->addCallback
|
|
||||||
(
|
|
||||||
"clicked",
|
|
||||||
F_METHOD_CALLBACK (this, &FApplication::cb_exitApp)
|
|
||||||
);
|
|
||||||
|
|
||||||
myLineEdit->addCallback
|
myLineEdit->addCallback
|
||||||
(
|
(
|
||||||
"activate", // e.g. on <Enter>
|
"activate", // e.g. on <Enter>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the Final Cut widget toolkit *
|
* This file is part of the Final Cut widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2014-2017 Markus Gans *
|
* Copyright 2014-2018 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* The Final Cut is free software; you can redistribute it and/or *
|
* The Final Cut is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU Lesser General Public License *
|
* modify it under the terms of the GNU Lesser General Public License *
|
||||||
|
@ -130,7 +130,6 @@ class FFileDialog : public FDialog
|
||||||
void onKeyPress (FKeyEvent*);
|
void onKeyPress (FKeyEvent*);
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
int readDir();
|
|
||||||
static const FString fileOpenChooser ( FWidget*
|
static const FString fileOpenChooser ( FWidget*
|
||||||
, const FString& = FString()
|
, const FString& = FString()
|
||||||
, const FString& = FString() );
|
, const FString& = FString() );
|
||||||
|
@ -166,6 +165,10 @@ class FFileDialog : public FDialog
|
||||||
void clear();
|
void clear();
|
||||||
int numOfDirs();
|
int numOfDirs();
|
||||||
void sortDir();
|
void sortDir();
|
||||||
|
int readDir();
|
||||||
|
void getEntry (struct dirent*);
|
||||||
|
void followSymLink (dir_entry&);
|
||||||
|
void dirEntriesToList();
|
||||||
int changeDir (const FString&);
|
int changeDir (const FString&);
|
||||||
void printPath (const FString&);
|
void printPath (const FString&);
|
||||||
static const FString getHomeDir();
|
static const FString getHomeDir();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the Final Cut widget toolkit *
|
* This file is part of the Final Cut widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2014-2017 Markus Gans *
|
* Copyright 2014-2018 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* The Final Cut is free software; you can redistribute it and/or *
|
* The Final Cut is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU Lesser General Public License *
|
* modify it under the terms of the GNU Lesser General Public License *
|
||||||
|
@ -141,8 +141,10 @@ class FLabel : public FWidget
|
||||||
int getHotkeyPos (wchar_t[], wchar_t[], uInt);
|
int getHotkeyPos (wchar_t[], wchar_t[], uInt);
|
||||||
void setHotkeyAccelerator();
|
void setHotkeyAccelerator();
|
||||||
int getAlignOffset (int);
|
int getAlignOffset (int);
|
||||||
void printLine (wchar_t[], uInt, int, int = 0);
|
|
||||||
void draw();
|
void draw();
|
||||||
|
void drawMultiLine();
|
||||||
|
void drawSingleLine();
|
||||||
|
void printLine (wchar_t[], uInt, int, int = 0);
|
||||||
|
|
||||||
// Data Members
|
// Data Members
|
||||||
FStringList multiline_text;
|
FStringList multiline_text;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the Final Cut widget toolkit *
|
* This file is part of the Final Cut widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2014-2017 Markus Gans *
|
* Copyright 2014-2018 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* The Final Cut is free software; you can redistribute it and/or *
|
* The Final Cut is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU Lesser General Public License *
|
* modify it under the terms of the GNU Lesser General Public License *
|
||||||
|
@ -254,136 +254,6 @@ void FFileDialog::onKeyPress (FKeyEvent* ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
int FFileDialog::readDir()
|
|
||||||
{
|
|
||||||
const char* const dir = directory.c_str();
|
|
||||||
const char* const filter = filter_pattern.c_str();
|
|
||||||
directory_stream = opendir(dir);
|
|
||||||
|
|
||||||
if ( ! directory_stream )
|
|
||||||
{
|
|
||||||
FMessageBox::error (this, "Can't open directory\n" + directory);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear();
|
|
||||||
|
|
||||||
while ( true )
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
struct dirent* next = readdir(directory_stream);
|
|
||||||
|
|
||||||
if ( next )
|
|
||||||
{
|
|
||||||
if ( next->d_name[0] == '.' && next->d_name[1] == '\0' )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( ! show_hidden
|
|
||||||
&& next->d_name[0] == '.'
|
|
||||||
&& next->d_name[1] != '\0'
|
|
||||||
&& next->d_name[1] != '.' )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( dir[0] == '/' && dir[1] == '\0'
|
|
||||||
&& std::strcmp(next->d_name, "..") == 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dir_entry entry;
|
|
||||||
entry.name = strdup(next->d_name);
|
|
||||||
|
|
||||||
#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
|
|
||||||
entry.fifo = (next->d_type & DT_FIFO) == DT_FIFO;
|
|
||||||
entry.character_device = (next->d_type & DT_CHR ) == DT_CHR;
|
|
||||||
entry.directory = (next->d_type & DT_DIR ) == DT_DIR;
|
|
||||||
entry.block_device = (next->d_type & DT_BLK ) == DT_BLK;
|
|
||||||
entry.regular_file = (next->d_type & DT_REG ) == DT_REG;
|
|
||||||
entry.symbolic_link = (next->d_type & DT_LNK ) == DT_LNK;
|
|
||||||
entry.socket = (next->d_type & DT_SOCK) == DT_SOCK;
|
|
||||||
#else
|
|
||||||
struct stat s;
|
|
||||||
stat (entry.name, &s);
|
|
||||||
entry.fifo = S_ISFIFO (s.st_mode);
|
|
||||||
entry.character_device = S_ISCHR (s.st_mode);
|
|
||||||
entry.directory = S_ISDIR (s.st_mode);
|
|
||||||
entry.block_device = S_ISBLK (s.st_mode);
|
|
||||||
entry.regular_file = S_ISREG (s.st_mode);
|
|
||||||
entry.symbolic_link = S_ISLNK (s.st_mode);
|
|
||||||
entry.socket = S_ISSOCK (s.st_mode);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( entry.symbolic_link ) // symbolic link
|
|
||||||
{
|
|
||||||
char resolved_path[MAXPATHLEN] = {};
|
|
||||||
char symLink[MAXPATHLEN] = {};
|
|
||||||
std::strncpy (symLink, dir, sizeof(symLink) - 1);
|
|
||||||
std::strncat ( symLink
|
|
||||||
, next->d_name
|
|
||||||
, sizeof(symLink) - std::strlen(symLink) - 1);
|
|
||||||
|
|
||||||
if ( realpath(symLink, resolved_path) != 0 ) // follow link
|
|
||||||
{
|
|
||||||
struct stat sb;
|
|
||||||
|
|
||||||
if ( lstat(resolved_path, &sb) == 0 )
|
|
||||||
{
|
|
||||||
if ( S_ISDIR(sb.st_mode) )
|
|
||||||
entry.directory = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( entry.directory )
|
|
||||||
dir_entries.push_back (entry);
|
|
||||||
else if ( pattern_match(filter, entry.name) )
|
|
||||||
dir_entries.push_back (entry);
|
|
||||||
else
|
|
||||||
std::free(entry.name);
|
|
||||||
}
|
|
||||||
else if ( errno != 0 )
|
|
||||||
{
|
|
||||||
FMessageBox::error (this, "Reading directory\n" + directory);
|
|
||||||
|
|
||||||
if ( errno == EOVERFLOW ) // Value too large to be stored in data type
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
} // end while
|
|
||||||
|
|
||||||
if ( closedir(directory_stream) != 0 )
|
|
||||||
{
|
|
||||||
FMessageBox::error (this, "Closing directory\n" + directory);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
sortDir();
|
|
||||||
|
|
||||||
// fill list with directory entries
|
|
||||||
filebrowser->clear();
|
|
||||||
|
|
||||||
if ( ! dir_entries.empty() )
|
|
||||||
{
|
|
||||||
std::vector<dir_entry>::const_iterator iter, last;
|
|
||||||
iter = dir_entries.begin();
|
|
||||||
last = dir_entries.end();
|
|
||||||
|
|
||||||
while ( iter != last )
|
|
||||||
{
|
|
||||||
if ( (*iter).directory )
|
|
||||||
filebrowser->insert(FString((*iter).name), fc::SquareBrackets);
|
|
||||||
else
|
|
||||||
filebrowser->insert(FString((*iter).name));
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
const FString FFileDialog::fileOpenChooser ( FWidget* parent
|
const FString FFileDialog::fileOpenChooser ( FWidget* parent
|
||||||
, const FString& dirname
|
, const FString& dirname
|
||||||
|
@ -701,6 +571,159 @@ void FFileDialog::sortDir()
|
||||||
, sortByName );
|
, sortByName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
int FFileDialog::readDir()
|
||||||
|
{
|
||||||
|
const char* const dir = directory.c_str();
|
||||||
|
directory_stream = opendir(dir);
|
||||||
|
|
||||||
|
if ( ! directory_stream )
|
||||||
|
{
|
||||||
|
FMessageBox::error (this, "Can't open directory\n" + directory);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear();
|
||||||
|
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
struct dirent* next = readdir(directory_stream);
|
||||||
|
|
||||||
|
if ( next )
|
||||||
|
{
|
||||||
|
// Continue if name = "." (current directory)
|
||||||
|
if ( next->d_name[0] == '.' && next->d_name[1] == '\0' )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Skip hidden entries
|
||||||
|
if ( ! show_hidden
|
||||||
|
&& next->d_name[0] == '.'
|
||||||
|
&& next->d_name[1] != '\0'
|
||||||
|
&& next->d_name[1] != '.' )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Skip ".." for the root directory
|
||||||
|
if ( dir[0] == '/' && dir[1] == '\0'
|
||||||
|
&& std::strcmp(next->d_name, "..") == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
getEntry(next);
|
||||||
|
}
|
||||||
|
else if ( errno != 0 )
|
||||||
|
{
|
||||||
|
FMessageBox::error (this, "Reading directory\n" + directory);
|
||||||
|
|
||||||
|
if ( errno == EOVERFLOW ) // Value too large to be stored in data type
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
} // end while
|
||||||
|
|
||||||
|
if ( closedir(directory_stream) != 0 )
|
||||||
|
{
|
||||||
|
FMessageBox::error (this, "Closing directory\n" + directory);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
sortDir();
|
||||||
|
|
||||||
|
// Insert directory entries into the list
|
||||||
|
dirEntriesToList();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FFileDialog::getEntry (struct dirent* d_entry)
|
||||||
|
{
|
||||||
|
const char* const filter = filter_pattern.c_str();
|
||||||
|
dir_entry entry;
|
||||||
|
|
||||||
|
entry.name = strdup(d_entry->d_name);
|
||||||
|
|
||||||
|
#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
|
||||||
|
entry.fifo = (d_entry->d_type & DT_FIFO) == DT_FIFO;
|
||||||
|
entry.character_device = (d_entry->d_type & DT_CHR ) == DT_CHR;
|
||||||
|
entry.directory = (d_entry->d_type & DT_DIR ) == DT_DIR;
|
||||||
|
entry.block_device = (d_entry->d_type & DT_BLK ) == DT_BLK;
|
||||||
|
entry.regular_file = (d_entry->d_type & DT_REG ) == DT_REG;
|
||||||
|
entry.symbolic_link = (d_entry->d_type & DT_LNK ) == DT_LNK;
|
||||||
|
entry.socket = (d_entry->d_type & DT_SOCK) == DT_SOCK;
|
||||||
|
#else
|
||||||
|
struct stat s;
|
||||||
|
stat (entry.name, &s);
|
||||||
|
entry.fifo = S_ISFIFO (s.st_mode);
|
||||||
|
entry.character_device = S_ISCHR (s.st_mode);
|
||||||
|
entry.directory = S_ISDIR (s.st_mode);
|
||||||
|
entry.block_device = S_ISBLK (s.st_mode);
|
||||||
|
entry.regular_file = S_ISREG (s.st_mode);
|
||||||
|
entry.symbolic_link = S_ISLNK (s.st_mode);
|
||||||
|
entry.socket = S_ISSOCK (s.st_mode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
followSymLink(entry);
|
||||||
|
|
||||||
|
if ( entry.directory )
|
||||||
|
dir_entries.push_back (entry);
|
||||||
|
else if ( pattern_match(filter, entry.name) )
|
||||||
|
dir_entries.push_back (entry);
|
||||||
|
else
|
||||||
|
std::free(entry.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FFileDialog::followSymLink (dir_entry& entry)
|
||||||
|
{
|
||||||
|
if ( ! entry.symbolic_link )
|
||||||
|
return; // No symbolic link
|
||||||
|
|
||||||
|
char resolved_path[MAXPATHLEN] = {};
|
||||||
|
char symLink[MAXPATHLEN] = {};
|
||||||
|
struct stat sb;
|
||||||
|
const char* const dir = directory.c_str();
|
||||||
|
|
||||||
|
std::strncpy (symLink, dir, sizeof(symLink) - 1);
|
||||||
|
std::strncat ( symLink
|
||||||
|
, entry.name
|
||||||
|
, sizeof(symLink) - std::strlen(symLink) - 1);
|
||||||
|
|
||||||
|
if ( realpath(symLink, resolved_path) == 0 )
|
||||||
|
return; // Cannot follow the symlink
|
||||||
|
|
||||||
|
if ( lstat(resolved_path, &sb) == -1 )
|
||||||
|
return; // Cannot get file status
|
||||||
|
|
||||||
|
if ( S_ISDIR(sb.st_mode) )
|
||||||
|
entry.directory = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FFileDialog::dirEntriesToList()
|
||||||
|
{
|
||||||
|
// Fill list with directory entries
|
||||||
|
|
||||||
|
filebrowser->clear();
|
||||||
|
|
||||||
|
if ( dir_entries.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<dir_entry>::const_iterator iter, last;
|
||||||
|
iter = dir_entries.begin();
|
||||||
|
last = dir_entries.end();
|
||||||
|
|
||||||
|
while ( iter != last )
|
||||||
|
{
|
||||||
|
if ( (*iter).directory )
|
||||||
|
filebrowser->insert(FString((*iter).name), fc::SquareBrackets);
|
||||||
|
else
|
||||||
|
filebrowser->insert(FString((*iter).name));
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
int FFileDialog::changeDir (const FString& dirname)
|
int FFileDialog::changeDir (const FString& dirname)
|
||||||
{
|
{
|
||||||
|
|
216
src/flabel.cpp
216
src/flabel.cpp
|
@ -3,7 +3,7 @@
|
||||||
* *
|
* *
|
||||||
* This file is part of the Final Cut widget toolkit *
|
* This file is part of the Final Cut widget toolkit *
|
||||||
* *
|
* *
|
||||||
* Copyright 2014-2017 Markus Gans *
|
* Copyright 2014-2018 Markus Gans *
|
||||||
* *
|
* *
|
||||||
* The Final Cut is free software; you can redistribute it and/or *
|
* The Final Cut is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU Lesser General Public License *
|
* modify it under the terms of the GNU Lesser General Public License *
|
||||||
|
@ -486,6 +486,117 @@ int FLabel::getAlignOffset (int length)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FLabel::draw()
|
||||||
|
{
|
||||||
|
if ( isMonochron() )
|
||||||
|
{
|
||||||
|
setReverse(true);
|
||||||
|
|
||||||
|
if ( hasEmphasis() )
|
||||||
|
setBold(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( hasEmphasis() )
|
||||||
|
setColor (emphasis_color, getBackgroundColor());
|
||||||
|
else
|
||||||
|
setColor();
|
||||||
|
|
||||||
|
// Draw the text
|
||||||
|
if ( multiline && getHeight() >= 2 )
|
||||||
|
drawMultiLine();
|
||||||
|
else
|
||||||
|
drawSingleLine();
|
||||||
|
|
||||||
|
if ( isMonochron() )
|
||||||
|
{
|
||||||
|
setReverse(false);
|
||||||
|
|
||||||
|
if ( hasEmphasis() )
|
||||||
|
setBold(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FLabel::drawMultiLine()
|
||||||
|
{
|
||||||
|
uInt y = 0;
|
||||||
|
uInt text_lines = uInt(multiline_text.size());
|
||||||
|
|
||||||
|
|
||||||
|
while ( y < text_lines && y < uInt(getHeight()) )
|
||||||
|
{
|
||||||
|
wchar_t* label_text;
|
||||||
|
bool hotkey_printed = false;
|
||||||
|
int align_offset, hotkeypos = -1;
|
||||||
|
uInt length = multiline_text[y].getLength();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
label_text = new wchar_t[length + 1]();
|
||||||
|
}
|
||||||
|
catch (const std::bad_alloc& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t* src = const_cast<wchar_t*>(multiline_text[y].wc_str());
|
||||||
|
wchar_t* dest = const_cast<wchar_t*>(label_text);
|
||||||
|
|
||||||
|
if ( ! hotkey_printed )
|
||||||
|
hotkeypos = getHotkeyPos(src, dest, length);
|
||||||
|
else
|
||||||
|
std::wcsncpy(dest, src, length);
|
||||||
|
|
||||||
|
setPrintPos (1, 1 + int(y));
|
||||||
|
|
||||||
|
if ( hotkeypos != -1 )
|
||||||
|
{
|
||||||
|
align_offset = getAlignOffset (int(length - 1));
|
||||||
|
printLine (label_text, length - 1, hotkeypos, align_offset);
|
||||||
|
hotkey_printed = true;
|
||||||
|
hotkeypos = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
align_offset = getAlignOffset (int(length));
|
||||||
|
printLine (label_text, length, -1, align_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
y++;
|
||||||
|
delete[] label_text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
void FLabel::drawSingleLine()
|
||||||
|
{
|
||||||
|
wchar_t* label_text;
|
||||||
|
int hotkeypos = -1, align_offset;
|
||||||
|
uInt length = text.getLength();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
label_text = new wchar_t[length + 1]();
|
||||||
|
}
|
||||||
|
catch (const std::bad_alloc& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hotkeypos = getHotkeyPos (text.wc_str(), label_text, length);
|
||||||
|
|
||||||
|
if ( hotkeypos != -1 )
|
||||||
|
length--;
|
||||||
|
|
||||||
|
setPrintPos (1,1);
|
||||||
|
align_offset = getAlignOffset (int(length));
|
||||||
|
printLine (label_text, length, hotkeypos, align_offset);
|
||||||
|
delete[] label_text;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
void FLabel::printLine ( wchar_t line[]
|
void FLabel::printLine ( wchar_t line[]
|
||||||
, uInt length
|
, uInt length
|
||||||
|
@ -557,106 +668,3 @@ void FLabel::printLine ( wchar_t line[]
|
||||||
if ( hasReverseMode() )
|
if ( hasReverseMode() )
|
||||||
setReverse(false);
|
setReverse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
void FLabel::draw()
|
|
||||||
{
|
|
||||||
wchar_t* label_text;
|
|
||||||
uInt length;
|
|
||||||
int hotkeypos, align_offset;
|
|
||||||
|
|
||||||
if ( isMonochron() )
|
|
||||||
{
|
|
||||||
setReverse(true);
|
|
||||||
|
|
||||||
if ( hasEmphasis() )
|
|
||||||
setBold(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( hasEmphasis() )
|
|
||||||
setColor (emphasis_color, getBackgroundColor());
|
|
||||||
else
|
|
||||||
setColor();
|
|
||||||
|
|
||||||
hotkeypos = -1;
|
|
||||||
|
|
||||||
if ( multiline && getHeight() >= 2 )
|
|
||||||
{
|
|
||||||
uInt y = 0;
|
|
||||||
uInt text_lines = uInt(multiline_text.size());
|
|
||||||
bool hotkey_printed = false;
|
|
||||||
|
|
||||||
while ( y < text_lines && y < uInt(getHeight()) )
|
|
||||||
{
|
|
||||||
length = multiline_text[y].getLength();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
label_text = new wchar_t[length + 1]();
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc& ex)
|
|
||||||
{
|
|
||||||
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wchar_t* src = const_cast<wchar_t*>(multiline_text[y].wc_str());
|
|
||||||
wchar_t* dest = const_cast<wchar_t*>(label_text);
|
|
||||||
|
|
||||||
if ( ! hotkey_printed )
|
|
||||||
hotkeypos = getHotkeyPos(src, dest, length);
|
|
||||||
else
|
|
||||||
std::wcsncpy(dest, src, length);
|
|
||||||
|
|
||||||
setPrintPos (1, 1 + int(y));
|
|
||||||
|
|
||||||
if ( hotkeypos != -1 )
|
|
||||||
{
|
|
||||||
align_offset = getAlignOffset (int(length - 1));
|
|
||||||
printLine (label_text, length - 1, hotkeypos, align_offset);
|
|
||||||
hotkey_printed = true;
|
|
||||||
hotkeypos = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
align_offset = getAlignOffset (int(length));
|
|
||||||
printLine (label_text, length, -1, align_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
y++;
|
|
||||||
delete[] label_text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = text.getLength();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
label_text = new wchar_t[length + 1]();
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc& ex)
|
|
||||||
{
|
|
||||||
std::cerr << "not enough memory to alloc " << ex.what() << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hotkeypos = getHotkeyPos (text.wc_str(), label_text, length);
|
|
||||||
|
|
||||||
if ( hotkeypos != -1 )
|
|
||||||
length--;
|
|
||||||
|
|
||||||
setPrintPos (1,1);
|
|
||||||
align_offset = getAlignOffset (int(length));
|
|
||||||
printLine (label_text, length, hotkeypos, align_offset);
|
|
||||||
delete[] label_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isMonochron() )
|
|
||||||
{
|
|
||||||
setReverse(false);
|
|
||||||
|
|
||||||
if ( hasEmphasis() )
|
|
||||||
setBold(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue