Browse Source

Syntax improvements, and also add myself as a contributor in the LICENSE file.

master
Aitor 1 month ago
parent
commit
28c9970f47
29 changed files with 2061 additions and 1554 deletions
  1. +1
    -0
      LICENSE
  2. +20
    -0
      hopman-1.0/CMakeLists.txt
  3. +1
    -0
      hopman-1.0/LICENSE
  4. +20
    -0
      hopman-1.0/gtkmm/CMakeLists.txt
  5. +77
    -53
      hopman-1.0/gtkmm/annex.cpp
  6. +45
    -20
      hopman-1.0/gtkmm/annex.h
  7. +26
    -6
      hopman-1.0/gtkmm/blk_model.cpp
  8. +31
    -9
      hopman-1.0/gtkmm/blk_model.h
  9. +104
    -73
      hopman-1.0/gtkmm/blk_node.cpp
  10. +78
    -51
      hopman-1.0/gtkmm/blk_node.h
  11. +434
    -394
      hopman-1.0/gtkmm/blk_tree.cpp
  12. +120
    -102
      hopman-1.0/gtkmm/blk_tree.h
  13. +22
    -1
      hopman-1.0/gtkmm/buttonbox.cpp
  14. +25
    -4
      hopman-1.0/gtkmm/buttonbox.h
  15. +4
    -4
      hopman-1.0/gtkmm/cli.cpp
  16. +4
    -4
      hopman-1.0/gtkmm/cli.h
  17. +80
    -96
      hopman-1.0/gtkmm/eject_dialog.cpp
  18. +37
    -16
      hopman-1.0/gtkmm/eject_dialog.h
  19. +46
    -28
      hopman-1.0/gtkmm/fpipe.cpp
  20. +27
    -3
      hopman-1.0/gtkmm/fpipe.h
  21. +74
    -55
      hopman-1.0/gtkmm/hopman_ui.cpp
  22. +41
    -14
      hopman-1.0/gtkmm/hopman_ui.h
  23. +91
    -69
      hopman-1.0/gtkmm/menu.cpp
  24. +43
    -41
      hopman-1.0/gtkmm/svr.cpp
  25. +22
    -17
      hopman-1.0/gtkmm/svr.h
  26. +398
    -332
      hopman-1.0/gtkmm/worker.cpp
  27. +124
    -95
      hopman-1.0/main.cpp
  28. +46
    -67
      hopman-1.0/suid.cpp
  29. +20
    -0
      hopman-1.0/watch/CMakeLists.txt

+ 1
- 0
LICENSE View File

@@ -1,5 +1,6 @@

Copyright (C) 2019 Didier Kryn <kryn@in2p3.fr>
Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that


+ 20
- 0
hopman-1.0/CMakeLists.txt View File

@@ -1,3 +1,23 @@
#
# CMakeLists.txt
# Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# See the LICENSE file.#
#

cmake_minimum_required(VERSION 3.0.2-1)

project(hopman)


+ 1
- 0
hopman-1.0/LICENSE View File

@@ -1,5 +1,6 @@

Copyright (C) 2019 Didier Kryn <kryn@in2p3.fr>
Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that


+ 20
- 0
hopman-1.0/gtkmm/CMakeLists.txt View File

@@ -1,3 +1,23 @@
#
# CMakeLists.txt
# Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# See the LICENSE file.#
#

# headers:
FILE(GLOB_RECURSE HEADER_GTK_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.h")



+ 77
- 53
hopman-1.0/gtkmm/annex.cpp View File

@@ -1,4 +1,24 @@

/*
* annex.cpp
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/
#include <unistd.h>
#include <cstdio>

@@ -10,82 +30,86 @@

namespace Hopman
{

Annex::Annex(int argc, char **argv, int x, int y)
{
for(int i=0; i<argc; i++)
args.push_back(std::string(argv[i]));
for(int i=0; i<argc; i++)
args.push_back(string(argv[i]));
pid_t pid = getpid();
char *c = NULL;
if (asprintf(&c, "%jd", (intmax_t) pid) != -1) {
mypid = std::string(c);
free(c); // cleanup when done.
} else
std::cerr << "Unable to get the pid " << std::endl;
pid_t pid = getpid();
char *c = NULL;
if (asprintf(&c, "%jd", (intmax_t) pid) != -1) {
mypid = string(c);
free(c); // cleanup when done.
} else
cerr << "Unable to get the pid\n";
x_screen = x;
y_screen = y;
watch_dir = "/dev/";
socket = "/tmp/" + mypid + "_hopman.socket";
helper_socket = "/tmp/" + mypid + "_hopman_helper.socket";
get_current_path();
set_pixmaps();
set_path_to_the_helper();
x_screen = x;
y_screen = y;
watch_dir = "/dev/";
socket = "/tmp/" + mypid + "_hopman.socket";
helper_socket = "/tmp/" + mypid + "_hopman_helper.socket";
worker_socket = "/tmp/" + mypid + "_hopman_worker.socket";
get_current_path();
set_pixmaps();
set_path_to_the_helper();
}

Annex::~Annex()
{
std::remove( socket.c_str() );
std::remove( helper_socket.c_str() );
remove( socket.c_str() );
remove( helper_socket.c_str() );
remove( worker_socket.c_str() );
}
// If we launch the application clicking on the applet, the path will be defined in the .desktop file
// In our case Path=/dev
void Annex::get_current_path()
{
char current_working_dir[1024] = {0};
getcwd(current_working_dir, 1024);
current_path = std::string(current_working_dir);
char current_working_dir[1024] = {0};
getcwd(current_working_dir, 1024);
current_path = string(current_working_dir);
}

void Annex::set_pixmaps()
{
std::string str = "/usr/share/pixmaps/hopman.png";
Glib::RefPtr<Gio::File> ref_path = Gio::File::create_for_path( str );
if ( ref_path->query_exists() )
app_icon = str;
else
std::cerr << app_icon + " , not found! " << std::endl;
string str = "/usr/share/pixmaps/hopman.png";
Glib::RefPtr<Gio::File> ref_path = Gio::File::create_for_path( str );
if ( ref_path->query_exists() )
app_icon = str;
else
cerr << app_icon + " , not found!" << endl;
str = "/usr/share/hopman/icons/usb-eject-32x32.png";
ref_path = Gio::File::create_for_path( str );
if ( ref_path->query_exists() )
eject_icon = str;
else
std::cerr << eject_icon + " , not found! " << std::endl;
str = "/usr/share/hopman/icons/usb-eject-32x32.png";
ref_path = Gio::File::create_for_path( str );
if ( ref_path->query_exists() )
eject_icon = str;
else
cerr << eject_icon + " , not found!" << endl;
str = "/usr/share/hopman/icons/usb-ejected-32x32.png";
ref_path = Gio::File::create_for_path( str );
if ( ref_path->query_exists() )
ejected_icon = str;
else
std::cerr << ejected_icon + " , not found! " << std::endl;
str = "/usr/share/hopman/icons/usb-ejected-32x32.png";
ref_path = Gio::File::create_for_path( str );
if ( ref_path->query_exists() )
ejected_icon = str;
else
cerr << ejected_icon + " , not found!" << endl;
str = "/usr/share/hopman/icons/warning.png";
ref_path = Gio::File::create_for_path( str );
if ( ref_path->query_exists() )
warning_icon = str;
else
std::cerr << warning_icon + " , not found! " << std::endl;
str = "/usr/share/hopman/icons/warning.png";
ref_path = Gio::File::create_for_path( str );
if ( ref_path->query_exists() )
warning_icon = str;
else
cerr << warning_icon + " , not found!" << endl;
}

void Annex::set_path_to_the_helper()
{
std::string path = current_path + "/suid";
Glib::RefPtr<Gio::File> ref_path = Gio::File::create_for_path( path );
if ( ref_path->query_exists() )
path_to_the_helper = path;
else
std::cerr << "Helper not found! " << std::endl;
string path = current_path + "/suid";
Glib::RefPtr<Gio::File> ref_path = Gio::File::create_for_path( path );
if ( ref_path->query_exists() )
path_to_the_helper = path;
else
cerr << "Helper not found!" << endl;
}

} // namespace Hopman

+ 45
- 20
hopman-1.0/gtkmm/annex.h View File

@@ -1,3 +1,23 @@
/*
* annex.h
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/

#ifndef __ANNEX_H__
#define __ANNEX_H__
@@ -6,32 +26,37 @@
#include <vector>

namespace Hopman
{
{

using namespace std;
class Annex
{
public:
Annex(int, char**, int, int);
virtual ~Annex();
Annex(int, char**, int, int);
virtual ~Annex();
// TODO: make private using getters to access them
int x_screen, y_screen;
std::vector<std::string> args;
std::string mypid,
current_path,
path_to_the_helper,
watch_dir,
socket,
helper_socket,
app_icon,
eject_icon,
ejected_icon,
warning_icon;
// TODO: make private using getters to access them
int x_screen, y_screen;
vector<string> args;
string mypid,
current_path,
path_to_the_helper,
watch_dir,
socket,
helper_socket,
worker_socket,
app_icon,
eject_icon,
ejected_icon,
warning_icon;
private:
void get_current_path();
void set_pixmaps();
void set_path_to_the_helper();
};
void get_current_path();
void set_pixmaps();
void set_path_to_the_helper();
};
} // namespace Hopman

#endif // __ANNEX_H__

+ 26
- 6
hopman-1.0/gtkmm/blk_model.cpp View File

@@ -1,4 +1,23 @@

/*
* blk_model.cpp
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/

#include "blk_model.h"

@@ -6,15 +25,16 @@ namespace Hopman {
BlkModel::BlkModel()
{
add(device);
add(fstype);
add(size);
add(icon);
add(vendor);
add(device);
add(fstype);
add(size);
add(icon);
add(vendor);
}

BlkModel::~BlkModel()
{

}

} // namespace Hopman

+ 31
- 9
hopman-1.0/gtkmm/blk_model.h View File

@@ -1,24 +1,46 @@

/*
* blk_model.h
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/
#ifndef __BLK_MODEL_H__
#define __BLK_MODEL_H__


#include <gtkmm.h>

namespace Hopman {
using namespace std;

class BlkModel : public Gtk::TreeModel::ColumnRecord
{
public:
BlkModel();
virtual ~BlkModel();
BlkModel();
virtual ~BlkModel();
Gtk::TreeModelColumn<std::string> device;
Gtk::TreeModelColumn<std::string> fstype;
Gtk::TreeModelColumn<std::string> size;
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
Gtk::TreeModelColumn<std::string> vendor;
Gtk::TreeModelColumn<string> device;
Gtk::TreeModelColumn<string> fstype;
Gtk::TreeModelColumn<string> size;
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf>> icon;
Gtk::TreeModelColumn<string> vendor;
};

} // namespace Hopman

#endif // __BLK_MODEL_H__

+ 104
- 73
hopman-1.0/gtkmm/blk_node.cpp View File

@@ -1,3 +1,23 @@
/*
* blk_node.cpp
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/


#include "blk_node.h"

@@ -7,15 +27,15 @@ namespace Hopman {

BlkNode::BlkNode( struct vdev_usb_device device )
{
pathname=std::string( device.sysfs_path );
basename=getBaseName();
devname="/dev/" + basename; // It should be annex.watch_dir + basename
mtpt=std::string( device.mtpt_str );
vendor=std::string( device.vendor_str );
model=std::string( device.model_str );
devtype=std::string( device.devtype_str );
inode=std::string( device.inode_str );
size=std::string( device.size_str );
pathname=string( device.sysfs_path );
basename=getBaseName();
devname="/dev/" + basename; // It should be annex.watch_dir + basename
mtpt=string( device.mtpt_str );
vendor=string( device.vendor_str );
model=string( device.model_str );
devtype=string( device.devtype_str );
inode=string( device.inode_str );
size=string( device.size_str );
}

BlkNode::~BlkNode()
@@ -23,141 +43,152 @@ BlkNode::~BlkNode()

}

std::string BlkNode::getBaseName()
string BlkNode::getBaseName()
{
char sep = '/';
size_t i = pathname.rfind(sep, pathname.length());
if (i != string::npos) {
return(pathname.substr(i+1, pathname.length() - i));
}

return("");
}

string BlkNode::getDirName()
{
char sep = '/';
size_t i = pathname.rfind(sep, pathname.length());
if (i != std::string::npos) {
return(pathname.substr(i+1, pathname.length() - i));
}
size_t pos = 0;
string token;
string delimiter = "/";
while ((pos = pathname.find(delimiter)) != string::npos) {
token = pathname.substr(0, pos);
pathname.erase(0, pos + delimiter.length());
}

return("");
return token;
}

std::string BlkNode::getDirName()
bool BlkNode::get_removed()
{
size_t pos = 0;
std::string token;
std::string delimiter = "/";
while ((pos = pathname.find(delimiter)) != std::string::npos) {
token = pathname.substr(0, pos);
pathname.erase(0, pos + delimiter.length());
}
return this->removed;
}

return token;
bool BlkNode::get_removable()
{
return this->removable;
}

bool BlkNode::get_is_removed()
void BlkNode::set_removed(bool value)
{
return this->is_removed;
this->removed = value;
}

void BlkNode::set_is_removed(bool value)
void BlkNode::set_removable(bool value)
{
this->is_removed = value;
this->removable = value;
}

std::string BlkNode::get_inode()
string BlkNode::get_inode()
{
return this->inode;
return this->inode;
}

std::string BlkNode::get_devname()
string BlkNode::get_devname()
{
return this->devname;
return this->devname;
}

std::string BlkNode::get_basename()
string BlkNode::get_basename()
{
return this->basename;
return this->basename;
}

std::string BlkNode::get_pathname()
string BlkNode::get_pathname()
{
return this->pathname;
return this->pathname;
}

std::string BlkNode::get_dirname()
string BlkNode::get_dirname()
{
return this->dirname;
return this->dirname;
}

std::string BlkNode::get_vendor()
string BlkNode::get_vendor()
{
return this->vendor;
return this->vendor;
}

std::string BlkNode::get_model()
string BlkNode::get_model()
{
return this->model;
return this->model;
}

std::string BlkNode::get_devtype()
string BlkNode::get_devtype()
{
return this->devtype;
return this->devtype;
}

std::string BlkNode::get_size()
string BlkNode::get_size()
{
return this->size;
return this->size;
}

void BlkNode::set_size (std::string str)
void BlkNode::set_size (string str)
{
this->size=str;
this->size=str;
}

std::string BlkNode::get_label()
string BlkNode::get_label()
{
return this->label;
return this->label;
}

void BlkNode::set_label (std::string str)
void BlkNode::set_label (string str)
{
this->label=str;
this->label=str;
}

std::string BlkNode::get_fstype()
string BlkNode::get_fstype()
{
return this->fstype;
return this->fstype;
}

void BlkNode::set_fstype (std::string str)
void BlkNode::set_fstype (string str)
{
this->fstype=str;
this->fstype=str;
}

std::string BlkNode::get_uuid()
string BlkNode::get_uuid()
{
return this->uuid;
return this->uuid;
}

void BlkNode::set_uuid (std::string str)
void BlkNode::set_uuid (string str)
{
this->uuid=str;
this->uuid=str;
}

std::string BlkNode::get_partuuid()
string BlkNode::get_partuuid()
{
return this->partuuid;
return this->partuuid;
}

void BlkNode::set_partuuid (std::string str)
void BlkNode::set_partuuid (string str)
{
this->partuuid=str;
this->partuuid=str;
}

std::string BlkNode::get_mtpt()
string BlkNode::get_mtpt()
{
return this->mtpt;
return this->mtpt;
}

std::vector<std::string> BlkNode::get_children_mtpt_vector()
vector<string> BlkNode::get_children_mtpt_vector()
{
std::vector<std::string> v;
v.begin();
for(auto &u : children)
v.push_back(u->get_mtpt());
return v;
vector<string> v;
v.begin();
for(auto &u : children)
v.push_back(u->get_mtpt());
return v;
}

} // namespace Hopman

+ 78
- 51
hopman-1.0/gtkmm/blk_node.h View File

@@ -1,3 +1,24 @@
/*
* blk_node.h
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/


#ifndef __BLK_NODE_H__
#define __BLK_NODE_H__

@@ -6,67 +27,73 @@
#include <vector>

extern "C" {
#include <stat_usb.h>
}

namespace Hopman {

using namespace std;

class BlkNode
{
public:
BlkNode( struct vdev_usb_device );
virtual ~BlkNode();
std::weak_ptr<BlkNode> parent;
std::vector< std::shared_ptr<BlkNode> > children;
// TODO: make private (setters used by the worker thread)
void set_is_removed(bool);
void set_label(std::string);
void set_fstype(std::string);
void set_size(std::string);
void set_uuid(std::string);
void set_partuuid(std::string);
// Getters
bool get_is_removed();
std::string get_inode(),
get_size(),
get_devname(),
get_basename(),
get_dirname(),
get_pathname(),
get_label(),
get_vendor(),
get_model(),
get_mtpt(),
get_fstype(),
get_devtype(),
get_uuid(),
get_partuuid();
std::vector<std::string> get_children_mtpt_vector();
BlkNode( struct vdev_usb_device );
virtual ~BlkNode();

weak_ptr<BlkNode> parent;
vector< shared_ptr<BlkNode> > children;
// TODO: make private (setters used by the worker thread)
void set_removed(bool);
void set_removable(bool);
void set_label(string);
void set_fstype(string);
void set_size(string);
void set_uuid(string);
void set_partuuid(string);

// Getters
bool get_removed();
bool get_removable();
string get_inode(),
get_size(),
get_devname(),
get_basename(),
get_dirname(),
get_pathname(),
get_label(),
get_vendor(),
get_model(),
get_mtpt(),
get_fstype(),
get_devtype(),
get_uuid(),
get_partuuid();
vector<string> get_children_mtpt_vector();

private:
bool is_removed;
std::string devname,
basename,
pathname,
dirname,
label,
vendor,
model,
mtpt,
fstype,
devtype,
inode,
size,
uuid,
partuuid;
std::string getBaseName(),
getDirName();
bool removed, removable;
string devname,
basename,
pathname,
dirname,
label,
vendor,
model,
mtpt,
fstype,
devtype,
inode,
size,
uuid,
partuuid;
string getBaseName(),
getDirName();
};

} // namespace Hopman

#endif //__BLK_NODE_H__

+ 434
- 394
hopman-1.0/gtkmm/blk_tree.cpp View File

@@ -1,3 +1,23 @@
/*
* blk_tree.cpp
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/


#include "blk_tree.h"
#include "hopman_ui.h"
@@ -6,484 +26,504 @@
#include "svr.h"

namespace Hopman {
BlkTree::BlkTree(const Hopman::Annex& annex)
:
m_WorkerThread (nullptr),
display_menu (false),
m_shall_quit (true)
: m_WorkerThread (nullptr),
display_menu (false),
m_shall_quit (true)
{
m_tooltip_window = new Gtk::Window(Gtk::WINDOW_POPUP);
m_tooltip_window->set_default_size(0,0);
set_tooltip_window(*m_tooltip_window);
m_tooltip_window->add(m_Label);
m_tooltip_window->show_all_children();
get_selection()->set_mode( Gtk::SELECTION_SINGLE );
set_hover_selection (true);
set_sensitive (true);
property_has_tooltip();
m_tooltip_window = new Gtk::Window(Gtk::WINDOW_POPUP);
m_tooltip_window->set_default_size(0,0);
set_tooltip_window(*m_tooltip_window);
m_tooltip_window->add(m_Label);
m_tooltip_window->show_all_children();
get_selection()->set_mode( Gtk::SELECTION_SINGLE );
set_hover_selection (true);
set_sensitive (true);
property_has_tooltip();

add_events(Gdk::BUTTON_PRESS_MASK);
add_events(Gdk::BUTTON_PRESS_MASK);
#if GTK_MAJOR_VERSION == 3

set_activate_on_single_click( true );
set_activate_on_single_click( true );
#endif
set_headers_visible (false);
set_enable_tree_lines (true);
//set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_BOTH);
set_headers_visible (false);
set_enable_tree_lines (true);
//set_grid_lines(Gtk::TREE_VIEW_GRID_LINES_BOTH);
m_refTreeModel = Gtk::TreeStore::create( m_Columns );
set_model( m_refTreeModel );
m_refTreeModel = Gtk::TreeStore::create( m_Columns );
set_model( m_refTreeModel );
append_column( "DEVICE", m_Columns.device );
append_column( "FSTYPE", m_Columns.fstype );
append_column( "SIZE", m_Columns.size );
append_column( "ICON", m_Columns.icon );
append_column( "VENDOR", m_Columns.vendor );
m_Menu = new cMenu(this);
selected.clear();
append_column( "DEVICE", m_Columns.device );
append_column( "FSTYPE", m_Columns.fstype );
append_column( "SIZE", m_Columns.size );
append_column( "ICON", m_Columns.icon );
append_column( "VENDOR", m_Columns.vendor );
m_Menu = new cMenu(this);
selected.clear();

show_all_children();
signal_query_tooltip().connect
(
sigc::mem_fun(*this, &BlkTree::on_query_tooltip),
false
);
signal_button_press_event().connect
(
sigc::mem_fun(*this, &BlkTree::on_button_press_event),
false
);
m_Dispatcher.connect
(
sigc::bind<const Hopman::Annex&>
(
sigc::mem_fun(*this, &BlkTree::get_info_from_worker_thread),
annex
)
);
show_all_children();
signal_query_tooltip().connect
(
sigc::mem_fun(*this, &BlkTree::on_query_tooltip),
false
);
signal_button_press_event().connect
(
sigc::mem_fun(*this, &BlkTree::on_button_press_event),
false
);
m_Dispatcher.connect
(
sigc::bind<const Hopman::Annex&>
(
sigc::mem_fun(*this, &BlkTree::get_info_from_worker_thread),
annex
)
);
// Start a new worker thread.
if (!m_WorkerThread)
{
m_WorkerThread = new std::thread (
[ this, annex ]
{
m_Worker.do_work(this, annex);
}
);
}
set_can_default();
show_all_children();
grab_focus();
this->ejected_icon = annex.ejected_icon;
this->socket = annex.socket;
this->path_to_the_helper = annex.path_to_the_helper;
// Start a new worker thread.
if (!m_WorkerThread)
{
m_WorkerThread = new thread (
[ this, annex ]
{
m_Worker.do_work(this, annex);
}
);
}
set_can_default();
show_all_children();
grab_focus();
this->ejected_icon = annex.ejected_icon;
this->socket = annex.socket;
this->path_to_the_helper = annex.path_to_the_helper;
}

// Destructor
BlkTree::~BlkTree()
{
delete m_tooltip_window;
delete m_Menu;
// Order the worker thread to stop and wait for it to stop.
if (m_WorkerThread->joinable())
{
m_WorkerThread->detach();
m_Worker.stop_work();
if(m_WorkerThread) {
delete m_WorkerThread;
m_WorkerThread = nullptr;
}
}
// Purge the contents
pObj.clear();
delete m_tooltip_window;
delete m_Menu;
// Order the worker thread to stop and wait for it to stop.
if (m_WorkerThread->joinable())
{
m_WorkerThread->detach();
m_Worker.stop_work();
if(m_WorkerThread) {
delete m_WorkerThread;
m_WorkerThread = nullptr;
}
}
// Purge the contents
pObj.clear();

// Deallocate memory
pObj.shrink_to_fit();
// Deallocate memory
pObj.shrink_to_fit();
}

bool BlkTree::get_shall_quit()
{
return this->m_shall_quit;
return this->m_shall_quit;
}

std::string BlkTree::get_selected()
string BlkTree::get_selected()
{
return selected;
return selected;
}

void BlkTree::notify()
{
m_Dispatcher.emit();
m_Dispatcher.emit();
}

void BlkTree::get_info_from_worker_thread(const Hopman::Annex& annex)
{
Hopman::Hopman_Ui *parent = dynamic_cast<Hopman::Hopman_Ui*>(this->get_toplevel());
if (parent) {
parent->resize(20,20);
parent->m_Spinner.stop();
parent->m_Spinner.hide();
parent->m_Label.hide();
}
Hopman::Hopman_Ui *parent = dynamic_cast<Hopman::Hopman_Ui*>(this->get_toplevel());
if (parent) {
parent->resize(20,20);
parent->m_Spinner.stop();
parent->m_Spinner.hide();
parent->m_Label.hide();
}

pObj.clear();
pObj.begin();
m_Worker.get_data( pObj );
// No devices?
if(!pObj.size()) {
Gtk::MessageDialog dialog(*parent, "No devices found.");
dialog.run();
gtk_main_quit();
}
// Fill the tree
m_refTreeModel->clear();
Glib::RefPtr<Gdk::Pixbuf> warning_icon = Gdk::Pixbuf::create_from_file( annex.warning_icon );
Glib::RefPtr<Gdk::Pixbuf> ejected_icon = Gdk::Pixbuf::create_from_file( annex.ejected_icon );
Glib::RefPtr<Gdk::Pixbuf> eject_icon = Gdk::Pixbuf::create_from_file( annex.eject_icon );
for(auto &u : pObj) {
row = *(m_refTreeModel->append());
row[m_Columns.device] = " " + u->get_devname();
row[m_Columns.fstype] = " " + u->get_fstype();
std::string str = u->get_size();
if(!str.compare("0,00") || !str.compare("0.00")) str="?";
else str+=" G";
int n = str.length();
for(unsigned i=n; i<8; i++) str = " " + str;
row[m_Columns.size] = str + " ";
row[m_Columns.vendor] = " [ " + u->get_vendor() + " - " + u->get_model() + " ] ";
bool mounted=false;
int num_children = 0;
for(auto &w : u->children) {
childrow = *(m_refTreeModel->append(row.children()));
childrow[m_Columns.device] = w->get_devname();
childrow[m_Columns.fstype] = " " + w->get_fstype();
std::string str = w->get_size() + " G";
int n = str.length();
for(unsigned i=n; i<8; i++) str = " " + str;
childrow[m_Columns.size] = str + " ";
if(w->get_mtpt().length()) {
childrow[m_Columns.vendor] = " >> " + w->get_mtpt();
childrow[m_Columns.icon] = eject_icon;
mounted=true;
}
num_children++;
}
if(mounted) row[m_Columns.icon] = warning_icon;
else {
if(num_children == 0) row[m_Columns.icon] = ejected_icon;
else row[m_Columns.icon] = eject_icon;
}
}
// Set parent's gravity
pObj.clear();
pObj.begin();
m_Worker.get_data( pObj );
if(!pObj.size())
return;
/*
// No devices?
{
Gtk::MessageDialog dialog(*parent, "No devices found.");
dialog.run();
gtk_main_quit();
}
*/
// Fill the tree
m_refTreeModel->clear();
Glib::RefPtr<Gdk::Pixbuf> warning_icon = Gdk::Pixbuf::create_from_file( annex.warning_icon );
Glib::RefPtr<Gdk::Pixbuf> ejected_icon = Gdk::Pixbuf::create_from_file( annex.ejected_icon );
Glib::RefPtr<Gdk::Pixbuf> eject_icon = Gdk::Pixbuf::create_from_file( annex.eject_icon );
for(auto &u : pObj) {
row = *(m_refTreeModel->append());
row[m_Columns.device] = " " + u->get_devname();
row[m_Columns.fstype] = " " + u->get_fstype();
string str = u->get_size() + " G";
int n = str.length();
for(unsigned i=n; i<8; i++) str = " " + str;
row[m_Columns.size] = str + " ";
row[m_Columns.vendor] = " [ " + u->get_vendor() + " - " + u->get_model() + " ] ";
bool mounted=false;
int num_children = 0;
for(auto &w : u->children) {
childrow = *(m_refTreeModel->append(row.children()));
childrow[m_Columns.device] = w->get_devname();
childrow[m_Columns.fstype] = " " + w->get_fstype();
string str = w->get_size() + " G";
int n = str.length();
for(unsigned i=n; i<8; i++) str = " " + str;
childrow[m_Columns.size] = str + " ";
if(w->get_mtpt().length()) {
childrow[m_Columns.vendor] = " >> " + w->get_mtpt();
childrow[m_Columns.icon] = eject_icon;
mounted=true;
}
num_children++;
}
if(mounted) row[m_Columns.icon] = warning_icon;
else {
if(!u->get_removable()) row[m_Columns.icon] = ejected_icon;
else row[m_Columns.icon] = eject_icon;
}
}
// Set parent's gravity
int x, y;
parent->get_position(x, y);
if(x > annex.x_screen/2) {
if(y > annex.y_screen/2) parent->set_gravity(Gdk::GRAVITY_SOUTH_EAST);
else parent->set_gravity(Gdk::GRAVITY_NORTH_EAST);
} else {
if(y > annex.y_screen/2) parent->set_gravity(Gdk::GRAVITY_SOUTH_WEST);
else parent->set_gravity(Gdk::GRAVITY_NORTH_WEST);
}
/*
while (Gtk::Main::events_pending ())
Gtk::Main::iteration ();
* */
if(y > annex.y_screen/2) parent->set_gravity(Gdk::GRAVITY_SOUTH_EAST);
else parent->set_gravity(Gdk::GRAVITY_NORTH_EAST);
} else {
if(y > annex.y_screen/2) parent->set_gravity(Gdk::GRAVITY_SOUTH_WEST);
else parent->set_gravity(Gdk::GRAVITY_NORTH_WEST);
}
/*
while (Gtk::Main::events_pending ())
Gtk::Main::iteration ();
* */
}

// Signal Handler (single click)
bool BlkTree::on_button_press_event(GdkEventButton* event)
{
//Call base class, to allow normal handling (requires: set_hover_selection( true ) );
Gtk::TreeView::on_button_press_event(event);
if(event->type == GDK_BUTTON_PRESS)
{
if(event->button == 1)
return on_left_button_press_event();
else if(event->button == 2)
return on_middle_button_press_event(event);
else if(event->button == 3)
return on_right_button_press_event(event);
}
else if(event->type==GDK_2BUTTON_PRESS)
return on_double_click_event(event);
return false;
//Call base class, to allow normal handling (requires: set_hover_selection( true ) );
Gtk::TreeView::on_button_press_event(event);
if(event->type == GDK_BUTTON_PRESS)
{
if(event->button == 1)
return on_left_button_press_event();
else if(event->button == 2)
return on_middle_button_press_event(event);
else if(event->button == 3)
return on_right_button_press_event(event);
}
else if(event->type==GDK_2BUTTON_PRESS)
return on_double_click_event(event);
return false;
}
bool BlkTree::on_left_button_press_event()
{
if(!this->do_action) return false;
this->do_action = false;
Glib::RefPtr<Gtk::TreeView::Selection> refTreeSelection = get_selection();
if(refTreeSelection)
{
Gtk::TreeModel::iterator iter = refTreeSelection->get_selected();
if(iter && (*iter).parent())
{
std::string str = (*iter)[ m_Columns.device ];
std::string cmd = "pumount " + str + " 2>&1";
FILE *fp;
char buf[1024];
std::string e( "" );
fp = popen( cmd.c_str(), "r" );
if(!fp) {
std::cout << "Popen error\n";
exit( EXIT_FAILURE );
}
// There is a bug in pmount related to the replicated stdout error message
std::string first_line( "" );
while(fgets(buf, sizeof(buf), fp)) {
if( !first_line.length() ) first_line = std::string(buf);
e+=std::string(buf);
}
// Is it replicated? If so, split it half
std::size_t pos=e.find(first_line, 2);
if(pos != -1) {
std::string str1=e.substr(0, pos);
std::string str2=e.substr(pos);
if(!str2.compare(str1)) e=str1;
}
if( WEXITSTATUS(pclose(fp)) == 5) {
Gtk::Window *parent = dynamic_cast<Gtk::Window*>(this->get_toplevel());
Gtk::MessageDialog dialog(*parent, "This is an INFO MessageDialog");
dialog.set_message( "[ERROR]: umount failed", false );
dialog.set_secondary_text( e.c_str(), false );
dialog.run();
}
// the weak_ptr has to be copied into a shared_ptr before usage
if (auto p = BlkTree::getNode(str)->parent.lock()) {
std::vector<std::string> children = p->get_children_mtpt_vector();
int n=0;
for (auto &u : children)
if( u.length() ) n++;
/* Check whether n > 1 because the already removed partition still
figures as mounted in the std::vector */
if(n == 1) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
Gtk::Window *parent = dynamic_cast<Gtk::Window*>(this->get_toplevel());
Gtk::MessageDialog dialog(*parent, "This is an INFO MessageDialog");
std::string msg = p->get_vendor() + " - " + p->get_model();
dialog.set_message( msg.c_str(), false );
dialog.set_secondary_text( "can be safely removed.", false );
parent->hide();
dialog.run();
gtk_main_quit();
}
} else {
std::cout << "weak pointer is expired\n";
}
}
}
return false;
if(!this->do_action) return false;
this->do_action = false;
Glib::RefPtr<Gtk::TreeView::Selection> refTreeSelection = get_selection();
if(refTreeSelection)
{
Gtk::TreeModel::iterator iter = refTreeSelection->get_selected();
if(iter && (*iter).parent())
{
string str = (*iter)[ m_Columns.device ];
string cmd = "pumount " + str + " 2>&1";
FILE *fp;
char buf[1024];
string e( "" );
fp = popen( cmd.c_str(), "r" );
if(!fp) {
cout << "Popen error\n";
exit( EXIT_FAILURE );
}
// There is a bug in pmount related to the replicated stdout error message
string first_line( "" );
while(fgets(buf, sizeof(buf), fp)) {
if( !first_line.length() ) first_line = string(buf);
e+=string(buf);
}
// Is it replicated? If so, split it half
size_t pos=e.find(first_line, 2);
if(pos != -1) {
string str1=e.substr(0, pos);
string str2=e.substr(pos);
if(!str2.compare(str1)) e=str1;
}
int x = WEXITSTATUS(pclose(fp));
if(x == 5) {
Gtk::Window *parent = dynamic_cast<Gtk::Window*>(this->get_toplevel());
Gtk::MessageDialog dialog(*parent, "This is an INFO MessageDialog");
dialog.set_message( "[ERROR]: umount failed", false );
dialog.set_secondary_text( e.c_str(), false );
dialog.run();
}
/*
// the weak_ptr has to be copied into a shared_ptr before usage
if (auto p = BlkTree::getNode(str)->parent.lock()) {
vector<string> children = p->get_children_mtpt_vector();
int n=0;
for (auto &u : children)
if( u.length() ) n++;
// Check whether n > 1 because the already removed partition still
// figures as mounted in the vector
if( n == 1 && !is_device_removable(p) ) {
this_thread::sleep_for(chrono::milliseconds(500));
Gtk::Window *parent = dynamic_cast<Gtk::Window*>(this->get_toplevel());
Gtk::MessageDialog dialog(*parent, "This is an INFO MessageDialog");
string msg = p->get_vendor() + " - " + p->get_model();
dialog.set_message( msg.c_str(), false );
dialog.set_secondary_text( "can be safely removed.", false );
dialog.show();
}
} else {
throw runtime_error( "weak pointer is expired\n" );
}
*/
}
}
return false;
}

bool BlkTree::on_double_click_event(GdkEventButton* event)
{
this->m_shall_quit = false;
Hopman::EjectDialog *eject_dialog = new Hopman::EjectDialog( this->selected, this->ejected_icon, this->socket, this->path_to_the_helper );
eject_dialog->run();
delete eject_dialog;
this->m_shall_quit = true;
return true;
this->m_shall_quit = false;
Hopman::EjectDialog *eject_dialog = new Hopman::EjectDialog( this->selected, this->ejected_icon, this->socket, this->path_to_the_helper );
eject_dialog->run();
delete eject_dialog;
this->m_shall_quit = true;
return true;
}

bool BlkTree::on_middle_button_press_event(GdkEventButton* event)
{
/* *
*
* */
return true;
/* *
*
* */
return true;
}

bool BlkTree::on_right_button_press_event(GdkEventButton* event)
{
if(display_menu) {
m_Menu->display_menu(event, selected, is_partition_unmounted( selected ));
return true;
} else {
return false;
}
if(display_menu) {
m_Menu->display_menu(event, selected, is_partition_unmounted( selected ));
return true;
} else {
return false;
}
}

bool BlkTree::is_partition_unmounted(std::string partition)
bool BlkTree::is_device_removable(shared_ptr<Hopman::BlkNode> node)
{
bool res = true;
std::string dev=partition;
dev.pop_back();
for(auto &u : pObj) {
if(!dev.compare(u->get_devname()))
for(auto &v : u->children) {
if(!v->get_devname().compare(partition) && v->get_mtpt().length()) {
res = false;
}
}
}
return res;
try {
// Read the value in $SYSFS_PATH/removable
string filename = node->get_pathname() + "/removable";
unique_ptr<FILE, decltype(&fclose)> fp(::fopen(filename.c_str(), "r"), &fclose);
char ch = (char)fgetc(fp.get());
if (ch == '0')
return false;
else if (ch == '1')
return true;
}
catch(exception const& e) {
throw runtime_error("Sorry, there was an error opening the pipe\n");
};
}

bool BlkTree::is_partition_unmounted(string partition)
{
bool res = true;
string dev=partition;
dev.pop_back();
for(auto &u : pObj) {
if(!dev.compare(u->get_devname()))
for(auto &v : u->children) {
if(!v->get_devname().compare(partition) && v->get_mtpt().length()) {
res = false;
}
}
}
return res;
}
void BlkTree::on_mount()
{
FILE *fp;
char buf[1024];
std::string e( "" );
std::string cmd = "pmount " + selected + " 2>&1";
fp = popen( cmd.c_str(), "r" );
if(!fp) {
std::cout << "Popen error\n";
exit( EXIT_FAILURE );
}
// There is a bug in pmount related to the replicated stdout error message
std::string first_line( "" );
while(fgets(buf, sizeof(buf), fp)) {
if( !first_line.length() ) first_line = std::string(buf);
e+=std::string(buf);
}
// Is it replicated? If so, split it half
std::size_t pos=e.find(first_line, 2);
if(pos != -1) {
std::string str1=e.substr(0, pos);
std::string str2=e.substr(pos);
if(!str2.compare(str1)) e=str1;
}
FILE *fp;
char buf[1024];
string e( "" );
string cmd = "pmount " + selected + " 2>&1";
fp = popen( cmd.c_str(), "r" );
if(!fp) {
cout << "Popen error\n";
exit( EXIT_FAILURE );
}
// There is a bug in pmount related to the replicated stdout error message
string first_line( "" );
while(fgets(buf, sizeof(buf), fp)) {
if( !first_line.length() ) first_line = string(buf);
e+=string(buf);
}
// Is it replicated? If so, split it half
size_t pos=e.find(first_line, 2);
if(pos != -1) {
string str1=e.substr(0, pos);
string str2=e.substr(pos);
if(!str2.compare(str1)) e=str1;
}

if( WEXITSTATUS(pclose(fp)) > 3) {
Gtk::Window *parent = dynamic_cast<Gtk::Window*>(this->get_toplevel());
Gtk::MessageDialog dialog(*parent, "[ERROR]: pmount failed");
dialog.set_secondary_text( e.c_str(), false );
dialog.run();
gtk_main_quit();
}
if( WEXITSTATUS(pclose(fp)) != 255) {
Gtk::Window *parent = dynamic_cast<Gtk::Window*>(this->get_toplevel());
Gtk::MessageDialog dialog(*parent, "[ERROR]: pmount failed");
dialog.set_secondary_text( e.c_str(), false );
dialog.run();
gtk_main_quit();
}
}

// Signal Handler
void BlkTree::on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn *column)
{
if(column->get_title().compare("ICON")) return;
else this->do_action = true;
if(column->get_title().compare("ICON")) return;
else this->do_action = true;
}

void BlkTree::on_cursor_changed()
{
display_menu = false;
selected.clear();
Glib::RefPtr<Gtk::TreeView::Selection> refTreeSelection = get_selection();
if(refTreeSelection)
{
Gtk::TreeModel::iterator iter = refTreeSelection->get_selected();
if(iter) {
std::string strLabel( "" );
std::string temp( "" );
std::string str=(*iter)[ m_Columns.device ];
str.erase(std::remove(str.begin(), str.end(), ' '), str.end()); /* Remove spaces in blanck */
this->selected = str;
auto node = BlkTree::getNode(this->selected);
if( (*iter).parent() ) { /* child */
// In the children, we'll specify parent's label too
// Parent's weak_ptr has to be copied into a shared_ptr before usage
if (auto p = node->parent.lock()) {
display_menu = true;
temp=p->get_label();
if(temp.size()) temp+=" | ";
} else {
std::cout << "weak pointer is expired\n";
}
display_menu = false;
selected.clear();
Glib::RefPtr<Gtk::TreeView::Selection> refTreeSelection = get_selection();
if(refTreeSelection)
{
Gtk::TreeModel::iterator iter = refTreeSelection->get_selected();
if(iter) {
string strLabel( "" );
string temp( "" );
string str=(*iter)[ m_Columns.device ];
str.erase(std::remove(str.begin(), str.end(), ' '), str.end()); /* Remove spaces in blanck */
this->selected = str;
auto node = BlkTree::getNode(this->selected);
if( (*iter).parent() ) { /* child */
// In the children, we'll specify parent's label too
// Parent's weak_ptr has to be copied into a shared_ptr before usage
if (auto p = node->parent.lock()) {
display_menu = true;
temp=p->get_label();
if(temp.size()) temp+=" | ";
} else {
throw runtime_error( "weak pointer is expired\n" );
}

temp+=node->get_label();
if(temp.size()) strLabel+=" LABEL=" + temp + " \n";
strLabel+=" UUID=" + node->get_uuid() + " \n";
strLabel+=" PARTUUID=" + node->get_partuuid() + " ";
} else { /* parent */
temp=node->get_label();
if(temp.size()) strLabel+=" LABEL=" + temp + " \n";
temp=node->get_uuid();
if(temp.size()) strLabel+=" UUID=" + node->get_uuid() + " ";
}
m_Label.set_text( strLabel );
}
}
temp+=node->get_label();
if(temp.size()) strLabel+=" LABEL=" + temp + " \n";
strLabel+=" UUID=" + node->get_uuid() + " \n";
strLabel+=" PARTUUID=" + node->get_partuuid() + " ";
} else { /* parent */
temp=node->get_label();
if(temp.size()) strLabel+=" LABEL=" + temp + " \n";
temp=node->get_uuid();
if(temp.size()) strLabel+=" UUID=" + node->get_uuid() + " ";
}
m_Label.set_text( strLabel );
}
}
}

bool BlkTree::on_test_collapse_row (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path)
{
Gtk::Window *parent = dynamic_cast<Gtk::Window*>(this->get_toplevel());
if (parent)
parent->resize(20,20);
return Gtk::TreeView::on_test_collapse_row (iter, path);
Gtk::Window *parent = dynamic_cast<Gtk::Window*>(this->get_toplevel());
if (parent)
parent->resize(20,20);
return Gtk::TreeView::on_test_collapse_row (iter, path);
}

bool BlkTree::on_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip)
{
if( m_Label.get_text().length() > 1) m_Label.show();
m_tooltip_window->hide();
m_tooltip_window->resize(1, 1);
if( m_Label.get_text().length() > 1) m_Label.show();
m_tooltip_window->hide();
m_tooltip_window->resize(1, 1);
return true;
}

std::shared_ptr<Hopman::BlkNode> BlkTree::getNode( std::string dev )
shared_ptr<Hopman::BlkNode> BlkTree::getNode( string dev )
{
std::string duplicate = dev;
duplicate.pop_back();
for(auto &p : pObj) {
std::string d_name=p->get_devname();
if( !dev.compare(d_name) )
return p;
else if( !duplicate.compare(d_name) )
for(auto &w : p->children)
if( !w->get_devname().compare(dev) )
return w;
}
return nullptr;
string duplicate = dev;
duplicate.pop_back();
for(auto &p : pObj) {
string d_name=p->get_devname();
if( !dev.compare(d_name) )
return p;
else if( !duplicate.compare(d_name) )
for(auto &w : p->children)
if( !w->get_devname().compare(dev) )
return w;
}
return nullptr;
}

} //namespace Hopman

+ 120
- 102
hopman-1.0/gtkmm/blk_tree.h View File

@@ -1,3 +1,22 @@
/*
* blk_tree.h
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/


#ifndef __BLK_TREE_H__
@@ -12,124 +31,123 @@
#include "blk_node.h"

namespace Hopman {
// TODO
//class EjectDialog;
using namespace std;
class BlkTree : public Gtk::TreeView
{
public:
BlkTree(const Hopman::Annex&);
virtual ~BlkTree ();
bool get_shall_quit();
BlkTree(const Hopman::Annex&);
virtual ~BlkTree ();
bool get_shall_quit();

class cMenu : public Gtk::Menu
{
public:
cMenu(BlkTree*);
virtual ~cMenu();
void display_menu(GdkEventButton*, std::string, bool);
class cMenu : public Gtk::Menu
{
public:
cMenu(BlkTree*);
virtual ~cMenu();
void display_menu(GdkEventButton*, string, bool);
private:
std::string name;
// Child widgets
Gtk::MenuItem *item;
virtual void on_open_new_tab(BlkTree*);
virtual void on_open_new_window(BlkTree*);
};
private:
string name;
// Child widgets
Gtk::MenuItem *item;
virtual void on_open_new_tab(BlkTree*);
virtual void on_open_new_window(BlkTree*);
};
std::string get_selected();
class Worker
{
Worker();
virtual ~Worker();
private:
struct BlkData { // data to manage
BlkData( ) { }
virtual ~BlkData() { }
std::string path, fstype, label, uuid, partuuid;
};
std::vector< std::shared_ptr<Hopman::BlkNode> > pObj_Worker;
void do_work(BlkTree*, const Hopman::Annex&);
void stop_work();
void get_data(std::vector<std::shared_ptr<Hopman::BlkNode>>&) const;
static bool compareNames(std::shared_ptr<Hopman::BlkNode>, std::shared_ptr<Hopman::BlkNode>);
static bool compareNodes(std::shared_ptr<Hopman::BlkNode>, std::shared_ptr<Hopman::BlkNode>);
static std::vector<std::string> split_line(const std::string&, const std::string&);
static void showList(struct vdev_usb_device_list*);
// Synchronizes access to member data.
mutable std::mutex m_Mutex;
string get_selected();
class Worker
{
Worker();
virtual ~Worker();
private:
struct BlkData { // data to manage
BlkData( ) { }
virtual ~BlkData() { }
string path, fstype, label, uuid, partuuid;
};
vector< shared_ptr<Hopman::BlkNode> > pObj_Worker;
void do_work(BlkTree*, const Hopman::Annex&);
void stop_work();
void get_data(vector< shared_ptr<Hopman::BlkNode> >&) const;
static bool compareNames(shared_ptr<Hopman::BlkNode>, shared_ptr<Hopman::BlkNode>);
static bool compareNodes(shared_ptr<Hopman::BlkNode>, shared_ptr<Hopman::BlkNode>);
static vector<string> split_line(const string&, const string&);
static void showList(struct vdev_usb_device_list*);
// Synchronizes access to member data.
mutable mutex m_Mutex;
// Data used by both GUI thread and worker thread.
bool m_first_time, m_shall_stop;
// Declare the outer class as friend of the inner class:
friend class BlkTree;
};
// Data used by both GUI thread and worker thread.
bool m_first_time, m_shall_stop;
// Declare the outer class as friend of the inner class:
friend class BlkTree;
};

protected:
/*
* This is for the single click event, since
* set_activate_on_single_click( true ) is not available in gtkmm 2.4
* */
virtual bool on_button_press_event(GdkEventButton*) override;
virtual bool on_left_button_press_event();
virtual bool on_right_button_press_event(GdkEventButton*);
virtual bool on_middle_button_press_event(GdkEventButton*);
virtual bool on_double_click_event(GdkEventButton*);
virtual void on_mount();
virtual bool is_partition_unmounted(std::string);
/* This is for the double click event */
void on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* /* column */);
bool on_test_collapse_row (const Gtk::TreeModel::iterator&, const Gtk::TreeModel::Path&);
void on_cursor_changed();
/* Tooltip */
bool on_query_tooltip(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>&);
bool on_button_press_event(GdkEventButton*) override;
bool on_left_button_press_event();
bool on_right_button_press_event(GdkEventButton*);
bool on_middle_button_press_event(GdkEventButton*);
bool on_double_click_event(GdkEventButton*);
void on_mount();
bool is_partition_unmounted(string);
/* This is for the double click event */
void on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* /* column */);
bool on_test_collapse_row (const Gtk::TreeModel::iterator&, const Gtk::TreeModel::Path&);
void on_cursor_changed();
/* Tooltip */
bool on_query_tooltip(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>&);
private:
std::vector<std::shared_ptr<Hopman::BlkNode>> pObj;
Gtk::Window *m_tooltip_window;
Gtk::Label m_Label;
bool display_menu, do_action, m_shall_quit;
std::string selected, ejected_icon, socket, path_to_the_helper;
Worker m_Worker;
std::thread *m_WorkerThread;
// Glib:
Glib::Dispatcher m_Dispatcher;
// Called from the worker thread:
void fill_tree();
void notify();
// Dispatcher handler:
void get_info_from_worker_thread(const Hopman::Annex&);
int X;
vector< shared_ptr<Hopman::BlkNode> > pObj;
Gtk::Window *m_tooltip_window;
Gtk::Label m_Label;
bool display_menu, do_action, m_shall_quit;
string selected, ejected_icon, socket, path_to_the_helper;
Worker m_Worker;
thread *m_WorkerThread;
// Glib:
Glib::Dispatcher m_Dispatcher;
// Called from the worker thread:
void fill_tree();
void notify();
// Dispatcher handler:
void get_info_from_worker_thread(const Hopman::Annex&);
bool is_device_removable(shared_ptr<Hopman::BlkNode>);
cMenu *m_Menu;
guint cols_count;
Hopman::BlkModel m_Columns;
Glib::RefPtr<Gtk::TreeStore> m_refTreeModel;
Gtk::TreeModel::Row row, childrow;
Gtk::TreeViewColumn* pColumn;
Gtk::CellRendererProgress* cell;
std::shared_ptr<Hopman::BlkNode> getNode(std::string);
cMenu *m_Menu;
guint cols_count;
Hopman::BlkModel m_Columns;
Glib::RefPtr<Gtk::TreeStore> m_refTreeModel;
Gtk::TreeModel::Row row, childrow;
Gtk::TreeViewColumn* pColumn;
Gtk::CellRendererProgress* cell;
shared_ptr<Hopman::BlkNode> getNode(string);
};
} // namespace Hopman

typedef Hopman::BlkTree::cMenu BlkTreeCMenu;
typedef Hopman::BlkTree::Worker BlkTreeWorker;

} // namespace Hopman

#endif // __BLK_TREE_H__


+ 22
- 1
hopman-1.0/gtkmm/buttonbox.cpp View File

<
@@ -1,3 +1,23 @@
/*
* blk_node.cpp
* Copyright (C) 2021 Aitor Cuadrado Zubizarreta <aitor_czr@gnuinos.org>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* See the LICENSE file. *
*/


#include "buttonbox.h"

@@ -5,7 +25,7 @@ namespace Hopman {

myButtonBox::myButtonBox(bool horizontal, int spacing, Gtk::ButtonBoxStyle layout)
{
if (horizontal)
if (horizontal)
bbox = new Gtk::HButtonBox;
else
bbox = new Gtk::VButtonBox;
@@ -21,4 +41,5 @@ myButtonBox::~myButtonBox()