Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

work-in-progress to support select browser mode #12

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from

Conversation

KyleRConway
Copy link

initial work to enable a mode to select installed browser every time i link is clicked.

@micahflee micahflee changed the title work-in-progress work-in-progress to support select browser mode Sep 16, 2018
@micahflee
Copy link
Owner

This is a great start!

First, a quick note about pull requests on github. It's helpful to name the PR with something description the feature you're adding, or the bug you're fixing. So I changed it from just "work-in progress" to "work-in-progress to support select browser mode". Also it's good to reference the issue this PR fixes (in this case #6), because just by mentioning it here it links it to the issue.

The main thing is that, because of how porcupine is currently packaged, we need to restructure the code a bit if we want to use more files that just porcupine for the code, like choose_browser.py. It's not too hard to do this -- basically, I'd need to make porcupine a python module (so, a folder) instead a script, with its own __init__.py file inside. Then I'd have to make another python script called porcupine that just does basically:

import porcupine
porcupine.main()

To see what I mean, you can check out torbrowser-launcher which does this:

Anyway, if porcupine becomes very much larger of a project this will be necessary. But for the time being, I think it might just be simpler to implement everything in same porcupine file.

What I'd do is create a new function called get_browser_list(), and copy basically all of the logic that's in choose_browser.py into that function. Then make it return a list of browser, with each browser maybe a being a dictionary, like this:

[
  {
    "name": "Firefox",
    "exec_path": "/usr/bin/firefox",
    "icon_path": "/usr/share/icons/hicolor/64x64/apps/firefox.png"
  },
  { ... }
]

Then, you'd probably want to make a new Qt5 widget class, basically a dialog window that pops up showing you all of the options...

Anyway, want to work more on this, and merge choose_browser.py into porcupine? You can make more commits and push them to the same branch, and they'll show up in this PR so I can keep commenting on them.

@KyleRConway
Copy link
Author

Thanks @micahflee

I really appreciate the feedback and the help (I'll need it)! Very much appreciate the explanation of git standards and python modules! I'll try to integrate the code as suggested into the main porcupine file.

I suspect my biggest difficulty here will be creating a Qt5 widget class (though even having the language to look this up will be helpful). I was able to poke around your code to add the radio button for the startup though, so with a little work it'll probably be fine. If there's a good resource to learn about implementing simple Qt5 widget classes I'd love to hear about it!

Thanks again for the help!

@micahflee
Copy link
Owner

micahflee commented Sep 19, 2018

I'm not sure about a good resource to help you make a custom Qt5 widget, however I do have some example code. So, the first thing to know is that in Qt there's a class hierarchy. Nearly everything (from windows, dialog boxes, labels, buttons, etc.) is a widget. The base class is called QWidget, and everything inherits from that.

So, to make a custom widget, choose which type of already-existing widget you want to base your custom one off of. For example, you could choose to base it off of QWidget, or QLabel, or QListWidget, etc.

Check out the classes in this file in OnionShare: https://github.com/micahflee/onionshare/blob/develop/onionshare_gui/share_mode/file_selection.py

This file includes the following classes (and which types of widgets they inherit from):

class DropHereLabel(QtWidgets.QLabel):
class DropCountLabel(QtWidgets.QLabel):
class FileList(QtWidgets.QListWidget):
class FileSelection(QtWidgets.QVBoxLayout):

You can see the DropHereLabel class in this screenshot:

screenshot_2018-09-19_10-51-31

It's a simple one:

class DropHereLabel(QtWidgets.QLabel):
    """
    When there are no files or folders in the FileList yet, display the
    'drop files here' message and graphic.
    """
    def __init__(self, common, parent, image=False):
        self.parent = parent
        super(DropHereLabel, self).__init__(parent=parent)

        self.common = common

        self.setAcceptDrops(True)
        self.setAlignment(QtCore.Qt.AlignCenter)

        if image:
            self.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/logo_transparent.png'))))
        else:
            self.setText(strings._('gui_drag_and_drop', True))
            self.setStyleSheet(self.common.css['share_file_selection_drop_here_label'])

        self.hide()

    def dragEnterEvent(self, event):
        self.parent.drop_here_image.hide()
        self.parent.drop_here_text.hide()
        event.accept()

Basically, you could do something like this instead:

drop_here_label = QtWidgets.QLabel()
drop_here_label.setAcceptDrops(True)
drop_here_label.setAlignment(QtCore.Qt.AlignCenter)
# (and so on...)

But it's cleaner to just make the full DropHereLabel widget self-contained as its own object.

So I think step one is picking out what type of widget you're going to use for the dialog thing that pops up. This depends on how you want it to look, but in my mind I picture something that's sort of like a horizontal container similar to the alt-tab menu selector.

Maybe you'll need a QWidget (or even a QDialog? not sure which is better in this case), that has a QHBoxLayout (meaning widgets get stuffed horizontally in it) layout inside of it, and in that layout a different widget for each browser?

BTW the official C++ Qt5 documentation is pretty good, and all of the class and method names and args are exactly the same as in python, so I generally just use the C++ docs.

@KyleRConway
Copy link
Author

@micahflee -- I think I've got the new function get_browser_list() in the main porcupine file returning a list of dictionaries with the appropriate keys and values. I'm going to start working on the GUI aspect next. I'll inquire if I have any further questions, but I think your notes will (THANK YOU!) will take me far!

@micahflee
Copy link
Owner

Awesome! Let me know when you want to me test out the code some more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants